您的位置:首页 > 产品设计 > UI/UE

Vue父子组件互相通信实例

2018-01-20 20:23 821 查看
组件实例之间的作用域是独立的,意味了不应该在子组件的模板内直接引用父组件的数据,但是父子组件之间需要通信:父组件要给子组件传递数据,子组件需要将它内部发生的事情告知给父组件。



prop 是父组件用来传递数据的一个自定义属性。子组件需要显式地用 props 选项声明 “prop”:

Vue.component('child', {

// 声明 props

props: ['message'],

// 就像 data 一样,prop 可以用在模板内

// 同样也可以在 vm 实例中像 “this.message” 这样使用

template: '<span>{{ message }}</span>'

})


一个实例:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>多层组件通信</title>
</head>
<body>
<div id="app">
<my-parent :imgtitle='title' :imgsrc='img'></my-parent>
</div>

<template id="my_img">
<img :src="imgsrc" width="200">
</template>

<template id="my_title">
<h2>{{title}}</h2>
</template>

<template id="my_parent">
<div>
<child1 :imgsrc="imgsrc"></child1>
<child2 :title="imgtitle"></child2>
</div>
</template>

<script src="js/vue.min.js"></script>
<script>
//1.子组件的实例
let Child1 = Vue.extend({
template:'#my_img',
props:['imgsrc']
});
let Child2 = Vue.extend({
template:'#my_title',
props:['title']
});
//注册父组件
Vue.component('my-parent',{
props:['imgtitle','imgsrc'],
components:{
'child1':Child1,
'child2':Child2
},
template:'#my_parent'
});
new Vue({
el:'#app',
data:{
title:'我很帅',
img:'img/01.jpg'
}
});
</script>
</body>
</html>


可以看到数据从父组件通过props传递给子组件,但是注意通过这种方法prop默认是单向绑定, 当父组件的属性变化时,将传导给子组件,但是反过来不会。这是为了防止子组件无意修改了父组件的状态。

然后就是子组件传递数据给父组件,通过自定义事件。

每个 Vue 实例都实现了事件接口(Events interface),即:

使用 $on(eventName) 监听事件

使用 $emit(eventName) 触发事件

父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。

一个实例,一旦子组件的total()事件发生,通过emit触发父组件的方法。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue的自定义事件</title>
</head>
<body>
<div id="app">
<my-btn @total="allcounter()"></my-btn>
<my-btn @total="allcounter()"></my-btn>
<my-btn @total="allcounter()"></my-btn>
<my-btn @total="allcounter()"></my-btn>
<my-btn @total="allcounter()"></my-btn>
<my-btn @total="allcounter()"></my-btn>
<p>所有按钮一共点击了{{totalCounter}}次</p>
</div>

<template id='my_btn'>
<button @click="total()">点击了{{counter}}次</button>
</template>

<script src="js/vue.min.js"></script>
<script>
Vue.component('my-btn',{
template:'#my_btn',
data(){
return{
counter:0
}
},
methods:{
total(){
this.counter += 1;

//子组件通知外界,我调用了这个方法
this.$emit('total');
}
}
});

new Vue({
el: '#app',
data: {
totalCounter:0
},
methods:{
allcounter(){
this.totalCounter += 1;
}
}
});
</script>
</body>
</html>


运行结果就是子组件之间的点击互不影响,父组件总点击数增加。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: