Vue 组件间通信

1、父 ---> 子 传递

 "props""$parent" 的用法:

Vue.component('child-component', {
  template: `
    <div>
      <p>{{parentData}}</p>
      <button @click="handleClick">打印父组件数据</button>
    </div>
  `,
  // 使用 "props" 获取父组件数据
  props: {
    parentData: String
  },
  methods: {
    // 使用 "$parent" 获取父组件数据
    // 假设父组件data内有"str"的数据
    handleClick() {
      console.log(this.$parents.str);
      // 还可以直接修改 父组件数据 (不建议)
      this.$parents.str = 'childChanged';
    }
  }
})
// 父组件绑定属性
// <child-component :parentData="parentData"></child-component>

2、子 ---> 父 传递

 "$emit""$children" 的用法:

Vue.component('child-component', {
  template: `
    <div>
      <p>{{parentData}}</p>
      <button @click="handleClick">把数据以参数形式发送给父组件</button>
    </div>
  `,
  // 使用 "props" 获取父组件数据
  data() {
    return {
      childrenData: 'children'
    }
  },
  methods: {
    // 使用 "$parent" 获取父组件数据
    // 假设父组件data内有"str"的数据
    handleClick() {
      // 父组件监听 "selfEvent" 事件,并获取数据
      this.$emit('selfEvent', this.childrenData)
      // 还可以直接修改 父组件数据 (不建议)
      this.$parents.str = 'childChanged';
    }
  }
})
// 父组件捕捉到事件,并获取数据
// <child-component @selfEvent="getChildData"></child-component>
getChildData(data){ 
  console.log(data);
  // 使用 "$children" 获取/修改子组件数据,获取到的为数组对象,但不建议直接修改
  this.$children[0].childrenData = 'parentData';
}

3、父 <---> 子 双向绑定

  "v-model" 的用法:

// 假设有如下组件
Vue.component('base-checkbox', {
  // model设定数据来源及发送数据源
  model: {
    prop: 'checked',
    event: 'change'
  },
  // 注意,仍需要在本子组件的props内声明checked
  props: {
    checked: Boolean
  },
  template: `
    <input
      type="checkbox"
      v-bind:checked="checked"
      v-on:change="$emit('change', $event.target.checked)"
    >
  `
})
// 然后就可以在父组件中使用 v-model 双向绑定数据
<base-checkbox v-model="lovingVue"></base-checkbox>

 ".sync" 的用法:(上例子的进阶写法)

Vue.component('base-checkbox', {
  props: {
    checked: Boolean
  },
  // 注意 $emit 需要使用 "update:" 
  template: `
    <input
      type="checkbox"
      v-bind:checked="checked"
      v-on:change="$emit('update:change', $event.target.checked)"
    >
  `
})
// 父组件的 "lovingVue" 与子组件的 "checked" 双向绑定
<base-checkbox :checked.sync="lovingVue"></base-checkbox>

4、爷 <---> 孙 传递

利用 v-bind="$attrs"v-on="$listeners" ,具体用法及注意事项查看官方文档。还涉及 "inheritAttrs"属性 的用法。

<div id="app">
  <p>父组件接收的数据:{{fromGrandson}}</p>
  <hr>
  <child :tograndson="tograndson" @tograndfather="toGrandfather></child>
</div>
Vue.component('grandson', {
  props: ['tograndson'],
  template: `
    <div>
      <p>孙组件接收的数据:{{tograndson}}</p>
      <button @click="$emit('tograndfather','to grandfather!')">点击发送给"父组件"</button>
    </div>
  `
});
Vue.component('child', {
  template: `
    <div>
      <p>子组件作为"中转站"</p>
      <hr>
      <grandson v-bind="$attrs" v-on="$listeners"></grandson>
    </div>
  `
});
new Vue({
  el: '#app',
  data: {
    tograndson: 'to grandson !',
    fromGrandson: ''
  },
  methods:{
    toGrandfather(data){
      this.fromGrandson = data;
    }
  }
});

运行结果:(在线demo


5、祖先 <---> 后代 传递

 "$root" 的用法:

// 假设根组件有数据 ancestorData: 'this is ancestor data!'
// "后代"组件使用 "$root" 获取数据
Vue.component('posterity', {
  template: `<div><p>{{$root.ancestorData}}</p></div>`,
  methods: {
    // 子组件也可以直接修改父组件的数据(不建议此做法)
    changeRootData(){
      $root.ancestorData = 'changeRootData';
    }
  }
})

 "provide" & "inject" 依赖/注入 :

// 最简单的例子:
Vue.component('child', {
  // 显示 "bar"
  template:`<div><p>{{foo}}</p></div>`,
  // 注入父组件或祖先组件的数据"foo"
  inject: ['foo']
});
new Vue({
  el: '#app',
  // 提供给子组件或后代组件的数据依赖
  provide: {
     foo: 'bar'
  }
});
// inject 的更多属性:
// 用对象的方式书写,"foo" 为父组件/祖先组件provide的数据名
inject: { foo: 'foo' }
// 提供默认值,当父组件/祖先组件provide内不存在"foo"时使用default值
inject: {
  foo: { default: 'fooooooooo' }
}
// 使用"from"指定其源属性,等效 inject:{foo:'bar'}
inject: {
  foo: {
    from: 'bar',
    default: 'foorrrr'
  }
}

6、兄 <---> 弟 传递

 "this.$parent.$emit" & "this.$parent.$on" 

Vue.component('child1', {
  template:`<div>
    <p>{{childOne}}</p>
    <button @click="handleClick">child1</button>
  </div>`,
  data() { return { childOne: 'childOneData' } },
  methods: {
    handleClick(){ this.$parent.$emit('childone', this.childOne); }
  }
});
Vue.component('child2', {
  template:`<div><p>{{childTwo}}</p></div>`,
  data() { return { childTwo: 'childTwoData' } },
  created() {
    this.$parent.$on('childone', (data) => { this.childTwo = data; })
  }
});

7、数据仓库

 "Vue.prototype.$bus" | "window.$bus" 

// 全局定义
Vue.prototype.$bus = { a: 1 };
window.$bus = { b: 2 };
// 所有组件均可以访问/修改/添加 $bus 的内容 (以钩子函数mounted为例)
mounted() {
  console.log(this.$bus);     // { a: 1 }
  console.log($bus);          // { b: 2 }
  this.$bus.c = 3;            // { a: 1, c: 3 }
}

 "Vuex"

飞机票

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值