Заменить тег динамически возвращает объект вместо содержимого - PullRequest
1 голос
/ 05 июля 2019

Я создаю чат-клиент и хочу сканировать сообщения на предмет определенного тега, в данном случае [item:42]

Я передаю сообщения одно за другим следующему компоненту:

<script>
import ChatItem from './ChatItem'

export default {
    props :[
        'chat'
    ],

    name: 'chat-parser',

    data() {
        return {
            testData: []
        }
    },

    methods : {
        parseMessage(msg, createElement){
            const regex = /(?:\[\[item:([0-9]+)\]\])+/gm;
            let m;

            while ((m = regex.exec(msg)) !== null) {
                msg = msg.replace(m[0],
                    createElement(ChatItem, {
                        props : {
                            "id" : m[1],
                        },
                    }))


                if (m.index === regex.lastIndex) {
                    regex.lastIndex++;
                }
            }


            return msg
        },

    },

    render(createElement) {
        let user = "";
        let msg  = this.parseMessage(this.$props.chat.Message, createElement)

        return createElement(
            'div',
            {

            },
            [
                 // "hello",// createElement("render function")
                createElement('span', '['+ this.$props.chat.Time+'] '),
                user,
                msg,
            ]
        )

    }
};

</script>

Я думал, что передача createElement методу parseMessage будет хорошей идеей, но он не работает должным образом, так как он заменяет тег на [object object]

ChatItem выглядиткак это:

<template>
    <div>
        <span v-model="item">chatITem : {{ id }}</span>
    </div>
</template>

<script>
    export default {
        data: function () {
            return {
                item : [],
            }
        },

        props :['id'],

        created() {
            // this.getItem()
        },

        methods: {
             getItem: function(){
               obj.item = ["id" : "42", "name": "some name"]
             },

        },
    }
</script>

Пример:

если сообщение выглядит так: what about [item:42] OR [item:24] оба должны быть заменены компонентом chatItem

1 Ответ

1 голос
/ 05 июля 2019

Хотя вы можете сделать это с помощью функции render, которая на самом деле не нужна, если вы просто анализируете текст в формате, который может использоваться шаблоном.

В этом случае я сохранил синтаксический анализатор очень примитивно. Это дает массив значений. Если значение является строкой, то шаблон просто выгружает его. Если значение является числом, оно считается числом, извлеченным из [item:24] и переданным в <chat-item>. Я использовал фиктивную версию <chat-item>, которая просто выводит число в теге <strong>.

new Vue({
  el: '#app',
 
  components: {
    ChatItem: {
      props: ['id'],
      template: '<strong>{{ id }}</strong>'
    }
  },

  data () {
    return {
      text: 'Some text with [item:24] and [item:42]'
    }
  },
  
  computed: {
    richText () {
      const text = this.text

      // The parentheses ensure that split doesn't throw anything away
      const re = /(\[item:\d+\])/g

      // The filter gets rid of any empty strings
      const parts = text.split(re).filter(item => item)
      
      return parts.map(part => {
        if (part.match(re)) {
          // This just converts '[item:24]' to the number 24
          return +part.slice(6, -1)
        }
        
        return part
      })
    }
  }
})
<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>
<div id="app">
  <template v-for="part in richText">
    <chat-item v-if="typeof part === 'number'" :id="part"></chat-item>
    <template v-else>{{ part }}</template>
  </template>
</div>

Если бы я собирался сделать это с помощью функции render, я бы сделал это почти так же, просто заменив шаблон функцией render.

Если бы требования разбора текста были немного сложнее, я бы не просто возвращал строки и числа. Вместо этого я бы использовал объекты для описания каждой части. Основные идеи остаются прежними.

...