v-model本质上是一个语法糖,
<input type="text" v-model="msg">
<p>输出msg的当前值:{{msg}}p>
<input type="text" :value="msg" @input="msg=$event.target.value">
其中,
1.数据变化,令视图跟着变化==>:value
2.视图变化,令数据跟着变化==>@input
$event.target.value表示输入框用户输入的值,
msg表示model层的数据
<select name="" id="" v-model="cityId">
<option value="101">北京option>
<option value="102">上海option>
<option value="103">广州option>
<option value="104">深圳option>
select>
<select name="" id="" :value="cityId" @change="cityId=$event.target.value">
<option value="101">北京option>
<option value="102">上海option>
<option value="103">广州option>
<option value="104">深圳option>
select>
父组件:(使用)
//
<BaseSelect :cityId="selectId" @changeId="selectId=$event"></BaseSelect>
//父组件提供数据
data(){return{selectId:102}}
子组件:(封装)
注意这里不能用v-model,要把它拆解成value属性和onchange事件
<select :value="cityId" @change="handleChange">
<option value="101">北京</option>
...
</select>
props:{
cityId:String
},
methods:{
handleChange(e){
//console.log(e.target.value);//是否拿到104
//this.$emit("事件名".e.target.value);
this.$emit("changeId".e.target.value);
}
}
}
父组件:App.vue
//html
<!-- $event是获得当前事件的形参 -->
<base-v-model :cityId="selectId" @changeId="selectId=$event"></base-v-model>
//js
import BaseVModel from "./components/BaseVModel.vue"
export default {
components: {
BaseVModel,
},
data(){
selectId:'102',//此处改成数数字然后子组件的props限制改成Number也可以
}
}
子组件:BaseVModel.vue
//html
<select name="" id="" :value="cityId" @change="handleChange">
<option value="101">北京</option>
<option value="102">上海</option>
<option value="103">广州</option>
<option value="104">深圳</option>
</select>
//js
props:{
cityId:String//父传子:接收父组件传过来的数据
},
methods: {
handleChange(e){
console.log(e.target.value);//获取用户改变城市后对应的id:102,103...
this.$emit("changeId",e.target.value);//子传父:把监听到的用户输入传给父组件
},
}
使用v-model进行对上例代码简化,思路是把绑定的事件和属性凑成value+input的形式
:value=cityId
替换为:value=value
this.$emit("changeId",e.target.value)
替换成this.$emit("input",e.target.value)
:cityId:selectId
替换成:value:selectId
@changeId="selectId=$event"
替换成@input="selectId=$event
":value
和@input
后,可以使用v-model替换它们,即v-model="selectId"
父组件:App.vue
//html
<!-- <base-v-model :value="selectId" @input="selectId=$event"></base-v-model> -->
<!-- 凑齐了:value和@input之后,就可以把它们改成v-model,从而达到了简化代码的目的 -->
<base-v-model v-model="selectId"></base-v-model>
//js
data:
selectId:'102'
子组件:BaseVModel.vue
//html
<select name="" id="" :value="value" @change="handleChange">
<option value="101">北京</option>
<option value="102">上海</option>
<option value="103">广州</option>
<option value="104">深圳</option>
</select>
//js
props:{
// cityId:String
value:String//改成用value接收,input的拓展示例也用这个value属性
},
methods: {
handleChange(e){
console.log(e.target.value);
// this.$emit("changeId",e.target.value);
this.$emit("input",e.target.value);
},
父组件:App.vue
//html
<!-- 拓展示例 -->
<base-v-model v-model="inputMsg"></base-v-model>
<p>input输入了什么:{{inputMsg}}</p>
//js
data(){
inputMsg:"你好世界"
}
子组件:BaseVModel.vue
//html
<!-- 5.拓展和应用:把一个input文本框改成组件 -->
<input type="text" :value="value" @input="inputFunc">
//js
props:{
// cityId:String
value:String//改成用value接收,input的拓展示例也用这个value属性
},
methods: {
inputFunc(e){
this.$emit("input",e.target.value);
}
},