vue 使用 v-model 双向绑定父子组件的值遇见的问题及解决方案


Posted in Vue.js onMarch 01, 2021

场景

今天在使用 v-model 进行组件双向数据绑定的时候遇到了一个奇怪的问题,网页本身运行正常,浏览器一直出现警告信息。

[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "value"

引发这个警告的是一个自定义组件 RxSelect

Vue.component("RxSelect", {
 model: {
 prop: "value",
 event: "change",
 },
 props: {
 value: [Number, String],
 map: Map,
 },
 template: `
  <select
   v-model="value"
   @change="$emit('change', value)"
  >
   <option
   v-for="[k,v] in map"
   :value="k"
   :key="k"
   >{{v}}</option>
  </select>
  `,
});

吾辈使用的代码看起来代码貌似没什么问题?

<main id="app">
 当前选择的性别是: {{map.get(sex)}}
 <div>
 <rx-select :map="map" v-model="sex" />
 </div>
</main>

JavaScript 代码

new Vue({
 el: "#app",
 data: {
 map: new Map().set(1, "保密").set(2, "男").set(3, "女"),
 sex: "",
 },
});

经测试,程序本身运行正常,父子组件的传值也没什么问题,双向数据绑定确实生效了,然而浏览器就是一直报错。

尝试解决

吾辈找到一种方式

  1. 为需要双向绑定的变量在组件内部 data 声明一个变量 innerValue,并初始化为 value
  2. select 上使用 v-model绑定这个变量 innerValue
  3. 监听 value 的变化,在父组件中 value 变化时修改 innerValue 的值
  4. 监听 innerValue 的变化,在变化时使用 this.$emit('change', val) 告诉父组件需要更新 value 的值
Vue.component("RxSelect", {
 model: {
 prop: "value",
 event: "change",
 },
 props: {
 value: [Number, String],
 map: Map,
 },
 data() {
 return {
  innerValue: this.value,
 };
 },
 watch: {
 value(val) {
  this.innerValue = val;
 },
 innerValue(val) {
  this.$emit("change", val);
 },
 },
 template: `
 <select v-model="innerValue">
 <option
  v-for="[k,v] in map"
  :value="k"
  :key="k"
 >{{v}}</option>
 </select>
 `,
});

使用代码完全一样,然而组件 RxSelect 的代码却多了许多。。。

解决

一种更优雅的方式是使用 computed 计算属性以及其的 get/set,代码增加的程度还是可以接受的

Vue.component("RxSelect", {
 model: {
 prop: "value",
 event: "change",
 },
 props: {
 value: [Number, String],
 map: Map,
 },
 computed: {
 innerValue: {
  get() {
  return this.value;
  },
  set(val) {
  this.$emit("change", val);
  },
 },
 },
 template: `
 <select v-model="innerValue">
 <option
  v-for="[k,v] in map"
  :value="k"
  :key="k"
 >{{v}}</option>
 </select>
 `,
});

以上就是vue 使用 v-model 双向绑定父子组件的值遇见的问题及解决方案的详细内容,更多关于vue 使用 v-model 双向绑定父子组件的值的资料请关注三水点靠木其它相关文章!

Vue.js 相关文章推荐
vue祖孙组件之间的数据传递案例
Dec 07 Vue.js
详解vue-cli项目在IE浏览器打开报错解决方法
Dec 10 Vue.js
Vue中computed和watch有哪些区别
Dec 19 Vue.js
vue 导航守卫和axios拦截器有哪些区别
Dec 19 Vue.js
利用Vue实现简易播放器的完整代码
Dec 30 Vue.js
Vue 数据响应式相关总结
Jan 28 Vue.js
如何管理Vue中的缓存页面
Feb 06 Vue.js
Vue全局事件总线你了解吗
Feb 24 Vue.js
Vue.js中v-for指令的用法介绍
Mar 13 Vue.js
vue数据字典取键值项目的字典问题
Apr 12 Vue.js
vue如何在data中引入图片的正确路径
Jun 05 Vue.js
vue el-table实现递归嵌套的示例代码
Aug 14 Vue.js
vue前端和Django后端如何查询一定时间段内的数据
Feb 28 #Vue.js
vue-router路由懒加载及实现的3种方式
Feb 28 #Vue.js
vue-router懒加载的3种方式汇总
Feb 28 #Vue.js
Vue SPA 首屏优化方案
Feb 26 #Vue.js
vue 动态添加的路由页面刷新时失效的原因及解决方案
Feb 26 #Vue.js
vue项目配置 webpack-obfuscator 进行代码加密混淆的实现
Feb 26 #Vue.js
vue中h5端打开app(判断是安卓还是苹果)
Feb 26 #Vue.js
You might like
PHP curl 并发最佳实践代码分享
2012/09/05 PHP
php变量作用域的深入解析
2013/06/03 PHP
php中把美国时间转为北京时间的自定义函数分享
2014/07/28 PHP
PHP的PDO预定义常量讲解
2019/01/24 PHP
抽出www.templatemonster.com的鼠标悬停加载大图模板的代码
2007/07/11 Javascript
javascript学习笔记(十) js对象 继承
2012/06/19 Javascript
js实现页面转发功能示例代码
2013/08/05 Javascript
jquery if条件语句的写法
2016/05/19 Javascript
浅谈JS使用[ ]来访问对象属性
2016/09/21 Javascript
jQuery+ajax的资源回收处理机制分析
2017/01/07 Javascript
vue.js实现用户评论、登录、注册、及修改信息功能
2020/05/30 Javascript
JavaScript实现连连看连线算法
2019/01/05 Javascript
iphone刘海屏页面适配方法
2019/05/07 Javascript
Vue中对iframe实现keep alive无刷新的方法
2019/07/23 Javascript
layui在form表单页面通过Validform加入简单验证的方法
2019/09/06 Javascript
JavaScript实现轮播图特效
2020/04/10 Javascript
django之常用命令详解
2016/06/30 Python
Python遍历目录并批量更换文件名和目录名的方法
2016/09/19 Python
详解python中 os._exit() 和 sys.exit(), exit(0)和exit(1) 的用法和区别
2017/06/23 Python
python中matplotlib实现最小二乘法拟合的过程详解
2017/07/11 Python
python生成多个只含0,1元素的随机数组或列表的实例
2018/11/12 Python
python http基本验证方法
2018/12/26 Python
TensorFlow卷积神经网络之使用训练好的模型识别猫狗图片
2019/03/14 Python
pytorch中tensor.expand()和tensor.expand_as()函数详解
2019/12/27 Python
python ubplot使用方法解析
2020/01/10 Python
澳大利亚游乐场设备品牌:Lifespan Kids
2019/05/24 全球购物
印尼购物网站:iLOTTE
2019/10/16 全球购物
Herschel Supply Co.美国:背包、手提袋及配件
2020/11/24 全球购物
留学自荐信写作方法
2014/01/27 职场文书
初中毕业典礼演讲稿
2014/09/09 职场文书
2014副镇长民主生活会个人对照检查材料思想汇报
2014/09/30 职场文书
群众路线查摆问题及整改措施
2014/10/10 职场文书
趣味运动会简讯
2015/07/20 职场文书
导游词之凤凰古城
2019/10/22 职场文书
小程序实现文字循环滚动动画
2021/06/14 Javascript
MySQL创建管理RANGE分区
2022/04/13 MySQL