最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Vue组件通信方式

    正文概述 掘金(Muc)   2021-04-11   580

    这篇文章希望从整体上认识Vue的几种通信方式,希望做到快速全面掌握。

    一、父子组件-props/$emit

    这种通信方式很常用,也很基础,大家都很熟悉。不展示代码,仅总结用法:

    父组件->子组件: 父组件 v-bind:绑定变量传给子组件。子组件通过props接收数据。

    子组件->父组件: 子组件通过emit提交,向父组件传值,父组件通过v-on绑定事件接收数据。

       this.$emit("titleChanged","子向父组件传值");//自定义事件  传递值“子向父组件传值”
    

    父组件通过props向下传递数据给子组件。(Vue的单向数据流)

    注:组件中的数据共有三种形式:data、props、computed

    二、父子组件-通过获取组件实例的方式— parent / $children 和 ref(ref更常用)

    (标题写法:parent 前面也有$。编辑器的问题。下面也都有。)

    $root :当前组件树的根 Vue 实例。如果当前实例没有父实例,此实例将会是其自己。

    $parent:父实例,如果当前实例有的话。

    $children

    当前实例的直接子组件。需要注意 children并不保证顺序,也不是响应式的。如果你发现自己正在尝试使用children 并不保证顺序,也不是响应式的。如果你发现自己正在尝试使用 children并不保证顺序,也不是响应式的。如果你发现自己正在尝试使用children 来进行数据绑定,考虑使用一个数组配合 v-for 来生成子组件,并且使用 Array 作为真正的来源。

    子实例可以用 this.parent访问父实例,子实例被推入父实例的parent 访问父实例,子实例被推入父实例的 parent访问父实例,子实例被推入父实例的children 数组中。

    需要注意的是:这两种都是直接得到组件实例,使用后可以直接调用组件的方法或访问数据。

    this.$parent.message     //在子组件中访问父组件中的数据
    this.$children[0].num    //因为父组件可能有很多子组件
    

    注意:

    节制地使用 $parent 和 $children - 它们的主要目的是作为访问组件的应急方法。更推荐用 props 和 events 实现父子组件通信
    

    ref: 如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例。

    注意:ref 也是很重要的一种方式,且实际工作中很常用。 除了可以使用它获取数据,还可以通过ref调用子组件中的方法,使其执行。

    三、EventBus中央事件总线-emit/ on

    这种方法通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级。当我们的项目比较大时,可以选择更好的状态管理解决方案vuex。

    var bus = new Vue()
    // 组件A
    bus.$emit('id-selected', 1)
    // 组件B
    bus.$on('id-selected', function (id) {
     console.log(id)
    })
    

    $on 监听了自定义事件,因为有时不确定何时会触发事件,一般会在 mounted 或 created 钩子中来监听。

    四、Vuex

    详见本人文章: Vuex的使用和原理

    五、localstorage /sessionstorage使用

    这种通信比较简单,缺点是数据和状态比较混乱,不太容易维护。

    localStorage / sessionStorage可以结合vuex, 实现数据的持久保存,同时使用vuex解决数据和状态混乱问题.

    六、attrs/listeners (前面都有$符)

    多级组件嵌套需要传递数据时,通常使用的方法是通过vuex。但如果仅仅是传递数据,而不做中间处理,也可使用Vue2.4 版本提供的另一种方法----attrs/attrs/attrs/listeners。

    vm.$attrs

    包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。

    $listeners:

    包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件。

    // 父组件 index.vue
    <list class="list-box"  desc="描述" :list="list"></list>
    
    // 子组件 list.vue
    props: {
        list: [],
    },
    mounted() {
        console.log(this.$attrs)  // {title: "标题", desc: "描述"}
    
    // 子组件 list.vue
    <detail v-bind="$attrs"></detial>
    
    // 孙子组件 detail.vue
    // 不定义props,直接打印 $attrs
    mounted() {
        console.log(this.$attrs)  // {title: "标题", desc: "描述"}
    

    同样的,通过 listeners用类似的操作方式可以进行跨级的事件传递,实现子到父的通信。listeners 用类似的操作方式可以进行跨级的事件传递,实现子到父的通信。listeners用类似的操作方式可以进行跨级的事件传递,实现子到父的通信。listeners 包含了父作用域中不含 .native 修饰的 v-on 事件监听器,通过 v-on="$listeners" 传递到子组件内部。

    // 父组件 index.vue
    <list @change="change" @update.native="update"></list>
    
    // 子组件 list.vue
    <detail v-on="$listeners"></detail>
    // 孙子组件 detail.vue
    mounted() {
        this.$listeners.change()
        this.$listeners.update() // TypeError: this.$listeners.update is not a function
    }
    

    七、provide / inject API (一般开发不用)

    在根组件中,传入变量,然后在后代组件中使用即可。

    Vue组件通信方式

    // 父级组件提供 'foo'
    var Provider = {
      provide: {
        foo: 'bar'
      },
      // ...
    }
    // 子组件注入 'foo'
    var Child = {
      inject: ['foo'],
      created () {
        console.log(this.foo) // => "bar"
      }
      // ...
    }
    

    利用 ES2015 Symbols、函数 provide 和对象 inject:

    const s = Symbol()
    
    const Provider = {
      provide () {
        return {
          [s]: 'foo'
        }
      }
    }
    
    const Child = {
      inject: { s },
      // ...
    }
    

    慎用 provide/inject

    Vuex 和 provide/inject 最大的区别在于,Vuex 中的全局状态的每次修改是可以追踪回溯的,而 provide/inject 中变量的修改是无法控制的,换句话说,你不知道是哪个组件修改了这个全局状态。

    了解参考


    起源地下载网 » Vue组件通信方式

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元