zoukankan      html  css  js  c++  java
  • Vue -> 组件通信

    组件通信

    :v-bind (props) $emit
    在父组件中定义一个数据 父->子
    data(){
    	return {
    		message: 'hello world';
    	}
    }
    template中
    <child :message="message" />
    通过prop属性的方式把message绑定到变量message里面 
    在子组件里就可以接受这个prop
    props:['message']然后进行使用
    template:
    {{message}}
    
    在子组件中:  子->父
    methods:{
    	xxx(){
    		this.$emit('aaa','bbb')   
    		// bbb是携带的值 当事件触发时 就会把bbb带入到$event这个变量中 赋值给message
    		// 所以当事件触发时最终会把message设置为bbb
    	}
    }
    在父组件中就可以监听aaa事件
    <child :message="message" @aaa="message = $event"  />
    当事件触发最终会把message设置为bbb
    

    回调函数(callback)

    也是props + $emit

    父组件中: 父->子
    data(){
    	return {
    		message: '';
    	}
    },
    methods:{
    	changeMessage(){
    		this.message = 'aaa'
    	}
    }
    template:
    <child :message="message" :changeMessageFn="changeMessage"  /> 把changeMessage作为另外一个prop传给child
    所以此时child就接收message和changeMessageFn两个prop
    在子组件中:
    props:['message','changeMessageFn']然后进行使用
    template:
    <button @click="changeMessageFn">按钮</button>
    在点击时就可以执行changeMessageFn
    
    $root $parent $children
    访问根组件
    this.$root.foo 
    // 获取根组件的数据/计算属性/方法
    // 所有的子组件都可以将这个实例作为一个全局 store 来访问或使用。
    
    在子组件中访问父组件
    this.$parent.message
    
    在父组件中访问子组件
    this.$children[0].number   
    // [0]是因为一个父组件可以有很多子组件
    // 当前实例的直接子组件。需要注意 $children 并不保证顺序,也不是响应式的。
    
    
    1. 对于 demo 或非常小型的有少量组件的应用来说这是很方便的。
      不过这个模式扩展到中大型应用来说就不然了。因此在绝大多数情况下,我们强烈推荐使用 Vuex 来管理应用的状态。

    ​ - Vue官方文档

    provide + inject 依赖注入

    这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。

    provide

    选项应该是一个对象或返回一个对象的函数。该对象包含可注入其子孙的 property。在该对象中你可以使用 ES2015 Symbols 作为 key,但是只在原生支持 SymbolReflect.ownKeys 的环境下可工作。

    inject

    一个字符串数组 或

    一个对象,对象的 key 是本地的绑定名,value 是:

    • 在可用的注入内容中搜索用的 key (字符串或 Symbol),或
    • 一个对象,该对象的:
      • from property 是在可用的注入内容中搜索用的 key (字符串或 Symbol)
      • default property 是降级情况下使用的 value

    提示:provideinject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的 property 还是可响应的。

    ​ - 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 },
      // ...
    }
    
    
    父组件中:
    export default{
    	provide:{
    		message:'aaaa'
    	}
    }
    子组件中:
    export default{
    	inject:['message']
    }
    template:
    {{message}}
    

    依赖注入还是有负面影响的。它将你应用程序中的组件与它们当前的组织方式耦合起来,使重构变得更加困难。同时所提供的 property 是非响应式的。这是出于设计的考虑,因为使用它们来创建一个中心化规模化的数据跟使用 $root做这件事都是不够好的。如果你想要共享的这个 property 是你的应用特有的,而不是通用化的,或者如果你想在祖先组件中更新所提供的数据,那么这意味着你可能需要换用一个像 Vuex这样真正的状态管理方案了。

    ​ - Vue官方文档

    $attrs + $listeners
    三级组件: parent child grandchild
    $attrs:
    
    parent中:
    定义message  并在child中:message="message"
    child中:
    给grandchild组件绑定
    <grandchild v-bind="$attrs">   //$attrs属性包括了parent中传过来的message
    grandchild中:
    template:
    {{$attrs.message}}
    
    $listeners:
    
    parent:
    methods:{
    	aaa(){
    		this.message='aaa'
    	}
    }
    在child标签上定义了一个事件监听器
    <child @aaa="aaa">
    在child中就可以通过:  
    <button @click="$listeners.aaa">按钮</button> 访问到
    此时就可以执行绑定的事件处理函数aaa 把name改为aaa  在点击按钮的时候就会修改
    
    ref refs

    ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。

    父组件中:
    <child ref="childaaa">
    methods:{
    	aaa(){
    		使用:
    		this.$refs.childaaa可以获取到这个组件实例child 就可以访问属性 执行方法
    		this.$refs.childaaa.xxx
    		this.$refs.childaaa.xxx()
    	}
    }
    // $refs 只会在组件渲染完成之后生效,并且它们不是响应式的。
    // 应该避免在模板或计算属性中访问 $refs。
    

    兄弟组件通信

    需求:child1点击按钮可以修改数据传到child2中

    props + $emit 经过父亲

    child1:
    使用$emit方式 在父组件中监听发射的事件 然后就可以修改数据值 
    父组件中的值修改了 就会传递给child1和child2 所以child2就可以接收数据了 
    

    EventBus = new Vue 不经过父亲 一:$emit 二:监听

    main.js中:
    export const eventBus = new Vue()  //eventBus实际上就是vue的实例 所以可以在main.js创建并导出
    然后就可以在child1中使用eventBus
    child1:
    eventBus.$emit('aaa','bbb') //因为eventBus是vue实例 所以存在$emit方法 并携带bbb
    child2:
    created(){
    	eventBus.$on('aaa',(name)=>{
    		this.name=name   // name为携带的bbb
    	})
    }
    
    

    具体的总线学习内容可参见 Vue-EventBus

  • 相关阅读:
    231. Power of Two
    204. Count Primes
    205. Isomorphic Strings
    203. Remove Linked List Elements
    179. Largest Number
    922. Sort Array By Parity II
    350. Intersection of Two Arrays II
    242. Valid Anagram
    164. Maximum Gap
    147. Insertion Sort List
  • 原文地址:https://www.cnblogs.com/liyf-98/p/14421479.html
Copyright © 2011-2022 走看看