Vue的父子组件传值比较有意思,父组件通过属性绑定,把自身的值和子组件的一个属性绑定起来,子组件通过props属性接收,该属性类型为数组,是Vue对象中比较少有的类型,data、computer、methods等方法都是对象的形式,props则是数组的形式。父组件通过v-on来监听子组件发出的事件来接收子组件的调用。在这里我是理解成子组件发送信号来通知上层,毕竟调用的是this.$emit来做到的。
我们假设子组件名为,我们通过v-bind来绑定一个值给它。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <template> <div id="#app"> // 通过v-bind绑定父子组件的属性 <hello v-bind:messageFromParent="message"/> </div> <template>
<script lang="ts"> import Vue from 'vue'; import Hello from './Hello.vue'; export default Vue.extend({ data: { message: "this message from parent" }, components: { "hello": Hello } }); </script>
|
子组件hello.vue通过props属性接收,内容是这样的:
1 2 3 4 5 6 7 8 9 10 11 12 13
| <template> <div> {{ messageFromParent }} </div> </template>
<script lang="ts"> import Vue from 'vue'; export default Vue.extend({ props: [ "messageFromParent" ] }); </script>
|
这里有个需要注意的地方,父组件给子组件的数据是单向的,虽然子组件也可以修改父组件传入的数据,但是会产生一个错误,并打印在终端里。
那么我们怎么才能修改父组件的值呢?答案是this.$emit
。
我们给子组件绑定上v-on,来监听子组件的事件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <template> <div id="#app"> // 通过v-bind绑定父子组件的属性,通过v-on监听子组件的属性变化 <hello v-bind:messageFromParent="message" v-on:changeParentData="changeData"/> </div> <template>
<script lang="ts"> import Vue from 'vue'; import Hello from './Hello.vue'; export default Vue.extend({ data: { message: "this message from parent" }, components: { "hello": Hello }, methods: { changeData: function(data: string) { message = data; } } }); </script>
|
子组件只需要发送出修改即可:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <template> <div> <button v-on:click="change">修改父组件数据</button> {{ messageFromParent }} </div> </template>
<script lang="ts"> import Vue from 'vue'; export default Vue.extend({ props: [ "messageFromParent" ], methods: { change: function() { this.$emit("changeParentData", "change data by child"); } } }); </script>
|
以上就是Vue父子组件传值的一种常用方法,适用于相邻组件的,如果隔代了,那么这种方式就不好用了,中间路过的组件都需要转发这个事件,处理这种情况就需要使用provide/ inject
了,不过那就是另一篇文章啦。