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页面刷新,数据丢失的问题
Nov 24 Vue.js
详解Vue 的异常处理机制
Nov 30 Vue.js
vue组件中节流函数的失效的原因和解决方法
Dec 02 Vue.js
vue实现两个区域滚动条同步滚动
Dec 13 Vue.js
vue3.0实现插件封装
Dec 14 Vue.js
Vue实现随机验证码功能
Dec 29 Vue.js
vue form表单post请求结合Servlet实现文件上传功能
Jan 22 Vue.js
vue常用高阶函数及综合实例
Feb 25 Vue.js
vue整合百度地图显示指定地点信息
Apr 06 Vue.js
vue二维数组循环嵌套方式 循环数组、循环嵌套数组
Apr 24 Vue.js
vue elementUI批量上传文件
Apr 26 Vue.js
vue/cli 配置动态代理无需重启服务的方法
May 20 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
JavaScript创建命名空间的5种写法
2014/06/24 PHP
PHP使用mysql_fetch_row查询获得数据行列表的方法
2015/03/18 PHP
PHP中多线程的两个实现方法
2016/10/14 PHP
短信提示使用 特效
2007/01/19 Javascript
jquery中:input和input的区别分析
2011/07/13 Javascript
Javascript图像处理—为矩阵添加常用方法
2012/12/27 Javascript
jQuery判断checkbox是否选中的小例子
2013/12/02 Javascript
jQuery调取jSon数据并展示的方法
2015/01/29 Javascript
JavaScript获得页面base标签中url的方法
2015/04/03 Javascript
JavaScript中继承用法实例分析
2015/05/16 Javascript
JavaScript人脸识别技术及脸部识别JavaScript类库Tracking.js
2015/09/14 Javascript
JS函数定义方式的区别介绍
2016/03/22 Javascript
JavaScript中的继承之类继承
2016/05/01 Javascript
微信小程序 HTTPS报错整理常见问题及解决方案
2016/12/14 Javascript
[Bootstrap-插件使用]Jcrop+fileinput组合实现头像上传功能实例代码
2016/12/20 Javascript
原生和jQuery的ajax用法详解
2017/01/23 Javascript
Angular实现可删除并计算总金额的购物车功能示例
2017/12/26 Javascript
微信小程序wepy框架笔记小结
2018/08/08 Javascript
vscode下vue项目中eslint的使用方法
2019/01/13 Javascript
Vue3.0 响应式系统源码逐行分析讲解
2019/10/14 Javascript
微信小程序实现转盘抽奖
2020/09/21 Javascript
[01:02:03]2014 DOTA2华西杯精英邀请赛 5 24 NewBee VS VG
2014/05/26 DOTA
Python中的异常处理学习笔记
2015/01/28 Python
Python中利用Scipy包的SIFT方法进行图片识别的实例教程
2016/06/03 Python
Python标准库06之子进程 (subprocess包) 详解
2016/12/07 Python
Python判断文件或文件夹是否存在的三种方法
2017/07/27 Python
Python机器学习之决策树算法
2017/12/22 Python
浅析python参数的知识点
2018/12/10 Python
pandas的连接函数concat()函数的具体使用方法
2019/07/09 Python
Python turtle库绘制菱形的3种方式小结
2019/11/23 Python
详解基于Facecognition+Opencv快速搭建人脸识别及跟踪应用
2021/01/21 Python
Parfume Klik丹麦:香水网上商店
2018/07/10 全球购物
分解成质因数(如435234=251*17*17*3*2,据说是华为笔试题)
2014/07/16 面试题
公司营业员的自我评价
2014/03/04 职场文书
长辈生日祝福语大全(72句)
2019/08/09 职场文书
python pandas 解析(读取、写入)CSV 文件的操作方法
2022/12/24 Python