Vue.js 教程

Vue.js Prop 单向数据流

将介绍 Vue.js 中,父组件和子组件之间 Prop 之间数据流向关系,以及一些注意事项。涉及知识点:

  • 父组件和子组件之间 Prop 的关系

  • 什么是单向下行绑定

  • 子组件试图修改 Prop 的情况

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

每次父级组件发生变更时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。

子组件修改 Prop

前面介绍子组件修改 Prop 不会影响父组件的 Prop,因此不建议这么做。但是,也有例外,下面列举了两种常见的试图变更一个 prop 的情形:

(1)这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。在这种情况下,最好定义一个本地的 data 属性并将这个 prop 用作其初始值,例如:

props: ['initialCounter'],
data: function () {
   return {
       counter: this.initialCounter
   }
}

(2)这个 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个计算属性,例如:

props: ['size'],
computed: {
   normalizedSize: function () {
       return this.size.trim().toLowerCase()
   }
}

注意:在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变变更这个对象或数组本身将会影响到父组件的状态。

完整示例

该示例定义了一个子组件,且在根组件和子组件均定义了按钮,该按钮用来对 count 加一操作。例如:

<html>
<head>
   <meta charset="UTF-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Vue</title>
   <!-- 使用 CDN 引入 Vue 库 -->
   <!-- <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> -->
   <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.7.9/vue.js"></script>
</head>
<body>

   <div id="app">
       <h1>
           count: {{ count }}
           <button v-on:click="incrParent">count++</button>
       </h1>
       <my-component my-title="Hello Vue.js"
           v-bind:my-count="count"></my-component>
   </div>

   <script type="text/javascript">
       Vue.component("my-component", {
           props: {
               myTitle: String,
               myCount: Number
           },
           template: `
               <div style="background:red;">
                   <h2>{{myTitle}}</h2>
                   <p>Count: {{myCount}}</p>
                   <p>
                       <button v-on:click="incr">myCount++</button>
                   </p>
               </div>
           `,
           methods: {
               incr: function(){
                   this.myCount += 1;
               }
           }
       });

       var app = new Vue({
           el: "#app",
           data: {
               count: 1024
           },
           methods: {
               incrParent: function(){
                   this.count += 1;
               }
           }
       });
   </script>

</body>
</html>

运行效果图:

上图中,当我们点击组件外的按钮增加 count 会影响子组件,而点击子组件内部的按钮增加 count,并不会影响父组件。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号