vue 之 数据传递(子传父,父传子,非父子通信<事件总线>,父取子<ref,$refs>,插槽,provide和inject数据传递)

一.父传子

传递: 通过在子组件:属性 = 变量 来传递 

接收:在子控件内部,props 来接收

第一种:传递基本数据类型

问题:不能直接被用作子组件的v-model双向绑定的变量,否则报错

解决:可以在data中定一个新的变量,把这个值给这个新的变量

第二种:传递对象Object

问题:可以将obj.属性作为子组件的v-model双向绑定的变量,修改时不报错,但是这样做了以后会污染父组件的obj对象,所以需要避免这个情况

解决:可以通过浅拷贝和深拷贝来处理,这样就可以避免污染父组件数据

说明:在通过拷贝时,在created,beforeMount,mounted三个生命周期都有写, 注意,计算属性不要和双向绑定混合使用

app.vue


<template>
  <div id="app">
    <HelloWorld :msg="msg" :person="person" keys="默认key值" @iptFn1="iptFn1" />
  </div>
</template>

<script>
import HelloWorld from "./components/HelloWorld.vue";

export default {
  name: "App",
  data() {
    return {
      msg: "这是父传子",
      person: {
        name: "张三",
        age: 18,
      },
    };
  },
  components: {
    HelloWorld,
  },
  methods: {
    iptFn1() {
      console.log(this.person);
    },
  },
};
</script>

<style></style>

  

 

 

hellow.vue

<template> <div class="hello"> <!-- msg的值 --> {{ msg }} <input type="text" v-model="msg1" @input="iptFn" /> <hr /> <!-- 对象属性 传过来的重新给person1 --> <input type="text" v-model="person1.name" @input="iptFn1" /> <hr /> <!-- 对象属性 浅拷贝额对象created,beforeMount,mount --> <input type="text" v-model="person2.name" @input="iptFn2" /> {{ "person2:" + person2.name }} <hr /> <!-- 对象属性 计算属性中拷贝 --> <input type="text" v-model="person3.name" @input="iptFn3" /> {{ "person3:" + JSON.stringify(person3) }} <hr /> <!-- person的内容 --> {{ person }} <hr /> <!-- keys的值 --> {{ keys }} </div> </template> <script> import $ from "jquery"; export default { name: "HelloWorld", props: { msg: { type: String, default: "消息", require: true, }, person: { type: Object, default: function() { return {}; }, }, keys: { type: String, }, }, data() { return { msg1: this.msg, person1: this.person, person2: {}, }; }, computed: { // person3() { // return $.extend(false, this.person); //当被用作双向绑定时,会出现无法 // }, }, created() { // this.person2 = $.extend(false, this.person); }, beforeMount() { // this.person2 = $.extend(false, this.person); }, mounted() { this.person2 = $.extend(false, this.person); }, methods: { iptFn() { console.log(this.msg1); }, iptFn1() { this.person1.age = 20; this.$emit("iptFn1"); }, iptFn2() { console.log(this.person2.name); // this.$emit("iptFn1"); }, iptFn3() { console.log(this.person3.name); // this.$emit("iptFn1"); }, }, }; </script> <style scoped></style>

  

二.子传父

传递:在子组件内部写,this.$emit('事件名',参数1[,参数2...])

接收:在父组件中的子组件上写 @事件名 = 事件名,同时在父组件methods上定一个接收参数的方法

 

三.非父子间的通信(事件总线)

    请参考vue 之 事件总线(订阅者模式,非父子间的数据传递) 

    建议:多熟悉一下事件总线的使用,可以发现事件总线可以替代 孙-->子-->父的这种通$emit形式来处理的方案.

   语法:

//在main.js 定义一个bus     
const bus = new Vue()
Vue.prototype.bus  = bus

//发布
this.bus.$emit('key',参数) //参数可以是基础数据类型或者复杂数据类型

//接收   建议: 在created,beforeMount,mounted生命周期去使用
this.bus.$on('key',(res)=>{  //res是从发布传过来的值  })

  

 

四.父拿取子的数据

   ref 和 $refs 来通过 父读取子的数据

   注意点:

   1.$refs一定是属于父的

   参考网站: Vue中ref和$refs的介绍及使用

 

 

五.可以通过插槽父取子 (仅仅局限所在的插槽内部使用)

 

六.provide 和 inject (数据传递)

parent.vue

export default {
    data(){
       return {
          name:'张三',
          age:18
       }
   },
   provide(){
      return {
         name:this.name
      }
   },
components:{
son
} }
son.vue

<div>{{  name  }}</div>

export default {
   
   inject:['name'],
   components:{
      Grandson
   }
}

 

grandson

<div>{{  name  }}</div>

export default {
   
   inject:['name']
}

  

  

  

 

 

 

 

vue 之 插槽slot

posted @ 2021-03-03 16:06  zmztyas  阅读(260)  评论(0编辑  收藏  举报