v-model原理(简易源码版)

说明

最近对v-model的源码分析一会,现在分享一下自己的见解,由于对源码可能不太熟悉,可能分析的太片面了,如果有大佬看见了也可以补充,我会及时的修改

作用与机制的分析

  1. 双向数据绑定机制
    v-model 是 Vue.js 中用于实现双向数据绑定的关键指令,它使得表单输入元素(如 input、textarea、select 等)的值能够与 Vue 实例的数据属性自动保持同步。双向数据绑定意味着当用户在表单元素上进行交互(如输入文本、选择选项等)时,Vue 实例对应的 data 属性会立即更新;反之,如果 data 属性的值发生变化,表单元素的显示值也会相应更新。
  2. v-model 的语法糖解析
    v-model 在底层实际上是以下两部分行为的封装:
    数据绑定(v-bind:value):将 Vue 实例中指定的数据属性(如 msg)绑定到表单元素的 value 属性(对于 checkbox 和 radio 类型,可能绑定的是 checked 属性)。这样,初始时表单元素会显示对应数据属性的值。

分析

  1. 由于v-model是指令,所以我们可以使用Vue给我们提供的自定义指令的方法Vue.directive()
  2. 使用自定义指令里面提供的bind方法,在这里主要是对绑定的元素进行绑定事件
    由于一般只有表单元素会和用户进行交互,所以这里就只对表单元素进行绑定,初次绑定之后,

比如:文本框绑定的input事件,select绑定的是change事件

3.先使用 el.value = vm[binding.expression]将一开始在data 绑定的值给表单的初始值(value)

4.然后给相对应的表单添加对应的响应事件

5.在响应事件函数回调中修改绑定的变量值,值为当前的表单的值,现在初始化

完成了,也做到了页面的值和data的值一样了,但是还有一个问题没解决,就是在改变data里面的值的时候怎么做到让页面的值更改

6.使用update监听该指令绑定的值是否改变,改变的时候 **el.value = vnode.context[binding.expression];**将页面的值替换为data的值

javascript 复制代码
// 定义一个名为 "my-model" 的自定义指令,实现类似 v-model 的双向绑定功能
Vue.directive('my-model', {
    // 指令的 "bind" 钩子,在元素首次绑定指令时执行
    bind(el, binding, vnode) {
      // 获取当前指令绑定的 Vue 实例上下文
      const vm = vnode.context;
      // 初始化时设置元素值,将数据模型的值赋给元素的 value 属性
      el.value = vm[binding.expression];
      // 监听 input 事件,当元素值发生改变时,更新数据模型
      el.addEventListener('input', function (event) {
        // 使用 $set 方法确保数据模型的属性变更能够触发视图更新
        vm.$set(vm, binding.expression, event.target.value);
      });
    },
  
    // 指令的 "update" 钩子,在指令绑定的值发生变化时执行
    // 优化:使用 "update" 钩子替代内嵌 Vue 实例,避免内存泄漏
    update(el, binding, vnode) {
      // 当数据模型的值变化时,同步更新元素的 value 属性
      el.value = vnode.context[binding.expression];
    },
  });
  
  // 创建主 Vue 实例
  new Vue({
    el: '#app',
    data: {
      inputValue: '', // 数据模型,用于双向绑定的值
    },
    methods: {
      showValue() {
        alert(this.inputValue); // 显示当前数据模型的值
      },
    },
  });
相关推荐
森叶2 分钟前
webpack 的打包target讲解 & node环境打包下的文件存储造成不易察觉的坑点
前端·webpack·node.js
亿牛云爬虫专家12 分钟前
Puppeteer的高级用法:如何在Node.js中实现复杂的Web Scraping
前端·javascript·爬虫·node.js·爬虫代理·puppeteer·代理ip
uhan2517 分钟前
2024年9月26日 linux笔记
linux·服务器·前端
Jiaberrr35 分钟前
uniapp视频禁止用户推拽进度条并保留进度条显示的解决方法——方案一
前端·javascript·微信小程序·uni-app·音视频
慧都小妮子1 小时前
Spire.PDF for .NET【页面设置】演示:设置 PDF 的查看器首选项和缩放系数
前端·pdf·.net·spire.pdf
OEC小胖胖1 小时前
js中正则表达式中【exec】用法深度解读
开发语言·前端·javascript·正则表达式·web
有一个好名字1 小时前
vue3路由
前端·vue.js
计算机学姐1 小时前
基于php摄影门户网站
开发语言·vue.js·vscode·后端·php·phpstorm·webstorm
马卫斌 前端工程师2 小时前
npm 源切换以及添加 使用工具 nrm 使用方法
前端·npm·node.js
小彭努力中2 小时前
49. 建模软件绘制3D场景(Blender)
前端·3d·blender·webgl