双向绑定 angular vs vue

angular 双向绑定

子组件定义

import {Component,forwardRef, EventEmitter, Input, Output } from '@angular/core';
import {ControlValueAccessor,NG_VALUE_ACCESSOR} from '@angular/forms'

@Component({
	selector:'toggle-button',
	template:`<div class="toggle-button-container" (click)="toggle()" style="background: red"> 
		<a href="javascript:;" class="text-close" *ngIf="!model">关</a> 
		<a href="javascript:;" class="text-open" *ngIf="model">开</a>
	</div>`,
	providers:[{
		provide:NG_VALUE_ACCESSOR,
		useExisting:forwardRef(()=>RioToggleButton),
		multi:true
	}]
})

export class ToggleButton implements ControlValueAccessor{
	@Input() model: any = ''
  	@Output() modelChange: EventEmitter<any> = new EventEmitter<any>()


	toggle():void {
		this.modelChange.emit(!this.model)
		//this.modelChange.emit(123)
	}

	writeValue(value: any): void {
	    this.model = value
	}

	registerOnChange(fn: Function): void {
	    this.controlChange = fn
	}
	  
	registerOnTouched(fn: Function): void {
	    this.controlTouch = fn
	}

	private controlChange: Function = () => {}
	private controlTouch: Function = () => {}
}

父组件

<div>
  {{deliverSwitch}}
  <toggle-button [(model)]="deliverSwitch"></toggle-button>
</div>


import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app';
  deliverSwitch = false;
}

如上

属性传递子组件:在子组件中@Input model属性是由父组件向子组件传递,model 值为父组件deliverSwitch提供,

属性值同步父组件:@Output modelChange 为EventEmitter实例,modelChange(这里需要刻意注意是model+Change),通过this.modelChange.emit(!this.model) 就可以将model 的值同步到父组件


更深入探讨父组件如何监听子组件model 的change (一般来讲只是使用双向绑定就可以完成大部分功能)

//(modelChange) 监听子组件this.modelChange.emit(modelVal)
<toggle-button [(model)]="deliverSwitch" (modelChange)="onModelChange($event)"></toggle-button>

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  deliverSwitch = false;
  onModelChange(modelVal) {
  	console.log(modelVal);//modelVal为子组件emit发过来的值
  }
}

vue 双向绑定 

vue 分为2中形式

形式1:以v-model,子组件以$emit("input", modelValue)同步父组件

父组件

{{count}}
<count-plus v-model="count"></count-plus>

子组件 如下通过this.$emit("input", ++this.count); $emit "input"事件来同步父组件v-model

Vue.component("countPlus", {
    props: {
        value: {
            required: true,
            type: Number 
        }
    },
    data() {
        //props 在子组件中不要直接使用
        return {
            count: this.value
        }
    },
    template: `
       <div @click="addCount">{{count}}</div>
    `,
    methods: {
        addCount() {
            this.$emit("input", ++this.count)
        }
    },
    watch: {
        value: function(newVal, oldVal) {
            this.count = newVal;
        }
    }
})

 

形式2:以属性的形式 :xxx.sync="data"  this.$emit("update:xxx", xxxValue);

父组件:

{{count}}
<count-plus :count.sync="count"></count-plus>

子组件 

Vue.component("countPlus", {
    props: {
       count: {
            required: true,
            type: Number 
        }
    },
    data() {
        //props 在子组件中不要直接使用
        return {
            countCopy: this.count
        }
    },
    template: `
       <div @click="addCount">{{countCopy}}</div>
    `,
    methods: {
        addCount() {
            this.$emit("update:count", ++this.countCopy)
        }
    },
    watch: {
        value: function(newVal, oldVal) {
            this.countCopy = newVal;
        }
    }
})

看到这里基本上就可以了 


 贴一段vue.prototype.$emit 

 

vue.prototype.$emit

其实无论是v-model 还是:prop.sync ,最终执行的都是在父组件中的回调函数,vue 自己给包装了一下,你可以跟一下代码,看看vue 经典的实现。

谢谢您的浏览。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值