Vue项目中经常使用到组件之间的数值传递,实现的方法很多,但是原理上基本大同小异。
实现思路:
父 向 子 组件传值:使用 props 属性。( props 是property[属性] 的复数简写 )
子 向 父 组件传值:使用自定义事件。
一、父子组件单向传值
1.1、父向子传值
父向子组件传值,子组件接收到数据之后,保存到自己的变量中。
- //父组件写法
- <cld :numP="num" ></cld>
- //子组件定义以及数据
- components:{
- cld:{
- template:'#child',
- props:{
- numP:Number
- },
- }
- }
- //子组件内容
- <template id="child">
- <div>
- {{ numP }}
- </div>
- </template>
props 用于接收父组件传过来的值,props 的写法有很多种,具体如:
- //方式1 : 直接接收数据
- props: [ 'numP' ]
- //方式2: 加类型限制
- props: [
- numP: Number
- ]
- //方式3:添加默认值
- props: [
- numP: {
- type:Number,
- default:0
- }
- ]
- //方式4:是否必须值限制
- props: [
- numP: {
- type:Number,
- default:0,
- require:true //添加必须值,不传此值会报错
- }
- ]
- //方式5:采用对象形式
- props: {
- numP: {
- type:Number,
- default:0,
- }
- }
1.2、子向父传值
子向父组件传值,主要通过自定义事件进行传值,具体实例如下:
- // 父组件内容
- <div>
- 子组件获取到的数据{{getNum}}
- <cld :numb="num" @accept="getNumC"></cld>
- </div>
- //父组件方法
- methods:{
- getNumC(data){
- this.getNum = data //接收子组件传的数据
- }
- },
- //子组件定义
- components:{
- cld:{
- template:'#child',
- data(){
- return{
- numC:1314 //子组件数据定义
- }
- },
- mounted(){
- this.$emit( 'accept' , this.numC ) // 触发自定义事件
- }
- }
- },
二、父子组件数据双向绑定
Vue 的数据都是单向流动的,而且 vue 中从来就没有任何的双向绑定,v-model 实现的双向绑定只是语法糖而已。
方式1:利用 watch 实现父子组件的数据双向绑定,具体实例如下:
- <div id="app">
- 数据<br>{{num}}
- <input type="text" v-model="num"><br>
- <cld :numb="num" @accept="getNumC"></cld>
- </div>
- //子组件内容
- <template id="child">
- <div>
- 数据<br>{{childNum}}
- <input type="text" v-model="childNum" />
- </div>
- </template>
- <!-- 父子组件通信 -->
- const app = new Vue({
- el:'#app',
- data:{
- num:'520',
- },
- methods:{
- getNumC(data){
- this.num = data
- }
- },
- components:{
- cld:{
- template:'#child',
- props:{
- numb:String
- },
- data(){
- return{
- childNum:0,
- }
- },
- watch:{
- numb:function(){
- this.childNum = this.numb
- },
- childNum:function(){
- this.$emit('accept',this.childNum)
- }
- },
- mounted(){
- this.childNum = this.numb
- }
- }
- }
- })
方式2:.sync 修饰符实现双向绑定
在vue 1.x 中的 .sync 修饰符所提供的功能。当一个子组件改变了一个带 .sync 的 prop 的值时,这个变化也会同步到父组件中所绑定的值。这很方便,但也会导致问题,因为它破坏了单向数据流。(数据自上而下流,事件自下而上走)
- <cld :numb.sync="num" ></cld>
- //会扩展为:
- <cld :numb="bar" @update:numb=”val => bar = val”/>
当组件需要更新 numb 的值时,需要触发更新事件:
- this.$emit("update:numb", newValue );
使用具体实例如下:
- // 父组件
- <Father :foo.sync="foo"></Father>
- //子组件
- props: ['foo'],
- data() {
- return {
- newFoo: this.foo;
- }
- },
- methods:{
- add:function(){
- this.newMsg=10;
- this.$emit('update:foo',this.newFoo);
- }
- }