Vue 2.0 中利用 $attrs 与 $listeners 实现多级组建数据传递与事件响应 以及 Vue 3.0 中的实现

120 阅读2分钟

attrsattrs 与 listeners 分别在 Vue 2.0 与 Vue3.0 中的使用

Vue3.0

// 在一级组建中
// 定义一个子组件testSub.vue 并导入
import testSubVue from './testSub.vue';
// 这里 event 与 test 方法 分别为子组件和孙子组建中的自定义事件 两个名字不能写成一样否则会有一个不会响应
<testSubVue :msg="msg" :money="money" :title="title" :desc="desc" v-on:event="event" v-on:test="test"></testSubVue>
setup() {
    const data = reactive({
            msg:"Hello ",
            money:10000,
            title:"Hello",
            desc:"GoodBoy"
        })
    const event =(value)=> {
            console.log('父组件响应事件' + value)
        }

     const test= (e) => {
            console.log('父组件响应事件' + e)
     }
     
     return {
          event,
          test,
          ...toRefs(data)
     }
        
}

// 在二级组建中
// 新建一个子组件并导入
import subView from '@/views/textSubSubView.vue'
 components: {
      subView
 },
 
 // 这里有一点 如果当前组建使用props 接收了上一级组建传递的数据 那么在attrs 中将不被包含 
 props:["msg"],
 // 这下面的逻辑可以不要 只是另外一种一级一级事件传递的实现方式 这里不用只做记录
 emits: ['event'],
 setup(props, ctx) {
       const event =(e)=> {
           console.log('二级组建的接收事件' + e)
            //  ctx.emit('event',e)
       }
        return {event}
    }

// 组建模板中的代码实现
<span>父组件给的值{{ $attrs }}</span>
<!-- v-on="$listeners"  vue 3.0 中被移除 -->
<subView v-bind="$attrs" v-on:event="event" ></subView>
<button @click="clickSend">listern替换的实现方法</button>

**// 在三级组建中**
    <div>
      <h3>testView 的第三级组建</h3>
      <span>{{ $attrs.desc }}</span>
      <button @click="clickAction">listener事件</button>
   </div>
   
   export default {
        emits: ['test'],
        setup(props, ctx) {
            const clickAction = () => {
                ctx.emit('test','H11111.....')
            }
            return {clickAction}
        }
    }

  • 以上就是Vue 3.0 中多级父子组建间数据传递的实现 遗憾的是在Vue 3.0 中 $listeners修饰符被废弃了

Vue 2.0 中 attrsattrs 与 listener 的实现

// 一级组建
// 新建 testView 子组件 以及 testSubView孙子组建
    import testView from '@/components/testView.vue'
    components: {
        testView
      },
      data() {
        return {
          msg:"Hello111",
          money:10000
        }
      },
     action(value) {
         console.log('第三级组建传递过来的数据.........' + value)
     }
    
    // 组建模板
    <testView :money="money" :msg="msg" @action="action"></testView>
    
    
    // 二级组建
        import sonView from '@/components/testSubView.vue'
        components: {
            sonView
        },
    // 组建模板  (这里是与Vue 3.0 不同的地方主要使用 v-on添加$listeners 修饰符  3.0中使用v-on直接绑定响应事件)
        <sonView v-bind="$attrs" v-on="$listeners"></sonView>
        
    
   // 三级组建
        <h3>第三级组建</h3>
        <div>---{{ $attrs.msg }}---</div>
        <button @click="clickAction">三级listeners 事件</button>
        <testEndView v-bind="$attrs" v-on="$listeners"></testEndView>
        methods: {
            clickAction() {
                this.$emit('action')
            }
        }

  • 以上就是Vue 2.0 中 attrsattrs 与listener 的完整实现
总结: 共同点 2.0 和 3.0 中都使用 v-bind=attrs向下传递响应式数据在子组件中如果使用了props接收了某个对象数据那么attrs中就不再限制该数据只显示没有被props接收的数据不同点:Vue2.0中使用von=attrs 向下传递响应式数据 在子组件中如果使用了props接收了某个对象数据 那么 attrs 中就不再限制该数据 只显示没有被props 接收的数据 不同点: 在Vue 2.0 中使用v-on=listeners 修饰符实现事件的响应 在Vue 3.0 中废了了$listeners 方法 转而使用v-on:事件名 =”事件名“的方式直接响应子组件的事件 相对于Vue 2.0 中实现更加轻便
  • 新手小白 如果错误还望过路大神及时指教 如有更优实现方式还望不吝赐教