v-model
v-model就实现了双向数据绑定,实际上它就是通过Vue提供的事件机制。即在子组件通过$emit()触发一个事件,在父组件使用v-on来监听对应的事件并修改相应的数据。
input的v-model就是通过<input :value="value" @input="input"/>
封装一个input组件,v-model实现
两个注意点:
假设不是使用的value属性和input事件,而是使用string属性和strChange事件。通过mode属性设置
爷父孙组件,父组件通过computed实现
js
// 父组件
<my-input v-model="value"></my-input>
// my-input子组件组件
<template>
<!-- 2. 监听 input 事件的出发 -->
<div class="input" contenteditable @input="input"></div>
</template>
<script>
export default {
// 1. 接受父级传递的值
props: {
value: {
type: String,
default: ''
}
},
methods: {
// 3. 编写 input 事件触发执行的事件处理函数
input (event) {
// 4. $emit input 事件,并将 event.target.innerText 作为参数
this.$emit('input', event.target.innerText)
}
}
}
</script>
原生实现数据双向绑定
html
<body>
<span id="text"></span>
<input id="value" />
</body>
<script>
window.onload = function() {
let input = document.getElementById('value')
let text = document.getElementById('text')
let data = { value: '' }
input.value = data.value
text.innerHTML = data.value
// 数据劫持
Object.defineProperty(data, 'value', {
set: function (val) {
input.value = val
text.innerHTML = val
},
get: function () {
return input.value
}
})
input.addEventListener('keyup', function (){
data.value = input.value
})
}
</script>