Vue中父子组件传值

2019年3月10日13:09:54 发表评论 阅读(1,749)

Vue中父子组件传值

父组件向子组件传递数据可以通过props接收然后去处理,子组件向父组件传递数据可以通过$emit事件触发的形式传递。

父组件向子组件传递数据

  1. <div id="root">
  2.     <counter :count="1"></counter>//加冒号为js表达式(数字),不加则为字符串
  3.     <counter :count="2"></counter>//加冒号为js表达式(数字),不加则为字符串
  4. </div>
  5. <script>
  6.     /**
  7.      * 定义局部组件(count),并在根实例注册组件
  8.      * @type {{props: string[], template: string, methods: {handleClick: counter.methods.handleClick}}}
  9.      */
  10.     var counter = {
  11.         props: ['count'],
  12.         template: '<div @click="handleClick">{{count}}</div>',
  13.         methods: {
  14.             handleClick: function () {
  15.                 this.count ++
  16.             }
  17.         }
  18.     }
  19.     var vm = new Vue({
  20.         el: "#root",
  21.         components: {
  22.             counter: counter
  23.         }
  24.     })
  25. </script>

运行上面的代码,页面显示正常,但是我们打开console控制台会发现报错了,报错内容为:不可以直接修改父组件传递过来的数据!

原因

vue中有一个单向数据流的概念。这是因为父组件可以向子组件传递参数,传递的参数可以进行修改;子组件不可以反过来修改父组件传递过来的参数。

这是为什么呢?

因为一旦子组件接收的count不是一个基础类型的数据,比如是一个object引用形式的数据 ,你在子组件改变了传递过来的内容,有可能接收到的引用型数据还被其他子组件使用,这样的话,你这个子组件改变的数据不仅影响了这个组件还可能对其他组件造成影响。

一定要改变呢?

那也好办,可以这样写代码:

  1. <div id="root">
  2.     <counter :count="1"></counter>//加冒号为js表达式(数字),不加则为字符串
  3.     <counter :count="2"></counter>//加冒号为js表达式(数字),不加则为字符串
  4. </div>
  5. <script>
  6.     /**
  7.      * 定义局部组件(count),并在根实例注册组件
  8.      * @type {{props: string[], template: string, methods: {handleClick: counter.methods.handleClick}}}
  9.      */
  10.     var counter = {
  11.         props: ['count'],
  12.         template: '<div @click="handleClick">{{count}}</div>',
  13.         data: function () {
  14.             return {
  15.                 number: this.count
  16.             }
  17.         },
  18.         methods: {
  19.             handleClick: function () {
  20.                 this.number ++
  21.             }
  22.         }
  23.     }
  24.     var vm = new Vue({
  25.         el: "#root",
  26.         components: {
  27.             counter: counter
  28.         }
  29.     })
  30. </script>

定义一个data,子组件的data必须是一个函数,定义number的值为count,这样相当于把count的数据以number的名字复制了一份,接下来更改number的值就不会报错了。

子组件向父组件传递数据

子组件通过this.$emit('inc',2)触发事件,父组件通过@inc="handleIncrease"监听事件

实例代码:

  1. <div id="root">
  2.     <counter :count="1" @inc="handleIncrease"></counter> //加冒号为js表达式(数字),不加则为字符串
  3.     <counter :count="2" @inc="handleIncrease"></counter> //加冒号为js表达式(数字),不加则为字符串
  4.     <div>{{total}}</div>
  5. </div>
  6. <script>
  7.     /**
  8.      * 定义一个局部组件(counter),根实例注册组件
  9.      * 子组件接收父组件传递的内容(count)
  10.      * @type {{props: string[], template: string, data: counter.data, methods: {handleClick: counter.methods.handleClick}}}
  11.      */
  12.     var counter = {
  13.         props: ['count'],
  14.         template: '<div @click="handleClick">{{number}}</div>',
  15.         data: function () {
  16.             return {
  17.                 number: this.count
  18.             }
  19.         },
  20.         methods: {
  21.             handleClick: function () {
  22.                 this.number += 2;
  23.                 this.$emit('inc',2)
  24.             }
  25.         }
  26.     }
  27.     var vm = new Vue({
  28.         el: "#root",
  29.         data: {
  30.             total: 3
  31.         },
  32.         components: {
  33.             counter: counter
  34.         },
  35.         methods: {
  36.             handleIncrease: function (step) {
  37.                 this.total += step;
  38.             }
  39.         }
  40.     })
  41. </script>

 

weinxin
微信小程序
互联网开发,终身学习者,欢迎您的关注!
舍得

发表评论

不高兴 彩虹 吃瓜 丢翔 乖 滑稽 花心 惊哭 惊讶 挤眼 酷 伤心 帅吗? 礼物 玫瑰 怒 生气 喷 睡觉 太开心 小九九 啊
太阳 吐舌 委屈 笑眼 星星月亮 心碎 咦 阴险 疑问 真棒 偷笑 斜眼笑 震惊 略 哈欠 无奈哭 抠鼻 哼 期待 懒得理你 爱心 蜡烛