父 → 子
假如,我们需要定义一个 列表组件
,该组件的数据需要使用 根组件(vm)
中 data
的数据(最外层),这就要涉及到组件通信问题。
Vue 提供了解决方案,通过 Prop 向子组件传递数据 ,便可解决该问题。
我们先来创建组件及实例化Vue,做好基础环境工作,我们 先不进行传值:
<body>
<div id="app">
<List></List>
</div>
</body>
// 创建列表组件(子组件)
Vue.component('List', {
template: `<li>{{ msg }}</li>`,
data(){
return {
msg: "数据"
}
},
})
// 实例化Vue(根组件)
let vm = new Vue({
el: '#app',
data: {}
})
不难发现,List
子组件使用的数据是自身 data
身上的数据,所以毫无疑问正常显示。
那么问题来了,List
子组件如何使用根组件(vm)身上的 data ?(下图所示)
你只需要在 List(子组件)
加上 props
属性,props
值是一个数组,包含了接收数据(即父组件传递给子组件的变量),任何值都可以传递(对象 / 数组 / 函数 …)。
传递完成了还不行,你得 告知子组件数据传过来了,即在组件标签上绑定属性: :msg
,这段话不懂没关系,看完下面的 demo 你就明白了!
当一个值传递给一个 prop attribute 的时候,它就变成了那个组件实例的一个 property。
我们重构上面的代码,让其完成传递:
<body>
<div id="app">
<!-- 告知子组件 -->
<!-- 【:msg】接收父组件数据 -->
<!-- 【msg】父组件的数据 -->
<List :msg="msg"></List>
</div>
</body>
Vue.component('List', {
// 接收父组件数据
props:['msg'],
template: `<li>{{ msg }}</li>`,
data(){
return {}
},
})
// 实例化Vue
let vm = new Vue({
el: '#app',
data: {
msg: "我是父组件的数据!"
}
})
这样就完成了父传子的通信,需要注意的是 :msg = "msg"
不会被渲染。
子 → 父
上面我们完成了 父组件传值给子组件示例
,下面我们基于上面的例子继续探索。
你还记得吗?每一个子组件都是一个实例(VueComponent),就像 Vue 实例一样!
子组件也同样拥有
methods
/data
这些属性,除了没有el
。
我们在子组件中定义一个方法(show),来查看这个实例(VueComponent):
Vue.component('List', {
props:['msg'],
template: `<li>{{ msg }}
<button @click="show">点击触发</button>
</li>`,
data(){
return {}
},
methods: {
show(){
console.log(this)
}
}
})
你看!接下来我们展开这个实例,并找到 $root
这个属性:
没错!它就是我们要找的父组件实例!挂载着父组件的所有数据!
这时你可能有疑问,这跟传递值有半毛钱关系吗?为什么不用 $emit
来监听传值?
让我们回到最初,遐想一下,我们将 父组件
的数据传递给 子组件
,用意是什么?
是不是你 子组件
要用 父组件
的数据?如果不用为什么要传递?
上面说了,子组件
的 $root
属性下挂载着 父组件
的所有数据!
既然能直接拿到 父组件
的所有数据,为什么还要繁琐的传递呢?
注意:组件通信的方式有很多种,这里只谈这一种方式,您视情况而定!
我们完成一个小示例(当点击按钮时,获取父组件数据)
获取成功即为通信成功!
<body>
<div id="app">
<List></List>
</div>
</body>
// 子组件
Vue.component('List', {
template: `<li>获取父组件数据:{{ msg }}
<button @click="show">获取父组件数据</button>
</li>`,
data(){
return {
msg: ''
}
},
methods: {
show(){
// 获取父组件数据 data-msg
let e = this.$root.msg
// 将数据赋给子组件 data-msg
this.msg = e
}
}
})
// 父组件(根)
let vm = new Vue({
el: '#app',
data: {
msg: "我是父组件的数据!"
}
})
成功!
可以看到,我们并未使用繁琐的 props
/ $emit
… ,而是 直接获取父组件实例,然后直接拿数据。
写在后面
记住,能拿到 data
属性上挂载的数据,就能拿到 methods
属性上挂载的方法,懂吧!