一.父传子
传递: 通过在子组件:属性 = 变量 来传递
接收:在子控件内部,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'] }