vue-组件(单向数据流)
一、单向数据流简介
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>