我们正在Vuejs中构建一个聊天应用程序,现在每个聊天消息都是应用程序中的组件,现在每当我们更改一个聊天消息的值时,所有聊天消息的值都会改变
正在发生的事情
源代码
应用组件
const App = new Vue({
el: '#myApp',
data: {
children: [
MyCmp
],
m1: '',
m2: '',
m3: 'Hello world',
m4: 'How are you'
},
methods: {
sendMessage (event) {
if(event.key == "Enter") {
this.m2= this.m3;
this.children.push(MyCmp);
}
},
}
});
组件代码
let MyCmp = {
props: ['myMessage'],
template: `
<li class="self">
<div class="avatar"><img src="" draggable="false"/></div>
<div class="msg">
<p>{{ myMessage }}</p>
</div>
</li>
`
};
**查看组件正在生成的位置**
<ol class="chat">
<template v-for="(child, index) in children">
<component :is="child" :key="child.name" v-bind="{myMessage: m3}"></component>
</template>
</ol>
答案 0 :(得分:1)
即使通过将新组件推入子数组来创建新组件,它们仍将通过行v-bind="{myMessage: m3}"
绑定到相同数据。每当您更改m3
时,它将被向下传递到所有子组件,它们将呈现相同的消息。
这是一种创建自定义组件的奇怪方法,因为您可以使用Vue提供的模板语法或渲染功能轻松地做到这一点。
更改您的方法-将消息字符串而不是卡组件定义推送到children
中,并在MyCmp
内使用v-for
来呈现消息卡。
因此,新模板可以重构为:-
<ol class="chat">
<template v-for="(message, index) in children">
<my-cmp :key="index" :my-message="message"></my-cmp>
</template>
</ol>
在App组件内部,您可以将this.children.push(MyCmp)
替换为this.children.push(messageVariable);
,其中messageVariable
包含从输入框中收到的消息。
为什么推荐?这是一种标准方法,其中基于数据数组呈现组件列表。将会更容易扩展和维护。
您可以使用v-once指令将消息一次性绑定为静态文本。即使m3
在父级上更改,绑定也不会更新。
然后MyCmp
模板将变为:-
<li class="self">
<div class="avatar"><img src="" draggable="false"/></div>
<div class="msg">
<p v-once>{{ myMessage }}</p>
</div>
</li>
答案 1 :(得分:0)
您将所有组件实例的myMessage
与一个变量m3
绑定。因此,当m3
更改为myMessage
时,所有实例都将分别更改。使用另一个变量(例如msg
)来呈现消息,然后仅将myMessage
属性用于msg
的初始化,如下所示:
let MyCmp = {
props: ['myMessage'],
data: function () {
return {
msg: this.myMessage
}
},
template: `
<li class="self">
<div class="avatar"><img src="" draggable="false"/></div>
<div class="msg">
<p>{{ msg }}</p>
</div>
</li>
`
};