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

一.父传子

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

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

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

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

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

第二种:传递对象Object

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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>

  

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
hellow.vue<br><br><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形式来处理的方案.

   语法:

1
2
3
4
5
6
7
8
9
//在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 (数据传递)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
parent.vue
 
export default {
    data(){
       return {
          name:'张三',
          age:18
       }
   },
   provide(){
      return {
         name:this.name
      }
   },<br>   components:{<br>     son<br>   }
}
1
2
3
4
5
6
7
8
9
10
11
son.vue
 
<div>{{  name  }}</div>
 
export default {
    
   inject:['name'],
   components:{
      Grandson
   }
}

 

1
2
3
4
5
6
7
8
grandson
 
<div>{{  name  }}</div>
 
export default {
    
   inject:['name']
}

  

  

  

 

 

 

 

vue 之 插槽slot

posted @   zmztyas  阅读(275)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示