一、单向数据流简介
props是单向绑定的,当父组件的属性变化时,将传导给子组件,但是不会反过来。这是为了防止子组件无意修改了父组件的状态(这会让应用的数据流难以理解)。而且不允许子组件直接修改父组件的数据(会报错)。
1、子组件修改数据,不影响到父组件。
解决方式:如果子组件想把它作为局部数据来使用,可以将数据存入另外一个变量中再操作,不影响父组件中的数据。
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>单向数据流</title>
6 <!--引入vue-->
7 <script src="../js/vue.js"></script>
8 </head>
9 <body>
10
11 <div id="hello">
12 <h2>我是父组件:{{name}}</h2>
13 <input type="text" v-model='name'>
14 <hr>
15 <king :nameson='name'></king>
16 </div>
17
18 <template id='kings'>
19 <div>
20 <h3>我是子组件:{{username}}</h3>
21 <button @click='updateData'>修改子组件数据</button>
22 </div>
23 </template>
24
25
26 <script>
27 //vue实例
28 let vm = new Vue({ //vm其实也是一个组件,是根组件Root
29 el:'#hello',
30 data:{
31 name:'tom',
32 age:20
33 },
34 //自定义局部组件
35 components:{
36 'king':{ //子组件
37 template:'#kings',
38 props:['nameson'],
39 data(){ //定义data的目的是存放父组件传递过来的数据,实现修改子组件数据不影响到父组件
40 return {
41 username:this.nameson //方式1 将数据存入另外一个变量中再操作
42 }
43 },
44 methods:{
45 updateData(){
46 this.username='alice';
47 }
48 }
49 },
50
51 }
52 });
53 </script>
54 </body>
55 </html>
2、子组件修改数据,同步更新到父组件。解决方法:
a) 方法1:使用.sync修饰符,并需要$emit()显式地触发一个事件。
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>单向数据流</title>
6 <!--引入vue-->
7 <script src="../js/vue.js"></script>
8 </head>
9 <body>
10
11 <div id="hello">
12 <h2>我是父组件:{{name}}</h2>
13 <input type="text" v-model='name'>
14 <hr>
15 <!-- .sync修饰符 -->
16 <king :nameson.sync='name'></king>
17 </div>
18
19 <template id='kings'>
20 <div>
21 <h3>我是子组件:{{nameson}}</h3>
22 <button @click='updateData'>修改子组件数据</button>
23 </div>
24 </template>
25
26
27 <script>
28 //vue实例
29 let vm = new Vue({ //vm其实也是一个组件,是根组件Root
30 el:'#hello',
31 data:{
32 name:'tom',
33 age:20
34 },
35 //自定义局部组件
36 components:{
37 'king':{ //子组件
38 template:'#kings',
39 props:['nameson'],
40 methods:{
41 updateData(){
42 //this.nameson='alice';
43 this.$emit('update:nameson','alice'); //$emit()触发一个事件
44 }
45 }
46 },
47
48 }
49 });
50 </script>
51 </body>
52 </html>
b) 方法2:可以将父组件中的数据包装成对象,然后在子组件中修改对象的属性(因为对象是引用类型,指向同一个内存空间)。(推荐方式)
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>单向数据流</title>
6 <!--引入vue-->
7 <script src="../js/vue.js"></script>
8 </head>
9 <body>
10
11 <div id="hello">
12 <h2>我是父组件:{{user.name}}</h2>
13 <input type="text" v-model='user.name'>
14 <hr>
15 <king :user='user'></king>
16 </div>
17
18 <template id='kings'>
19 <div>
20 <h3>我是子组件:{{user.name}}</h3>
21 <button @click='updateData'>修改子组件数据</button>
22 </div>
23 </template>
24
25
26 <script>
27 //vue实例
28 let vm = new Vue({ //vm其实也是一个组件,是根组件Root
29 el:'#hello',
30 data:{ //把父组件的数据封装成对象
31 user:{
32 name:'tom',
33 age:20
34 }
35 },
36 //自定义局部组件
37 components:{
38 'king':{ //子组件
39 template:'#kings',
40 props:['user'],
41 methods:{
42 updateData(){
43 this.user.name='monica' //直接修改即可同步到父组件
44 }
45 }
46 },
47
48 }
49 });
50 </script>
51 </body>
52 </html>