怎么实现一个v-model
v-model本质是一个语法糖。
<input type="text" v-model="name">
相当于
<input type="text" v-bind:value="name" @input="name =$event.target.value">
所以,如果想实现一个v-model,那就在自定义组件的时候设置一个名为value的prop,并且在数据发生变化时$emit一个带新值的input事件,就可以在该自定义组件中使用v-model进行双向绑定。
<template>
<input type="text" v-bind:value="value" @input="handleInput" :placeholder="placehodler" />
</template>
<script>
export default {
name: 'kInput',
props: {
value: ['String', 'Number'],
placeholder: String
},
methods: {
handleInput ($event) {
// 通过input标签的原生事件input将值emit出去,以实现数据的双向绑定
this.$emit('input', $event.target.value)
}
}
}
</script>
<style scoped type="less">
</style>
此外,vue官网有另一种实现v-model的方法。针对像复选框,单选框这种类型的输入控件,他们会将value attribute用于不同的目的。为了兼容部分表单元素的特殊用户,vue对 v-model 的实现做了扩充,同时也更加灵活。
Vue.component('base-checkbox', {
model: {
prop: 'checked',
event: 'change'
},
props: {
checked: Boolean
},
template: `
<input
type="checkbox"
v-bind:checked="checked"
v-on:change="$emit('change', $event.target.checked)"
>
`
}) // ———— 源自 vue 官网
v-for为什么要key值,且key值不能为index
因为vue和react都是用的虚拟dom,虚拟dom都用的diff算法,这个算法为了高效,需要有key来给每个节点做一个唯一标识,这样性能就能大大提高。
- 使用index作为key其实就等于不加 key,因为 key 是当前的索引值,sameVNode 函数的结果为 true ,所以跟不加 key 的更新流程是一样的。
- 可能会出错 index 作为 key 只适用于不依赖子组件状态或临时 DOM 状态(例如表单输入值)的列表渲染输出。