一、 v-model简化父子组件通信
v-model是什么?
v-model 是Vue框架的一种内置的API指令,本质是一种语法糖写法。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
v-model实现表单的双向绑定
<template>
<div>
<input type="text"
v-model="msg">
<p>{{msg}}</p>
</div>
</template>
<script>
export default {
data () {
return {
msg: ''
}
}
}
</script>
原理:v-model是v-bind和v-on:input的结合,即监听了表单的input事件,然后修改value属性对应的值
完整代码可写为:
<template>
<div>
<input type="text"
:value="msg"
@input="bind">
<p>{{msg}}</p>
</div>
</template>
<script>
export default {
data () {
return {
msg: ''
}
},
methods: {
bind () {
this.msg = event.target.value
}
}
}
</script>
简化父子通信代码
普通写法
父组件(App.vue)
<template>
<div class="wrapper">
<!-- 自定义属性可以随意指定名字,自定义事件名称也可以随意指定 -->
<select-comp :value='selectId' @input="selectId=$event"></select-comp>
{{ selectId }}
</div>
</template>
<script>
import SelectComp from './components/SelectComp.vue'
export default {
name: 'App',
data() {
return{
selectId:'1001',
}
},
components: {
SelectComp,
},
methods: {},
}
</script>
<style lang="less" scoped></style>
子组件(SelectComp.vue)
<template>
<!--
selectId这个数据从父亲传递过来的,不能直接修改 所以不能使用v-model绑定数据
要想改变从父亲传递过来的数据 采用子传父
-->
<select :value="value" @change='changeOption'>
<option value="1001">北京</option>
<option value="1002">上海</option>
<option value="1003">广州</option>
<option value="1004">深圳</option>
</select>
</template>
<script>
export default {
data() {
return {};
},
props: {
value:{
type: String,
required: true
}
},
methods: {
changeOption(e){
this.$emit('input',e.target.value)
}
}
};
</script>
<style>
</style>
v-model简化写法
父组件(App.vue)
<template>
<div class="wrapper">
<!-- 自定义属性可以随意指定名字,自定义事件名称也可以随意指定 -->
<select-comp v-model="selectId"></select-comp>
{{ selectId }}
</div>
</template>
<script>
import SelectComp from './components/SelectComp.vue'
export default {
name: 'App',
data() {
return{
selectId:'1001',
}
},
components: {
SelectComp,
},
methods: {},
}
</script>
<style lang="less" scoped></style>
这里::value='selectId' @input="selectId=$event"
换成了 v-model="selectId"
完整代码
<select-comp v-model="selectId"></select-comp>
子组件(SelectComp.vue)
<template>
<select :value="value" @change='changeOption'>
<option value="1001">北京</option>
<option value="1002">上海</option>
<option value="1003">广州</option>
<option value="1004">深圳</option>
</select>
</template>
<script>
export default {
data() {
return {};
},
props: {
value:{
type: String,
required: true
}
},
methods: {
changeOption(e){
this.$emit('input',e.target.value)
}
}
};
</script>
<style>
</style>
这里:传递参数固定为value
$emit()中的事件名成固定为input
<select :value="value" @change="handleChange">...</select>
props: {
value: String
},
methods: {
handleChange (e) {
this.$emit('input', e.target.value)
}
}
v-model简化写法缺点: value属性 语义化不友好
二、 .sync修饰符
.sync修饰符作用:
可以实现 子组件 与 父组件数据 的 双向绑定,简化代码
简单理解:子组件可以修改父组件传过来的props值
当我们从父组件向子组件传入一个变量,子组件需要根据自身的变化引起变量值的改变时
可应用至弹框的开启、关闭
语法
父组件
<SelectComp :selectId.sync='selectId'/>
<!-- 等价于 -->
<SelectComp :selectId='selectId' @update:selectId='selectId = $event '/>
子组件
props: {
visible: Boolean
},
this.$emit('update:visible', false)
示例
父组件(App.vue)
<template>
<div class="wrapper">
<SelectComp :selectId.sync='selectId'/>
</div>
</template>
<script>
import SelectComp from './components/SelectComp.vue'
export default {
name: 'App',
data() {
return{
selectId:'1001'
}
},
components: {
SelectComp
},
methods: {},
}
</script>
SelectComp.vue
<template>
<select :value="selectId" @change='changeOption'>
<option value="1001">北京</option>
<option value="1002">上海</option>
<option value="1003">广州</option>
<option value="1004">深圳</option>
</select>
</template>
<script>
export default {
data() {
return {};
},
props: {
selectId:{
type: String,
required: true
}
},
methods: {
changeOption(e){
this.$emit('update:selectId',e.target.value)
}
}
};
</script>
使用v-model实现了父子组件的双向绑定(父亲的数据传递给儿子,儿子可以修改父亲数据)
方法一:
方法二:
方法二与方法一区别在于属性语义化