父组件向子组件传递数据可以通过props
接收然后去处理,子组件向父组件传递数据可以通过$emit
事件触发的形式传递。
父组件向子组件传递数据
- <div id="root">
- <counter :count="1"></counter>//加冒号为js表达式(数字),不加则为字符串
- <counter :count="2"></counter>//加冒号为js表达式(数字),不加则为字符串
- </div>
- <script>
- /**
- * 定义局部组件(count),并在根实例注册组件
- * @type {{props: string[], template: string, methods: {handleClick: counter.methods.handleClick}}}
- */
- var counter = {
- props: ['count'],
- template: '<div @click="handleClick">{{count}}</div>',
- methods: {
- handleClick: function () {
- this.count ++
- }
- }
- }
- var vm = new Vue({
- el: "#root",
- components: {
- counter: counter
- }
- })
- </script>
运行上面的代码,页面显示正常,但是我们打开console控制台会发现报错了,报错内容为:不可以直接修改父组件传递过来的数据!
原因
vue中有一个单向数据流
的概念。这是因为父组件可以向子组件传递参数,传递的参数可以进行修改;子组件不可以反过来修改父组件传递过来的参数。
这是为什么呢?
因为一旦子组件接收的count不是一个基础类型的数据,比如是一个object引用形式的数据 ,你在子组件改变了传递过来的内容,有可能接收到的引用型数据还被其他子组件使用,这样的话,你这个子组件改变的数据不仅影响了这个组件还可能对其他组件造成影响。
一定要改变呢?
那也好办,可以这样写代码:
- <div id="root">
- <counter :count="1"></counter>//加冒号为js表达式(数字),不加则为字符串
- <counter :count="2"></counter>//加冒号为js表达式(数字),不加则为字符串
- </div>
- <script>
- /**
- * 定义局部组件(count),并在根实例注册组件
- * @type {{props: string[], template: string, methods: {handleClick: counter.methods.handleClick}}}
- */
- var counter = {
- props: ['count'],
- template: '<div @click="handleClick">{{count}}</div>',
- data: function () {
- return {
- number: this.count
- }
- },
- methods: {
- handleClick: function () {
- this.number ++
- }
- }
- }
- var vm = new Vue({
- el: "#root",
- components: {
- counter: counter
- }
- })
- </script>
定义一个data,子组件的data必须是一个函数,定义number的值为count,这样相当于把count的数据以number的名字复制了一份,接下来更改number的值就不会报错了。
子组件向父组件传递数据
子组件通过this.$emit('inc',2)
触发事件,父组件通过@inc="handleIncrease"
监听事件
实例代码:
- <div id="root">
- <counter :count="1" @inc="handleIncrease"></counter> //加冒号为js表达式(数字),不加则为字符串
- <counter :count="2" @inc="handleIncrease"></counter> //加冒号为js表达式(数字),不加则为字符串
- <div>{{total}}</div>
- </div>
- <script>
- /**
- * 定义一个局部组件(counter),根实例注册组件
- * 子组件接收父组件传递的内容(count)
- * @type {{props: string[], template: string, data: counter.data, methods: {handleClick: counter.methods.handleClick}}}
- */
- var counter = {
- props: ['count'],
- template: '<div @click="handleClick">{{number}}</div>',
- data: function () {
- return {
- number: this.count
- }
- },
- methods: {
- handleClick: function () {
- this.number += 2;
- this.$emit('inc',2)
- }
- }
- }
- var vm = new Vue({
- el: "#root",
- data: {
- total: 3
- },
- components: {
- counter: counter
- },
- methods: {
- handleIncrease: function (step) {
- this.total += step;
- }
- }
- })
- </script>
微信小程序
互联网开发,终身学习者,欢迎您的关注!