Javascript Vue2事件总线在第二次调用后工作
我有一个嵌套组件,子组件应该从主实例接收一个参数,但问题是我必须调用事件两次以获取参数 index.htmlJavascript Vue2事件总线在第二次调用后工作,javascript,html,vue.js,event-handling,vuejs2,Javascript,Html,Vue.js,Event Handling,Vuejs2,我有一个嵌套组件,子组件应该从主实例接收一个参数,但问题是我必须调用事件两次以获取参数 index.html <div id="app"> <button @click="displayComponent">Display</button><br/><hr/> {{ message }} <mycomponent v-if="showComponent" @hide="hideComponents">
<div id="app">
<button @click="displayComponent">Display</button><br/><hr/>
{{ message }}
<mycomponent v-if="showComponent" @hide="hideComponents"></mycomponent>
</div>
显示
{{message}}
code.js
window.bus = new Vue();
Vue.component('mycomponent', {
template: `
<div>
<h3>Im the parent component</h3>
<childcomponent></childcomponent>
<button @click="$emit('hide')">Hide components</button>
</div>
`
});
Vue.component('childcomponent', {
template:`
<div>
<h4>Im the child component</h4>
<p>{{ data }}</p>
</div>
`,
data() {
return {
text: 'Nothing loaded'
};
},
methods: {
test() {
alert('hello');
},
getData(x) {
this.text = x;
}
},
created(){
bus.$on('extraCall', data => {
this.getData(data);
this.test();
});
}
});
const app = new Vue({
el: '#app',
data: {
message: 'hello world!',
showComponent: false
},
methods: {
displayComponent() {
bus.$emit('extraCall', 'this is some extra text');
this.showComponent = true;
},
hideComponents() {
this.showComponent=false;
}
}
});
window.bus=new Vue();
Vue.component('mycomponent'{
模板:`
Im是父组件
隐藏组件
`
});
Vue.component('childcomponent'{
模板:`
Im是子组件
{{data}}
`,
数据(){
返回{
文本:“未加载”
};
},
方法:{
测试(){
警惕(“你好”);
},
getData(x){
this.text=x;
}
},
创建(){
总线。$on('Extrall',数据=>{
这个.getData(数据);
这个。test();
});
}
});
const app=新的Vue({
el:“#应用程序”,
数据:{
信息:“你好,世界!”,
showComponent:false
},
方法:{
displayComponent(){
总线。$emit('extraCall','这是一些额外的文本');
this.showComponent=true;
},
hideComponents(){
this.showComponent=false;
}
}
});
子组件元素内的文本值被设置为默认值,单击显示按钮后,它将触发总线。$emit
使用extraCall
事件并将一些文本作为参数,这将更新文本值,并且仅在第二次单击显示按钮后才会发生
我缺少什么?
(及其子项
)在单击显示按钮时未实例化,因为v-if=“showComponent”
第一次点击:
extraCall
在总线上发出,但没有该事件的侦听器,因此将忽略该事件
在将showComponent
设置为true后实例化
在其创建的钩子中注册extraCall
事件的侦听器
extraCall
在总线上发出,并由
处理总线。$emit()
和this.showComponent=true
行,以便在发出事件之前实例化
,但这仍然不起作用,因为Vue将组件的创建延迟到更新视图时的下一个微任务
这可能会奏效:
displayComponent() {
this.showComponent = true;
// Wait for child component to be instantiated
this.$nextTick(() => {
bus.$emit('extraCall', 'this is some extra text');
});
}
如果上面的代码适合你,我还是不推荐它。在发出事件之前,不需要考虑子组件的创建(它将组件耦合在一起)。您应该以其他方式共享数据,检查关于跨组件共享数据的最佳方式的其他SO问题。好的,这确实有效,但正如您所说的,不是最优的,必须有更好的解决方案。但既然它解决了主要问题,我就把它作为一个解决方案,如果我找到一个更好的,我会把它贴在这里。谢谢!好吧,既然你真的很好而且很合作,我想问你,前一段时间我做了一些类似的事情,它工作了,但现在没有,我发现唯一的区别是html文件,显示组件而不是v-if的条件是v-show,当我更改它时,它就工作了。。。使用这个会有任何附带损害吗?。。。AFAIK v-show需要加载更多的内容,但随后只显示右侧,并且每次调用组件时v-if都会创建组件。
v-show
仅切换元素上的样式。如果v-show
为false,则组件仍然被创建,只是因为样式而被隐藏(您可以在开发工具中看到)v-if
将实际销毁/创建元素。如果在此处使用v-show
而不是v-If
,它将与原始代码一起工作。要在<代码> V-IF <代码>和<代码> V-Studio之间进行判断(1)是否需要始终创建的元素?(2) 将元素隐藏在DOM中会影响任何:n个子CSS选择器吗?(3) 使用v-show
使元素保持活动状态将占用更多内存等。非常感谢您的时间,现在我已经很清楚了。它对我不起作用。