Vue - 通俗易懂的组件通信问题(父子传值)

父 → 子

假如,我们需要定义一个 列表组件,该组件的数据需要使用 根组件(vm)data 的数据(最外层),这就要涉及到组件通信问题。

Vue 提供了解决方案,通过 Prop 向子组件传递数据 ,便可解决该问题。

我们先来创建组件及实例化Vue,做好基础环境工作,我们 先不进行传值

<body>
  <div id="app">
      <List>List>
  div>
body>
// 创建列表组件(子组件)
Vue.component('List', {
  template: `
  • {{ msg }}
  • `
    , data(){ return { msg: "数据" } }, }) // 实例化Vue(根组件) let vm = new Vue({ el: '#app', data: {} })

    在这里插入图片描述
    不难发现,List 子组件使用的数据是自身 data 身上的数据,所以毫无疑问正常显示。

    那么问题来了,List 子组件如何使用根组件(vm)身上的 data ?(下图所示)
    Vue - 通俗易懂的组件通信问题(父子传值)_第1张图片
    你只需要在 List(子组件) 加上 props 属性,props 值是一个数组,包含了接收数据(即父组件传递给子组件的变量),任何值都可以传递(对象 / 数组 / 函数 …)

    传递完成了还不行,你得 告知子组件数据传过来了,即在组件标签上绑定属性: :msg,这段话不懂没关系,看完下面的 demo 你就明白了!

    当一个值传递给一个 prop attribute 的时候,它就变成了那个组件实例的一个 property。

    我们重构上面的代码,让其完成传递:

    <body>
      <div id="app">
      		
      		
      		
           <List :msg="msg">List>
      div>
    body>
    
    Vue.component('List', {
    
      // 接收父组件数据
      props:['msg'],
      template: `
  • {{ msg }}
  • `
    , data(){ return {} }, }) // 实例化Vue let vm = new Vue({ el: '#app', data: { msg: "我是父组件的数据!" } })

    Vue - 通俗易懂的组件通信问题(父子传值)_第2张图片
    这样就完成了父传子的通信,需要注意的是 :msg = "msg" 不会被渲染。

    子 → 父

    上面我们完成了 父组件传值给子组件示例 ,下面我们基于上面的例子继续探索。

    你还记得吗?每一个子组件都是一个实例(VueComponent),就像 Vue 实例一样!

    子组件也同样拥有 methods / data 这些属性,除了没有 el

    我们在子组件中定义一个方法(show),来查看这个实例(VueComponent):

    Vue.component('List', {
      props:['msg'],
      template: `
  • {{ msg }}
  • `
    , data(){ return {} }, methods: { show(){ console.log(this) } } })

    在这里插入图片描述
    你看!接下来我们展开这个实例,并找到 $root 这个属性:
    Vue - 通俗易懂的组件通信问题(父子传值)_第3张图片
    没错!它就是我们要找的父组件实例!挂载着父组件的所有数据!


    这时你可能有疑问,这跟传递值有半毛钱关系吗?为什么不用 $emit 来监听传值?

    让我们回到最初,遐想一下,我们将 父组件 的数据传递给 子组件 ,用意是什么?

    是不是你 子组件 要用 父组件 的数据?如果不用为什么要传递?

    上面说了,子组件$root 属性下挂载着 父组件 的所有数据!

    既然能直接拿到 父组件 的所有数据,为什么还要繁琐的传递呢?

    注意:组件通信的方式有很多种,这里只谈这一种方式,您视情况而定!

    我们完成一个小示例(当点击按钮时,获取父组件数据)

    获取成功即为通信成功!

    <body>
      <div id="app">
          <List>List>
      div>
    body>
    
    // 子组件
    Vue.component('List', {
      template: `
  • 获取父组件数据:{{ msg }}
  • `
    , 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 属性上挂载的方法,懂吧!

    你可能感兴趣的:(+,Vue)