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

  • 相关阅读:
    Google Go语言推出第一个正式版本:Go 1
    前端开发工作感悟:具体的量化指标
    AIR SDK 更新方法
    HTML5 MediaStream的运用
    理解css中的长度单位
    快速提高 Vi/Vim 使用效率的原则与途径
    Saving the Day with Scoped CSS
    事件的发生顺序HTML5移动开发
    BigPipe学习研究
    构建合规的Web应用程序
  • 原文地址:https://www.cnblogs.com/liyf-98/p/14421479.html
Copyright © 2011-2022 走看看