赞
踩
props和$emit仅仅限制在父子组件中使用
<template> <div> <!-- 这是父组件 --> <div>父组件中的基本数据类型age的值是:{{this.age}}</div> <div>父组件中引用数据类型person的值是:{{this.person.name}} --- {{this.person.address}}</div> ---------------------------------------------------------------------------------------------------- <HelloWorld :age="age" msg="这是父组件的数据" :person="person"/> </div> </template> <script> import HelloWorld from '@/components/HelloWorld.vue' export default { name: 'Home', data(){ return { age : 18, person: { name: "张三", address: "aaa" } }; }, components: { HelloWorld }, } </script>
<template> <div> <!-- 这是子组件 --> <div>这是子组件,接收父组件的数据传递,age的值是:{{this.age}}</div> <div>这是子组件,接收父组件的数据传递,person的值是:{{person.name}} --- {{person.address}}</div> </div> </template> <script> export default { name: 'HelloWorld', props:["age", "person"], } </script>
<template> <div> <!-- 这是父组件 --> <div>父组件中的基本数据类型age的值是:{{this.age}}</div> <div>父组件中引用数据类型person的值是:{{this.person.name}} --- {{this.person.address}}</div> <div>父组件中接收子组件的数据fatherInfo的值是:{{this.fatherInfo}}</div> ---------------------------------------------------------------------------------------------------- <HelloWorld :age="age" :person="person" @sendFather="reciveInfo"/> </div> </template> <script> import HelloWorld from '@/components/HelloWorld.vue' export default { name: 'Home', data(){ return { age : 18, person: { name: "张三", address: "aaa" }, fatherInfo: "" }; }, components: { HelloWorld }, methods: { reciveInfo(info) { this.fatherInfo = info; } } } </script>
<template> <div> <!-- 这是子组件 --> <div>这是子组件,接收父组件的数据传递,age的值是:{{this.age}}</div> <div>这是子组件,接收父组件的数据传递,person的值是:{{person.name}} --- {{person.address}}</div> ---------------------------------------------------------------------------------------------------- <div><button @click="sendMessage">子组件向父组件传递数据的按钮</button></div> </div> </template> <script> export default { name: 'HelloWorld', data() { return { info: "这是子组件的数据" } }, props:["age", "person"], methods: { sendMessage() { this.$emit("sendFather", this.info); } } } </script>
<template> <div> <!-- 这是父组件 --> <div>父组件中的基本数据类型age的值是:{{this.age}}</div> <div>父组件中引用数据类型person的值是:{{this.person.name}} --- {{this.person.address}}</div> <div>父组件中接收子组件的数据fatherInfo的值是:{{this.fatherInfo}}</div> ---------------------------------------------------------------------------------------------------- <HelloWorld :age.sync="age" :person.sync="person"/> </div> </template> <script> import HelloWorld from '@/components/HelloWorld.vue' export default { name: 'Home', data(){ return { age : 18, person: { name: "张三", address: "aaa" }, fatherInfo: "" }; }, components: { HelloWorld }, methods: { reciveInfo(info) { this.fatherInfo = info; } } } </script>
<template> <div> <!-- 这是子组件 --> <div>这是子组件,接收父组件的数据传递,age的值是:{{this.age}}</div> <div>这是子组件,接收父组件的数据传递,person的值是:{{person.name}} --- {{person.address}}</div> ---------------------------------------------------------------------------------------------------- <div><button @click="sendMessage">用于修改props里面值的按钮</button></div> </div> </template> <script> export default { name: 'HelloWorld', data() { return { info: "这是子组件的数据" } }, props:["age", "person"], methods: { sendMessage() { this.$emit("update:age", 19); this.$emit("update:person", {name: "李四", address: "bbb"}); } } } </script>
<template> <div> <!-- 这是父组件 --> <div>父组件中的基本数据类型age的值是:{{this.age}}</div> <div>父组件中引用数据类型person的值是:{{this.person.name}} --- {{this.person.address}}</div> <div>父组件中接收子组件的数据fatherInfo的值是:{{this.fatherInfo}}</div> ---------------------------------------------------------------------------------------------------- <HelloWorld :age="age" :person="person"/> </div> </template> <script> import HelloWorld from '@/components/HelloWorld.vue' export default { name: 'Home', data(){ return { age : 18, person: { name: "张三", address: "aaa" }, fatherInfo: "" }; }, components: { HelloWorld }, methods: { reciveInfo(info) { this.fatherInfo = info; } } } </script>
<template> <div> <!-- 这是子组件 --> <div>这是子组件,接收父组件的数据传递,age的值是:{{this.age}}</div> <div>这是子组件,接收父组件的数据传递,person的值是:{{person.name}} --- {{person.address}}</div> ---------------------------------------------------------------------------------------------------- <input v-model="age" placeholder="请输入年龄"/> <input v-model="person.name" placeholder="请输入名称"/> </div> </template> <script> export default { name: 'HelloWorld', data() { return { info: "这是子组件的数据" } }, props:["age", "person"], methods: { sendMessage() { this.$emit("update:age", 19); this.$emit("update:person", {name: "李四", address: "bbb"}); } } } </script>
<template> <div> <!-- 这是父组件 --> <div>父组件中的基本数据类型age的值是:{{this.age}}</div> <div>父组件中引用数据类型person的值是:{{this.person.name}} --- {{this.person.address}}</div> <div>父组件中接收子组件的数据fatherInfo的值是:{{this.fatherInfo}}</div> ---------------------------------------------------------------------------------------------------- <HelloWorld :age="age" :person="person"/> </div> </template> <script> import HelloWorld from '@/components/HelloWorld.vue' export default { name: 'Home', data(){ return { age : 18, person: { name: "张三", address: "aaa" }, fatherInfo: "" }; }, components: { HelloWorld }, methods: { reciveInfo(info) { this.fatherInfo = info; } } } </script>
<template> <div> <!-- 这是子组件 --> <div>这是子组件,接收父组件的数据传递,age的值是:{{this.age}}</div> <div>这是子组件,接收父组件的数据传递,person的值是:{{person.name}} --- {{person.address}}</div> ---------------------------------------------------------------------------------------------------- <div><button @click="sendMessage">用于修改props里面值的按钮</button></div> </div> </template> <script> export default { name: 'HelloWorld', data() { return { info: "这是子组件的数据" } }, props:["age", "person"], methods: { sendMessage() { this.age = 19; this.person.name = "李四"; } } } </script>
provide和inject在传递上比方式一更加的宽泛,当provide的组件上添加了,那么其后代都可以通过inject进行数据接收,不限制在父子组件之间
<template> <div> <!-- 这是父组件 --> <div>父组件中的基本数据类型age的值是:{{this.age}}</div> <div>父组件中引用数据类型person的值是:{{this.person.name}} --- {{this.person.address}}</div> <div>父组件中接收子组件的数据fatherInfo的值是:{{this.fatherInfo}}</div> ---------------------------------------------------------------------------------------------------- <HelloWorld/> </div> </template> <script> import HelloWorld from '@/components/HelloWorld.vue' export default { name: 'Home', data(){ return { age : 18, person: { name: "张三", address: "aaa" }, fatherInfo: "" }; }, provide() { return { age : this.age, person: this.person } }, components: { HelloWorld }, methods: { reciveInfo(info) { this.fatherInfo = info; } } } </script>
<template> <div> <!-- 这是子组件 --> <div>这是子组件,接收父组件的数据传递,age的值是:{{this.age}}</div> <div>这是子组件,接收父组件的数据传递,person的值是:{{person.name}} --- {{person.address}}</div> ---------------------------------------------------------------------------------------------------- <Hello1 /> </div> </template> <script> import Hello1 from '@/components/Hello1.vue' export default { name: 'HelloWorld', data() { return { info: "这是子组件的数据" } }, inject:["age", "person"], components: { Hello1 } } </script>
<template> <!-- 这是父组件 --> <div > <div>这是孙组件,接收组件的数据传递,age的值是:{{this.age}}</div> <div>这是孙组件,接收组件的数据传递,person的值是:{{person.name}} --- {{person.address}}</div> </div> </template> <script> export default { name: 'Hello1', inject: ["age", "person"] } </script> <style> </style>
上面的写法有个问题,如果你只是针对非基本数据类型的某个属性进行修改,修改后所有的地方都会进行改变,但是改变基本数据类型后改变整个对象后,组件本身会改变,但是其他不会随之改变,会造成数据不一致问题。
<template> <div> <!-- 这是父组件 --> <div>父组件中的基本数据类型age的值是:{{this.age}}</div> <div>父组件中引用数据类型person的值是:{{this.person.name}} --- {{this.person.address}}</div> <div>父组件中接收子组件的数据fatherInfo的值是:{{this.fatherInfo}}</div> <div> <button @click="change1">父组件中修改provide传递的值</button> </div> ---------------------------------------------------------------------------------------------------- <HelloWorld/> </div> </template> <script> import HelloWorld from '@/components/HelloWorld.vue' export default { name: 'Home', data(){ return { age : 18, person: { name: "张三", address: "aaa" }, fatherInfo: "" }; }, provide() { return { age : this.age, person: this.person } }, components: { HelloWorld }, methods: { change1() { this.age = 19; this.person.name = "李四"; } } } </script>
<template> <div> <!-- 这是父组件 --> <div>父组件中的基本数据类型age的值是:{{this.age}}</div> <div>父组件中引用数据类型person的值是:{{this.person.name}} --- {{this.person.address}}</div> <div>父组件中接收子组件的数据fatherInfo的值是:{{this.fatherInfo}}</div> <div> <button @click="change1">父组件中修改provide传递的值</button> </div> ---------------------------------------------------------------------------------------------------- <HelloWorld/> </div> </template> <script> import HelloWorld from '@/components/HelloWorld.vue' export default { name: 'Home', data(){ return { age : 18, person: { name: "张三", address: "aaa" }, fatherInfo: "" }; }, provide() { return { age : () => this.age, person: () => this.person } }, components: { HelloWorld }, methods: { change1() { this.age = 19; this.person.name = "李四"; } } } </script>
<template> <div> <!-- 这是子组件 --> <div>这是子组件,接收父组件的数据传递,age的值是:{{this.age()}}</div> <div>这是子组件,接收父组件的数据传递,person的值是:{{person().name}} --- {{person().address}}</div> ---------------------------------------------------------------------------------------------------- <Hello1 /> </div> </template> <script> import Hello1 from '@/components/Hello1.vue' export default { name: 'HelloWorld', data() { return { info: "这是子组件的数据" } }, inject:["age", "person"], components: { Hello1 } } </script>
<template> <!-- 这是孙组件 --> <div > <div>这是孙组件,接收组件的数据传递,age的值是:{{this.age()}}</div> <div>这是孙组件,接收组件的数据传递,person的值是:{{person().name}} --- {{person().address}}</div> </div> </template> <script> export default { name: 'Hello1', inject: ["age", "person"] } </script> <style> </style>
当我们后代组件想修改inject接收的数据时,如果是响应式的书写方式,那么无法提供修改方式(可以通过下面的$listeners去源头进行修改);如果是非响应式的书写,对于非基本数据类型来说,只是改变对象里面的某个属性是可以的,但是这种修改会很难知道是哪个组件对属性进行了修改,比较难以追踪,需要谨慎。其他的不建议修改,会造成数据不一致。
这种方式很直接,将整个实例都获取去直接操作,$children是当前组件的直接子组件实例;$parent是当前组件的父组件实例,可以实现父组件及其后代组件上数据之间的传递。这种方式是获取组件本身的对象,与组件之间引用放置的顺序由很大关联,当改变组件引用的顺序时,需要同时修改获取原组件的下标,使用时需要谨慎考虑。
<template> <div> <!-- 这是父组件 --> <div>父组件中的基本数据类型age的值是:{{this.age}}</div> <div>父组件中引用数据类型person的值是:{{this.person.name}} --- {{this.person.address}}</div> <div> <button @click="change1">修改后代组件的值</button> </div> ---------------------------------------------------------------------------------------------------- <HelloWorld/> </div> </template> <script> import HelloWorld from '@/components/HelloWorld.vue' export default { name: 'Home', data(){ return { age : 18, person: { name: "张三", address: "aaa" }, fatherInfo: "" }; }, components: { HelloWorld }, methods: { change1() { this.$children[0].info = "修改子组件的数据"; this.$children[0].$children[0].count = "修改孙组件的数据"; } } } </script>
<template> <div> <!-- 这是子组件 --> <div>这是子组件,nfo的值是:{{this.info}}</div> ---------------------------------------------------------------------------------------------------- <Hello1 /> </div> </template> <script> import Hello1 from '@/components/Hello1.vue' export default { name: 'HelloWorld', data() { return { info: "这是子组件的数据" } }, components: { Hello1 }, methods: { change2() { } } } </script>
<template> <!-- 这是孙组件 --> <div > <div>这是孙组件,count的值是:{{this.count}}</div> </div> </template> <script> export default { name: 'Hello1', data() { return { count : "孙组件数据" } } } </script> <style> </style>
<template> <div> <!-- 这是父组件 --> <div>父组件中的基本数据类型age的值是:{{this.age}}</div> <div>父组件中引用数据类型person的值是:{{this.person.name}} --- {{this.person.address}}</div> ---------------------------------------------------------------------------------------------------- <HelloWorld/> </div> </template> <script> import HelloWorld from '@/components/HelloWorld.vue' export default { name: 'Home', data(){ return { age : 18, person: { name: "张三", address: "aaa" }, fatherInfo: "" }; }, components: { HelloWorld }, methods: { change1() { this.$children[0].info = "修改子组件的数据"; this.$children[0].$children[0].count = "修改孙组件的数据"; } } } </script>
<template> <div> <!-- 这是子组件 --> <div>这是子组件,nfo的值是:{{this.info}}</div> ---------------------------------------------------------------------------------------------------- <Hello1 /> </div> </template> <script> import Hello1 from '@/components/Hello1.vue' export default { name: 'HelloWorld', data() { return { info: "这是子组件的数据" } }, components: { Hello1 }, methods: { change2() { } } } </script>
<template> <!-- 这是孙组件 --> <div > <div>这是孙组件,count的值是:{{this.count}}</div> <div> <button @click="change3">修改后先辈组件的值</button> </div> </div> </template> <script> export default { name: 'Hello1', data() { return { count : "孙组件数据" } }, methods: { change3() { debugger; this.$parent.info ="修改直接父辈组件的值"; this.$parent.$parent.age = 20; } }, } </script> <style> </style>
这种方式和方式三一样是获取组件实例本身去操作。在组件上添加一个ref属性,给与这个组件一个标志,通过该标志去获取组件本身的实例,相比较与方式三需要确定组件的引用顺序,该方式没有该苦恼,但是在给ref值的时候注意值不要重复。同时没有办法通过$ref去获取父类对象,这点是相比较于方式三的缺陷。
<template> <div> <!-- 这是父组件 --> <div>父组件中的基本数据类型age的值是:{{this.age}}</div> <div>父组件中引用数据类型person的值是:{{this.person.name}} --- {{this.person.address}}</div> <div> <button @click="change1">修改后代组件的值</button> </div> ---------------------------------------------------------------------------------------------------- <HelloWorld ref="helloWorld"/> </div> </template> <script> import HelloWorld from '@/components/HelloWorld.vue' export default { name: 'Home', data(){ return { age : 18, person: { name: "张三", address: "aaa" }, fatherInfo: "" }; }, components: { HelloWorld }, methods: { change1() { debugger; this.$refs.helloWorld.info = "修改子组件的值"; this.$refs.helloWorld.$refs.hello1.count = "修改孙组件的值"; } } } </script>
<template> <div> <!-- 这是子组件 --> <div>这是子组件,nfo的值是:{{this.info}}</div> ---------------------------------------------------------------------------------------------------- <Hello1 ref ="hello1"/> </div> </template> <script> import Hello1 from '@/components/Hello1.vue' export default { name: 'HelloWorld', data() { return { info: "这是子组件的数据" } }, components: { Hello1 }, methods: { change2() { } } } </script>
<template> <!-- 这是孙组件 --> <div > <div>这是孙组件,count的值是:{{this.count}}</div> </div> </template> <script> export default { name: 'Hello1', data() { return { count : "孙组件数据" } }, methods: { }, } </script> <style> </style>
$attrs:包含了父作用域中没有被 prop 接收的所有属性(不包含class 和 style 属性)。这是其在使用是上的限制。在子组件中要通过这个去接收的条件。如果还要往下进行传递,需要v-bind来进行向下传递。自能是子类获取父类,同时只有定义出可以修改数据,中间传递组件无法修改值本身(可以通过下面的$listeners去源头进行修改)。
<template> <div> <!-- 这是父组件 --> <div>父组件中的基本数据类型age的值是:{{this.age}}</div> <div>父组件中引用数据类型person的值是:{{this.person.name}} --- {{this.person.address}}</div> <div> <button @click="change1">修改后代组件的值</button> </div> ---------------------------------------------------------------------------------------------------- <HelloWorld ref="helloWorld" :age="this.age" :person="this.person" /> </div> </template> <script> import HelloWorld from '@/components/HelloWorld.vue' export default { name: 'Home', data(){ return { age : 18, person: { name: "张三", address: "aaa" }, fatherInfo: "" }; }, components: { HelloWorld }, methods: { change1() { this.age = 19; this.person.name = "李四"; } } } </script>
<template> <div> <!-- 这是子组件 --> <div>子组件中的基本数据类型age的值是:{{this.$attrs.age}}</div> <div>子组件中引用数据类型person的值是:{{this.$attrs.person.name}} --- {{this.$attrs.person.address}}</div> <div> <button @click="change2">修改后代组件的值</button> </div> ---------------------------------------------------------------------------------------------------- <Hello1 ref ="hello1" v-bind="this.$attrs"/> </div> </template> <script> import Hello1 from '@/components/Hello1.vue' export default { name: 'HelloWorld', data() { return { info: "这是子组件的数据" } }, components: { Hello1 }, methods: { change2() { this.$attrs.age = 19; } } } </script>
<template> <!-- 这是孙组件 --> <div > <div>孙组件中的基本数据类型age的值是:{{this.$attrs.age}}</div> <div>孙组件中引用数据类型person的值是:{{this.$attrs.person.name}} --- {{this.$attrs.person.address}}</div> </div> </template> <script> export default { name: 'Hello1', data() { return { count : "孙组件数据" } }, methods: { }, } </script> <style> </style>
$listnters:包含所有父组件中的 v-on 事件监听器 (不包含 .native 修饰器的)。其作用与$emit的功能相似。但是其可以不限制与父子组件之间来使用。
注意与.native进行区分,native是用于将原生事件绑定到特定组件中使用的
<template> <div> <!-- 这是父组件 --> <div>父组件中的基本数据类型age的值是:{{this.age}}</div> <div>父组件中引用数据类型person的值是:{{this.person.name}} --- {{this.person.address}}</div> <div> <button @click="change1">修改后代组件的值</button> </div> <div> <Hello2 @click.native="handleTest3" /> </div> ---------------------------------------------------------------------------------------------------- <HelloWorld ref="helloWorld" :age="this.age" :person="this.person" v-on="{handleTest1, handleTest2}" /> </div> </template> <script> import HelloWorld from '@/components/HelloWorld.vue' import Hello2 from '@/components/Hello2.vue' export default { name: 'Home', data(){ return { age : 18, person: { name: "张三", address: "aaa" }, fatherInfo: "" }; }, components: { HelloWorld, Hello2 }, methods: { handleTest1(info) { console.log("有参数的传递处理{}", info); }, handleTest2() { console.log("无参数的参数处理"); }, handleTest3() { console.log("原生的处理方式"); } } } </script>
<template> <div> <!-- 这是子组件 --> <div>子组件中的基本数据类型age的值是:{{this.$attrs.age}}</div> <div>子组件中引用数据类型person的值是:{{this.$attrs.person.name}} --- {{this.$attrs.person.address}}</div> <div> <button @click="handle1">子类放在一个按钮来调用父类的handleTest1</button> </div> <div> <button @click="handle3">原生的处理方式</button> </div> ---------------------------------------------------------------------------------------------------- <Hello1 v-bind="this.$attrs" v-on="$listeners"/> </div> </template> <script> import Hello1 from '@/components/Hello1.vue' export default { name: 'HelloWorld', data() { return { info: "这是子组件的数据" } }, components: { Hello1 }, methods: { handle1() { // 两种写法 this.$listeners.handleTest1(this.info); this.$emit('handleTest1', this.info); }, handle3() { // this.handleTest3(); } } } </script>
<template> <!-- 这是孙组件 --> <div > <div>孙组件中的基本数据类型age的值是:{{this.$attrs.age}}</div> <div>孙组件中引用数据类型person的值是:{{this.$attrs.person.name}} --- {{this.$attrs.person.address}}</div> <button @click="handle2">子类放在一个按钮来调用父类的handleTest2</button> </div> </template> <script> export default { name: 'Hello1', data() { return { count : "孙组件数据" } }, methods: { handle2() { // 两种写法 this.$listeners.handleTest2(); this.$emit("handleTest2"); } }, } </script> <style> </style>
<!-- --> <template> <div > <button>用于测试native的使用</button> </div> </template> <script> export default { name: 'Hello2', components: {}, data() { return { } }, computed: {}, watch: {}, methods: { }, created() { }, mounted() { }, } </script> <style> </style>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。