vue(六)

本文详细介绍了Vue.js中组件间的通信方式,包括$emit、props、.sync修饰符、$parent/$children、中央事件总线(bus)以及Provide/Inject。通过实例演示了如何在父子组件间、多层组件间以及不直接相关的组件间传递数据,同时也提到了一些不推荐的直接修改父组件数据的方法,强调了最佳实践和注意事项。
摘要由CSDN通过智能技术生成

反向传值

  • 即子代向父传值

  • 语法:$emit

  • $emit的第一个参数来自定义的事件,第二个参数为要传递给父组件的值,父组件在子组件标签上绑定自定义事件来接收子组件传递的数据

    • 父组件中使用子组件时,在子组件身上绑定一个自己的更新事件

      <Box :data="value" @myevent="myevent1"></Box>
      
      //补充一种语法糖写法   注意这里的v-model的底层代码对应的是input方法,在使用其他方式的不要使用该语法糖
      <Box V-model="value"></Box>
      //这里相当于
      <Box @input="input" :value="value"></Box>
      
    • 在父组件中定义这个事件

      myevent1:function(value){//这个函数被定义在父组件种,将会在子组件中被触发,其中value参数表示子组件更新后的值
      	this.value = value
      }
      
    • 子组件中首先通过props接收父组件传过来的值

      props:{
      	data:{
      		type:String,
              default:''
          }
      }
      
    • 子组件在更新这个值的函数里,同时通过this.$emit触发父组件的myevent事件

      methods:{
      	change(){
      		this.$emit("父组件中的@事件类型名","新的值")
      	}
      }
      
    • 这里给出一个简单的完整示例 该示例由App.vue Box.vue两个文件组成

      • App.vue代码
      <template>
        <div id="app">
          <Box :msg="msg" @mychange="change"></Box>
        </div>
      </template>
      
      <script>
      import Box from "./Box.vue"
      export default {
        data() {
          return {
            msg:"父组件中的msg"
          }
        },
        components:{
          Box
        },
        methods: {
          change(arg){
            this.msg = arg
          }
        }
      };
      </script>
      
      <style lang="scss">
      </style>
      
      
      • Box.vue代码
      <template>
          <div>
              <h1>Box----{{msg}}</h1>
              <button @click="change">点击修改app中的msg值</button>
          </div>
      </template>
      
      <script>
      export default {
          props:["msg"],
          methods: {
              change(){
                  this.$emit("mychange","Box通过反向传值修改到了app里的值")
              }
          }
      }
      </script>
      
      <style lang="">
          
      </style>
      
  • 补充一点

    • 如果想给组件绑定原生事件

    • 方法:给事件绑定事件修饰符 .native 拿上面完整的示例中的代码举例

      <Box :msg="msg" @click.native="change"></Box>
      
  • 子组件直接修改父组件中的数据

    • 前面提到的子组件修改父组件的方法,都是通过函数传值到父组件,在通过父组件的函数对父组件的数据进行修改,这里给出一种子组件可以直接修改到父组件的方法

    • 语法:.sync修饰符 这是一种语法糖的写法

    • 同样使用前面完整的示例中的代码举例

      • App.vue中当我们加上.sync修饰符后,可以省略掉App.vue中的change方法

        <Box :msg.native="msg" ></Box>
        
      • Box.vue中不改变

多层组件传值

  • l i s t e n e r s / listeners/ listeners/attrs

    • 其中$listeners负责事件传递

    • $attrs负责属性传递,接收非props属性的值 包含了父作用域不作为prop被识别(且获取)的特性绑定(class和style除外)

    • 这里简单举例 假设我们有三层传递 这里仅给出中间层代码 其中被注释的部分为不引用 l i s t e n e r s / listeners/ listeners/attrs的情况

      <template>
      	<div>
      		<!-- <Three @twochange1="twochange1" :count="count"></Three> -->
      		<Three v-bind="$attrs" v-on="$listeners"></Three>
      	</div>
      </template>
      
      <script>
      	import Three from "./Three.vue"
      	export default {
      		// props:["count"],
      		components:{
      			Three
      		},
      		methods:{
      			// twochange1(v){
      			// 	this.$emit("appchange1",v)
      			// }
      		}
      	}
      </script>
      
      <style>
      </style>
      
      
      

p a r e n t / parent/ parent/root、 c h i l d r e n / children/ children/refs

  • 这些功能都是有劣势或危险的场景,官方建议我们尽量避开它们

  • $root:访问根组件vm对象,所有的子组件都可以将这个实例作为一个全局 store来访问或使用,现在有更好的技术vuex来代替

    • 在任何组件都可以直接利用this.$root来访问根组件
  • $parent:访问父组件对象,直接操作父组件的data数据,不需要再使用属性传值,但是容易出现渲染混乱之后只渲染一个的情况

  • $children:访问子组件对象数组,不能保证顺序,也不是响应式的

  • 这里补充一下;前三者的关系可以理解为 r o o t 为 祖 先 , 然 后 root为祖先,然后 rootparent与 c h i l d r e n 是 父 亲 与 儿 子 的 关 系 , 且 children是父亲与儿子的关系,且 childrenroot的$parent为undefined

中央事件总线bus

  • 通过创建一个新的vm对象,专门统一注册事件,供所有组件共同操作,达到所有组件随意隔代传值的效果

  • 具体方法为新建一个js文件来引入 文件内写上如下代码即可

    import Vue from "vue"
    let bus=new Vue({
    	methods:{
    		on(eventname,cb){			
    			this.$on(eventname,cb)
    		},
    		emit(eventname){
    			this.$emit(eventname,...arguments)
    		},
    		off(eventname){
    			this.$off(eventname)
    		}
    	}	
    })
    export default bus;
    
    • 然后在main.js引入该js文件,并将引用结果设置到原型上

      import $bus from "./bus.js"
      Vue.prototype.$bus=$bus
      

Provide/Inject

  • 通常情况下,组件向组件传递数据,可以采用父子props层层传递,也可以使用busVuex直接交互。在Vue2.2.0之后,Vue还提供了provide/inject选项

  • 但是官网不建议在应用中直接使用该方法

    //父组件中
    export default{
    	provide:{}
    }
    //后代组件中
    export default{
      inject: []
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值