Vue_(组件通讯)单项数据流
Vue单项数据流 传送门
单向数据流:父组件值的更新,会影响到子组件,反之则不行
修改子组件的值:
局部数据:在子组件中定义新的数据,将父组件传过来的值赋值给新定义的数据,之后操作这个新数据
如果对数据进行简单的操作,可以使用计算属性
修改子组件的prop,同步到父组件:
使用.sync修饰符
将要操作的数据封装成一个对象再操作
单单项数据流设计原则:
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。
Learn
一、单项数据流
二、单项数据流子组件数据同步到父组件
目录结构
【每个demo下方都存有html源码】
一、单项数据流
实现父组件属性值刷新子组件属性值两种方法,在子组件"child-component" 下定义两个方法获取父组件的文本
data(){ return { childName : this.name } }, computed : { childUpperName(){ return this.name.toString().toUpperCase(); } }
<script type="text/javascript"> new Vue({ data : { msg : 'helloVue' }, components : { "father-component" : { data(){ return { name : 'Gary' } }, props : ['msg'], template : "#father-template", components : { "child-component" : { template : "#child-template", props : ['name'], data(){ return { childName : this.name } }, computed : { childUpperName(){ return this.name.toString().toUpperCase(); } } } } } } }).$mount("#GaryId"); </script>
在子组件中通过v-model绑定childUpperName方法将父组件的文本内容覆盖到子组件当中
this.name.toString().toUpperCase()中toUpperCase() 把字符串转换成大写
<body> <div id="GaryId"> <father-component ></father-component> </div> </body> <template id="father-template"> <div> <h1>father component</h1> myData : <span>{{name}}</span><br /> <input type="text" v-model="name"/><hr /> <child-component :name="name"></child-component> </div> </template> <template id="child-template"> <div> <h2>child component</h2> fatherData : <span>{{childUpperName}}</span><br /> <input type="text" v-model="childUpperName"/><hr /> </div> </template>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Gary</title> </head> <body> <div id="GaryId"> <father-component ></father-component> </div> </body> <template id="father-template"> <div> <h1>father component</h1> myData : <span>{{name}}</span><br /> <input type="text" v-model="name"/><hr /> <child-component :name="name"></child-component> </div> </template> <template id="child-template"> <div> <h2>child component</h2> fatherData : <span>{{childUpperName}}</span><br /> <input type="text" v-model="childUpperName"/><hr /> </div> </template> <script type="text/javascript" src="../js/vue.js" ></script> <script type="text/javascript"> new Vue({ data : { msg : 'helloVue' }, components : { "father-component" : { data(){ return { name : 'Gary' } }, props : ['msg'], template : "#father-template", components : { "child-component" : { template : "#child-template", props : ['name'], data(){ return { childName : this.name } }, computed : { childUpperName(){ return this.name.toString().toUpperCase(); } } } } } } }).$mount("#GaryId"); </script> </html>
二、单项数据流子组件数据同步到父组件 .sync修饰符传送门
在<template id="father-template">中添加.sync修饰符
修改子组件中的数据将会同步到父组件
<child-component :name.sync="name" :user="user"></child-component>
<body> <div id="GaryId"> <father-component ></father-component> </div> </body> <template id="father-template"> <div> <h1>father component</h1> name : <span>{{name}}</span><br /> <input type="text" v-model="name"/><br /> userID : <span>{{user.id}}</span><br /> <input type="text" v-model="user.id"/><br /> <hr /> <child-component :name.sync="name" :user="user"></child-component> </div> </template> <template id="child-template"> <div> <h2>child component</h2> fatherData : <span>{{childName}}</span><br /> <input type="text" v-model="childName"/><br /> userID : <span>{{user.id}}</span><br /> <input type="text" v-model="user.id"/><br /> <hr /> </div> </template>
在子组件的props中进行属性注册props : ['name', 'user']
new Vue({ data : { msg : 'helloVue' }, components : { "father-component" : { data(){ return { name : 'Gary', user : { id : 1 } } }, props : ['msg'], template : "#father-template", components : { "child-component" : { template : "#child-template", props : ['name', 'user'], data(){ return { childName : this.name } }, computed : { childUpperName(){ return this.name.toString().toUpperCase(); } }, updated(){ this.$emit('update:name', this.childName); } } } } } }).$mount("#GaryId");
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Gary</title> </head> <body> <div id="GaryId"> <father-component ></father-component> </div> </body> <template id="father-template"> <div> <h1>father component</h1> name : <span>{{name}}</span><br /> <input type="text" v-model="name"/><br /> userID : <span>{{user.id}}</span><br /> <input type="text" v-model="user.id"/><br /> <hr /> <child-component :name.sync="name" :user="user"></child-component> </div> </template> <template id="child-template"> <div> <h2>child component</h2> fatherData : <span>{{childName}}</span><br /> <input type="text" v-model="childName"/><br /> userID : <span>{{user.id}}</span><br /> <input type="text" v-model="user.id"/><br /> <hr /> </div> </template> <script type="text/javascript" src="../js/vue.js" ></script> <script type="text/javascript"> new Vue({ data : { msg : 'helloVue' }, components : { "father-component" : { data(){ return { name : 'Gary', user : { id : 1 } } }, props : ['msg'], template : "#father-template", components : { "child-component" : { template : "#child-template", props : ['name', 'user'], data(){ return { childName : this.name } }, computed : { childUpperName(){ return this.name.toString().toUpperCase(); } }, updated(){ this.$emit('update:name', this.childName); } } } } } }).$mount("#GaryId"); </script> </html>