我正在构建一个聊天客户端,我想扫描消息中的特定标签,在这种情况下为[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组件替换
答案 0 :(得分:1)
虽然您可以使用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
函数。
如果文本解析要求稍微复杂一点,那么我不仅会返回字符串和数字。相反,我将使用对象来描述每个部分。核心思想却保持不变。