一、單向資料流簡介
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>