(一)Vue单向数据流(One-Way Data Flow)

单向数据流

一.什么是单向数据流

Vue官方文档解释为:

所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。

简单来说就是通过prop传递数据时,数据从父组件流向子组件,在子组件中不能修改数据的值,请看一个例子说明:

</html>
<!DOCTYPE html>
<html>

<head>
    <title>one-way data flow</title>
    <meta charset="utf-8">
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div id="app1">
        <custom-component :count="1"></custom-component>
    </div>
    <script type="text/javascript">
    Vue.component('custom-component', {
        props: ['count'],
        template: '<div><input type="button" value="改变count的值" @click="changeCount" />{{count}}</div>',
        methods: {
            changeCount() {
                this.count++;
            }
        }
    });
    var testApp = new Vue({
        el: '#app1'
    });
    </script>
</body>

</html>

打开浏览器,显示如下:
在这里插入图片描述
按F12调出开发者工具,点击按钮,控制台会显示vue警告,提示错误:

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop’s value. Prop being mutated: “count”

在这里插入图片描述
在这里插入图片描述
虽然渲染结果正确,但是vue给我们弹出了警告,所以我们应该遵循单向数据流,不应该在子组件中更改prop的值。

二.如何在子组件中更改prop的值

既然无法在子组件中直接更改父组件中传递的prop值,那么有没有间接的方法呢?答案是Yes。Vue官方文档提供了两种方法:data()属性和computed属性。

1.通过data属性:

</html>
<!DOCTYPE html>
<html>

<head>
    <title>one-way data flow</title>
    <meta charset="utf-8">
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div id="app1">
        <custom-component :count="1"></custom-component>
    </div>
    <script type="text/javascript">
    Vue.component('custom-component', {
        props: ['count'],
        template: '<div><input type="button" value="改变count的值" @click="changeCount" />{{counter}}</div>',
        //添加data,注意data在component中必须是一个函数
        data(){
            return {
                counter:this.count
            }
        },
        methods: {
            changeCount() {
                this.counter++;	//改变的是data中返回的counter,而不是改变props中的count值
            }
        }
    });
    var testApp = new Vue({
        el: '#app1'
    });
    </script>
</body>

</html>

2.通过计算属性:如果需要显示的值,是以prop值为基础,然后进行改变,可以通过computed属性改变后,然后渲染。

</html>
<!DOCTYPE html>
<html>

<head>
    <title>one-way data flow</title>
    <meta charset="utf-8">
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>

<body>
    <div id="app1">
        <custom-component name="唐维娟"></custom-component>
    </div>
    <script type="text/javascript">
    Vue.component('custom-component', {
        props: ['name'],
        template: '<span>{{show}}</span>', //这里使用计算属性show,而不是name
        computed: {
            show() {
                return `${this.name}今天又在睡懒觉。`;
            }
        },
    });
    var testApp = new Vue({
        el: '#app1'
    });
    </script>
</body>

</html>

渲染结果:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值