1.Vue双向绑定/MVVM响应式原理/v-model的原理
vue.js通过数据劫持结合发布订阅者模式,通过Object.defineProperty来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
2.Vue的发布订阅者模式
data中每个数据都绑定一个Dep,这个Dep中都存有所有用到该数据的观察者,
当数据改变时,发布消息给Dep,去通知每一个观察者,做出相应的回调函数。
3.MVVM原理
Model:Vue中的data数据
View:页面视图
ViewModel: model和view之间的枢纽,Vue源码
MVVM作为绑定的入口,整合observer,compile,watcher三者,通过observe来监听model数据变化,通过compile来解析编译模板指令,最终利用watcher搭起observe,compile之间的通信桥路,达到数据变化->视图更新,视图交互变化->数据model变更的双向绑定效果。
index.html

<!DOCTYPE html>
<header><title></title>
</header>
<body><div id="app"><h1>{{str}}</h1>{{str}}{{yy}}<button @click='btn'>按钮</button><input type="" name="" v-model='str'></div><script type="text/javascript" src="vue.js"></script><script>//vue是一个构造函数new Vue({el:'#app',data:{str:'你好',yy:'yaya'},//生命周期beforeCreate() {console.log('beforeCreate',this.$data,this.$el)},created() {console.log('created',this.$data,this.$el)},beforeMount() {console.log('beforeMount',this.$data,this.$el)},mounted() {console.log('mounted',this.$data,this.$el)},methods: {btn(e) {alert(1)console.log(e)this.str='hahaha'}}})</script></body>
</html>

vue.js

class Vue{constructor(options){// 将options挂到全局上this.$options=optionsthis.$watchEvent={}this.observe()if(typeof options.beforeCreate=='function') {options.beforeCreate.call(this)}//$datathis.$data=options.data//数据劫持this.proxyData()if(typeof options.created=='function') {options.created.call(this)}if(typeof options.beforeMount=='function') {options.beforeMount.call(this)}//节点$elthis.$el=document.querySelector(options.el)//模板解析this.compile(this.$el)if(typeof options.mounted=='function') {options.mounted.call(this)}}//数据劫持//1.给vue本身对象赋属性,来自data中;// 2.vue本身对象中的属性和data中的属性保持一致proxyData() {for(let k in this.$data) {Object.defineProperty(this,k,{get() {return this.$data[k]},set(val) {this.$data[k]=val}}) // console.log(this)}}//监听数据变化//触发data中的数据变化后执行watch中的updataobserve() {for(let key in this.$data) {let that=thislet value=this.$data[key]Object.defineProperty(this.$data,key,{get() {return value},set(val) {console.log('改变了')value=valif(that.$watchEvent[key]) {that.$watchEvent[key].forEach((item,index)=> {item.update()})}}}) }  }//渲染compile(node){node.childNodes.forEach((item,index)=> {//文本节点if(item.nodeType==3) {let reg=/\{\{(.*?)\}\}/glet text=item.textContent//给节点赋值item.textContent=text.replace(reg,(match,key)=> {key=key.trim()if(this.hasOwnProperty(key)) {let watch=new Watcher(this,key,item,'textContent')//属性,节点,内容if(this.$watchEvent[key]) {this.$watchEvent[key].push(watch)}else {this.$watchEvent[key]=[]this.$watchEvent[key].push(watch)}}return this.$data[key]})}//元素节点if(item.nodeType==1) {// 判断元素节点是否绑定了自定义属性@clickif(item.hasAttribute('@click')) {// 获取自定义属性的值let fn=item.getAttribute('@click').trim()item.addEventListener('click',(e)=> {console.log(this.$options)// 执行绑定了自定义属性的事件this.$options.methods[fn]// 事件对象this.$options.methods[fn](e)})}//判断元素节点是否添加了v-model指令if(item.hasAttribute('v-model')) {let key=item.getAttribute('v-model').trim()if(this.hasOwnProperty(key)){// console.log(this[key])item.value=this[key]}item.addEventListener('input',(e)=> {this[key]=item.value})}// 元素节点中的文本节点if(item.childNodes.length>0) {this.compile(item)}          }})}
}
//更新视图DOM
class Watcher{constructor(o,key,node,attr) {//对象this.o=o//属性名称this.key=key//结点this.node=node//改变文本节点内容的字符串this.attr=attr}// 更新操作update() {console.log(this.key)this.node[this.attr]=this.o[this.key]}
}

Vue源码分析-手写Vue(简易版)相关推荐

  1. Vue 源码之手写Vue Router

    Vue 源码之手写Vue Router 源码地址:https://github.com/CONOR007/Handwritten-routing 一.Vue Router的两种模式 hash模式实现原 ...

  2. 面试必会之ArrayList源码分析手写ArrayList

    作者:Java知音-微笑面对生活 简介 ArrayList是我们开发中非常常用的数据存储容器之一,其底层是数组实现的,我们可以在集合中存储任意类型的数据,ArrayList是线程不安全的,非常适合用于 ...

  3. 源码分析 | 手写mybait-spring核心功能(干货好文一次学会工厂bean、类代理、bean注册的使用)

    小傅哥 | https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获.专注于原创专题案例编写,目前已完成的专题有:Netty4.x实战专题案例.用Java实现JVM.基于Ja ...

  4. Vue源码分析——第三章

    Vue源码分析--第一章 Vue源码分析--第二章 // only used in dev mode//检测 val必需是数字function checkDuration(val, name, vno ...

  5. [Vue源码分析] 模板的编译

    最近小组有个关于vue源码分析的分享会,提前准备一下- 前言: Vue有两个版本:Runtime + Compiler . Runtime only ,前者是包含编译代码的版本,后者不包含编译代码,编 ...

  6. vue源码分析系列二:$mount()和new Watcher()的执行过程

    续vue源码分析系列一:new Vue的初始化过程 在initMixin()里面调用了$mount() if (vm.$options.el) {vm.$mount(vm.$options.el);/ ...

  7. Vue源码分析--Vue.component

    Vue源码分析–Vue.component 我将非 Vue.component 的部分去掉了 export function initAssetRegisters (Vue: GlobalAPI) { ...

  8. [Vue源码分析]自定义事件原理及事件总线的实现

    最近小组有个关于vue源码分析的分享会,提前准备一下- 前言: 我们都知道Vue中父组件可以通过 props 向下传数据给子组件:子组件可以通过向$emit触发一个事件,在父组件中执行回调函数,从而实 ...

  9. [Vue源码分析] v-model实现原理

    最近小组有个关于vue源码分析的分享会,提前准备一下- 前言: 我们都知道使用v-model可以实现数据的双向绑定,及实现数据的变化驱动dom的更新,dom的更新影响数据的变化.那么v-model是怎 ...

最新文章

  1. 计算Be原子基态能级
  2. C++类型转换: static_cast const_cast reinterpret_cast dynamic_cast
  3. linux pdf转换swf,CENTOS 5   PDF转换为SWF
  4. Mind Master Pro 8.0——安装教程
  5. 《终身成长》读书笔记(part3)--如果一个人能学会什么东西,那么世界上其他人也都可以学会
  6. 基本响应性的Web设计测试工具
  7. [2020-09-11 CQBZ/HSZX多校联测 T2] 泰拳警告(组合数+数学期望)
  8. 学习swing鼠标点击事件心得体会_西门子COMOS软件开发定制学习8-查询列表间的数据交互...
  9. 地铁售票系统设计思想及部分代码
  10. 深入理解HDFS:Hadoop分布式文件系统
  11. 小鹏汽车4月交付量5147台 同比增长285%
  12. 牛客网算法工程师能力评估
  13. Android实现计算器布局(表格布局)
  14. pcap文件格式及写pcap文件
  15. OverFeat学习
  16. 云服务器性能对照表,云服务器 性能对比
  17. 爬虫goodreads数据_精通技术的读者正在设计自己更好的goodreads版本
  18. becon帧 wifi_beacon帧
  19. 戏说数据仓库,商业智能BI中数据仓库的本质是什么?
  20. 【Java刷题】04_二叉树的左右视图

热门文章

  1. 海天酱油调味多元化,塑造品牌口碑
  2. elasticsearch7.0.1-highlighter高亮检索详解
  3. 《两地书》--Kubernetes(K8s)基础知识(docker容器技术)
  4. 写博客小技巧推荐(有简易版动图教程)
  5. 【机器学习-周志华】学习笔记-第十五章
  6. mtu 服务器优化,修改MTU值优化网络
  7. 从十几台电脑到百万IT投资 CIO张宝杰谈主动出击
  8. qt 控件设置相对位置_qt 手动设置控件的位置
  9. 头歌平台-人工智能导论实验(神经网络)
  10. python数据容器之集合、字典