• vue——爷孙组件之间通信 前端


    参考: vue父、子、孙组件间数据传递、事件传递 - 掘金 (juejin.cn)

    方式一. 利用$attrs实现祖孙组件间的数据传递,$listeners实现祖孙组件间的事件监听

    $attrs包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。
    $listeners包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。
    例:
     
    爷组件:
    <div>
         <my-mask :show="isShow" :title="title" :con="con" @on-submit="submit"></my-mask>
    </div>
    ... ... components: { myMask, // 子组件 }, data() { return { isShow: false, title: '我是标题', con: '我是内容', }; }, methods: { submit() { window.alert('关闭弹层'); this.isShow = false; }, } ... ...

    子组件my-mask:

    <div class="mask" v-if="show">
        <div class="mask-bg"></div>
        <alert v-bind="$attrs" v-on="$listeners"></alert>
    </div>
    
    ... ...
    
        components: {
            alert, // 孙组件
        },
        inheritAttrs: false,
        data() {
            return {}
        },
        props: ['show'],
    ... ...

    爷组件在传递数据给子组件的时候,如果子组件没有通过props接收祖组件传递的参数,那么这个数据会表现在子组件的根标签的属性上;通过设置 inheritAttrs 为 false,这些默认行为将会被去掉。

    然后我们可以在子组件绑定v-bind="$attrs",将这些特性传递给孙组件,孙组件通过props接收数据,同理可以通过 $listeners 实现爷孙之间的事件监听器传递。

    孙组件alert:

    <div class="alert">
        <h2>{{title}}</h2>
        <div class="alert-con">{{con}}</div>
        <button class="submit" @click="submit">确定</button>
    </div>
    
    ... ...
    
      data() {
            return {}
        },
        props: ['title', 'con'], // title和con来自于爷组件
        methods: {
            submit() {
                this.$emit('on-submit'); // 会触发爷组件的submit事件
            }
        }
    ... ...

    方式二. 利用provide/inject 实现祖孙组件间的数据传递和事件监听

    provide 和 inject 主要为高阶插件/组件库提供用例,允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。

    例:

    爷组件:

    <div>
        <my-con></my-con>
    </div>
    
    ... ...
    
     components: {
            myCon, // 子组件
        },
        provide() {
            return {
                store: this.store
            }
        },
        data() {
            return {
                store: {
                    state: {
                        type: 0
                    },
                    commit (type, value) {
                        this.state[type] = value
                    }
                },
            };
        },
        methods: {
            changeCon() {
                this.store.state.type ++;
                if(this.store.state.type > 2) this.store.state.type = 0;
            },
        },
    ... ...

    子组件my-con:

    <div>
        <my-table></my-table>
    </div>
    
    ... ...
    
        components: {
            myTable, // 孙组件
        },
        props: [],
    ... ...

    孙组件my-table:

    <div>
        <div class="tab-list">
            <span class="tab-item" v-for="(item, index) in list" @click="switchType(item.type)" :class="{'active': item.type === store.state.type}">{{item.value}}</span>
        </div>
    </div> 
    
    ... ...
    
         data() {
            return {
                tableType: 0,
                list: [{value: '新闻', type: 0}, {value: '汽车', type: 1},{value: '娱乐', type: 2}]
            }
        },
        inject: ['store'],
        methods: {
            switchType(value) {
                this.store.commit('type', value)
            }
        }
    ... ...
  • 相关阅读:
    Eric 的随机文件名 生成方法
    .NET模板引擎 EFPlatform.CodeGenerator (代码生成器 静态页生成 生成HTML 模板)
    Eric的行政区(省市)下列表控件和标签控件
    下载网页中远程图片的方法
    一起来玩Twister(扭扭乐)
    ASP.NET 安全认证(四)——巧妙实现 Form 表单认证跨站点、跨服务器的单点登录(Single Sign On) .
    DataList的编辑、更新、删除、全选、分页以及 <EditItemTemplate>模版中的DropDownList的数据绑定
    ASP.NET 安全认证(三)—— 用Form 表单认证实现单点登录(Single Sign On) .
    C# 中的委托和事件
    ASP.Net获取当前运行文件的文件名称
  • 原文地址:https://www.cnblogs.com/linjiangxian/p/15852746.html
Copyright © 2020-2023  润新知