大家好!我是木瓜太香!一名前端工程师,之前写过一篇《vue 父子组件状态同步的最佳形式》,这篇文章形容了大多数状况下的父子组件同步的最佳形式,也是被开源中国官网举荐了,在这里表示感谢!
这次作为续章是对上一篇文章的非凡状况的补充,并会给出较具体的形容与代码演示,当然如果你单看这篇文章来解决特定问题也是可行的。
对于父子组件状态同步,这篇文章《vue 父子组件状态同步的最佳形式》讲述了大多数状况下的最优解,然而当咱们心愿本人创立的可复用组件和封装的逻辑可能尽量行为统一的时候状况可能会有所不同,举个例子,咱们当初要封装一个输入框组件叫做 MyInput
咱们晓得一般的输入框通常会应用 v-model
来做双向数据绑定,这里如果想让封装的 MyInput
组件在应用上与一般的输入框是统一的,咱们就不免要让自定义组件也反对 v-model
指令,这之中其实实质上也会波及到父子组件的状态同步问题,应用咱们之前讲的形式也能根本实现,只是借助 vue
裸露进去的 api 能够让咱们写法更优雅,接下来咱们应用不同的形式来实现这个组件。
原来的实现形式
自定义的 MyInput
组件
<template>
<div class="myInput">
<!-- 这里只能用 vModel 不能够应用横杠写法 -->
<input type="text" :value="vModel" @input="inputHandle">
</div>
</template>
<script>
export default {
name: "MyInput",
props: {
// 这里也能够写成 'v-model': String 然而倡议依据格调来,如果右边都没有引号就间接驼峰
vModel: String
},
methods: {inputHandle (event) {
// 留神:这里应用 update:v-model 或 update:vModel 都能够
this.$emit("update:v-model", event.target.value)
}
}
}
</script>
应用形式
// 形式一
<my-input :v-model="text" @update:v-model="text = $event"></my-input>
// 形式二
<my-input :v-model.sync="text"></my-input>
能够看到,原来的形式也能实现,然而就应用来说 v-model
被当成属性,肯定要在后面加上 :
才能够用动静属性,后果就变成了 :v-model
,而后咱们为了简化写法去掉事件绑定,咱们最终的成果就是 :v-model.sync
这种写法总会让人感觉怪怪的,接下来咱们就来解决这个问题
vue-api 的形式实现
自定义的 MyInput
组件
<template>
<div class="myInput">
<input type="text" :value="value" @input="inputHandle">
</div>
</template>
<script>
export default {
name: "MyInput",
props: {value: String},
methods: {inputHandle (event) {this.$emit("input", event.target.value)
}
}
}
</script>
应用形式
<my-input v-model="text"></my-input>
看到这里可能一部分同学会一脸懵逼,这就同步了?emm,其实还真同步了,那 value
从哪儿来的,input
事件也没绑定啊,确实这些都被咱们省略掉了,其实这是 vue 的 api 带给咱们的便当,在咱们试图向自定义组件传入 v-model
这个非凡的属性的时候,vue 会帮咱们做两件事,一件是将 v-model
中的值作为 value 的值向下传递,这是咱们在外部要写 props value 的起因,另一件是在以后自定义组件上监听 input 事件,并在触发改事件的时候,将第一个参数赋值给 v-model
中的变量。你能够看到在咱们肉眼不可见的中央 vue 为咱们做了很多理论,然而大家要明确他为什么给你做这么多,认真想想不难看出,这些逻辑是业务场景中反复次数很多的逻辑,vue 不给你做,你本人也要做,还会闲麻烦!当然这还没完结呢!上面更精彩!
为属性 value
和事件 input
命名
有些时候咱们可能心愿 value 就作为一个一般的属性往下传,而咱们的业务场景外面 input 作为事件也不够形象,反正就是 value 和 input 不合乎你的业务中的语义,这个时候我想改名,咋办?接下来看上面的代码:
<template>
<div class="myInput">
<input type="text" :value="text" @input="inputHandle">
</div>
</template>
<script>
export default {
name: "MyInput",
model: {
prop: "text", // 该属性名
event: "update:v-model" // 改事件名
}
props: {text: String // 即使改名了,这里也必不可少},
methods: {inputHandle (event) {this.$emit("update:v-model", event.target.value)
}
}
}
</script>
下面就展现了咱们怎么更名,其实就是扭转了 props 中的承受的字段名,而后新增了 model 选项,这里须要留神的是,不论怎么样 props 中的字段都必不可少。
理论利用:父子组件状态同步
如题目所说,这个 api 仍然能够用作一些非凡状况下的父子组件状态同步,这里举一个理论的列子,假如咱们应用某框架,这个框架提供给咱们模态框组件名叫 Modal 这个组件须要增加 v-model 属性来显示暗藏模态框,通常咱们的模态框会有很多的逻辑,这个时候咱们会思考将其封装成一个自定义的组件,这个时候咱们心愿封装过得组件和原来的模态框组件具备雷同的应用形式都是加 v-model 来显示暗藏,这是时候咱们讲到的性能是不是就特地适合了呢?
我本人建了一个 web 前端的交换裙有趣味的能够退出进来交换哦:245650187(收费)237871108(免费)。
集体微信:GD6570 集体球球:718879459 当然你也能够哔哩哔哩搜寻木瓜太香