非非非题目党,干货预警!!!
介绍
大家好,我是清池交友 app 开发日记,记录清池交友 app 开发中学习过程和踩坑日记,伪全栈
技术栈:前端 js,vue,uniapp,后端 java
尤大镇贴
先奉上 2013 年尤大写的 vue 的第一行代码来自:
github 源码地址镇贴:vue 官网仓库 0.1 分支 explorations/getset.html 文件
引读:
- 本篇文章,用 30 行代码实现 0.1 版本 vue,是参照尤大 2013 年,在 git 上传的 vue 的第一行代码 (vue 的 0.1) 版本代码思路实现的,尤大仅用 40 行代码就实现了 0.1 版本的 vue。
- 为了更不便学习和交换,咱们基于尤大的代码省略了一些内容,提取外围性能代码,调整了代码程序,批改了局部变量命名,减少了正文,仅剩 30 行代码,更加简洁,直观的向大家展现 vue 的外围性能实现逻辑。
- 自己也是个小菜鸟,整顿本篇文章用了一天的工夫,不足之处欢送大家斧正批评,文中代码的具体实现细节存在不谨严的中央,请大家疏忽,本文仅用来交换 vue 的实现思维,并未深究细节。
注释:
实现逻辑简述
本文 30 行代码实现 vue,github 仓库地址
本篇文章中代码仅实现了 vue 的外围性能数据绑定,未实现其余性能。
文中 html 可间接关上在浏览器中运行,查看成果
咱们先用文字来简略形容下外围代码的实现逻辑
- 获取 vue 根结点的 dom,替换 dom 中的 {{}} 模板语法,并依据模板 {{msg}} 中应用 data 中的属性名称 (msg) 为其打上标记,不便之后寻找哪些 dom 应用了模板语法
- 记录模板语法中应用了 data 中的哪些属性,不便在这些值变动时更新 dom
- 遍历这些属性,并根属性名称找到对应的 dom,移除标记(标记用来寻找 dom,此时曾经取得了 dom,所以移除标记)
- 拦挡属性的 set、get 办法,在 set 属性时,更新 dom 的 textContent 实现数据变动更新视图的性能
代码实现
接下来看代码如下:
// 实例化 vue
const app = new vue('app', {msg: '清池丨洁净的恋爱交友 app'})
//id: app
//initData: {msg: "hello"}
function vue(id, initData) {
//vue 中个别都蕴含 el 属性,代表 vue 实例对应的 dom 元素
const vueDom = this.el = document.getElementById(id) // 获取 #app dom <div id="app">...</div>
//vue 的 data 属性,尾部为 data 赋值
const data = this.data = {}
// 定义常量,用来标示须要数据绑定的 dom 元素应用
const bindingMark = 'bind-dom-flag'
// 定义长期变量来存储模板中应用了 data 中的值的列表
const dataAttrs = {}
// 替换 #app dom 中的模板内容
vueDom.innerHTML = vueDom.innerHTML.replace(/{{(.*)}}/g, (match, dataAttrName) => {
// 用来记录模板中应用了 data 中的哪些值,本案例模板中只应用 data 中的 msg
dataAttrs[dataAttrName] = {} // {msg: {}}
// 给应用了模板的 dom 打上标记,bindingMark = data 中的值 msg,以便将这些 dom 放进 dataAttrs 中
return '<span' + bindingMark + '="' + dataAttrName + '"></span>'
})
// 遍历 dom 中应用的 data 属性
for (const dataAttrName in dataAttrs) {
// 获取 data 对应的 dom 列表
const doms = vueDom.querySelectorAll('[' + bindingMark + '="' + dataAttrName + '"]')
// 移除 dom 上的标记,标记用来获取 dom 列表,获取后就能够将标记删除了
doms.forEach((e) => {e.removeAttribute(bindingMark)
})
// 获取定义长期变量中的 dataAttr 对象,defineProperty 实现数据绑定须要借助这个对象来实现
const dataAttrObj = dataAttrs[dataAttrName]
// 劫持 data 属性的 set,get 办法
Object.defineProperty(data, dataAttrName, {get() {
// 返回长期变量 dataAttr 中的 attr
return dataAttrObj.val
},
set(newVal) {
// 更新 data 中此属性对应的所有 dom,更新所有模板中应用了 msg 的 dom
doms.forEach((dom) => {dataAttrObj.val = dom.textContent = newVal})
}
})
}
// 将内部传入的初始化值赋值给 vue 实例的 data 属性
for (const dataAttrName in initData) {
// 赋值,触发 set,更新 dom
this.data[dataAttrName] = initData[dataAttrName]
}
}
复制代码
html 如下:
<div id="app">
<p>{{msg}}</p>
<p>{{msg}}</p>
<p>{{msg}}</p>
</div>
复制代码
结尾总结:
看完本篇文章,置信大家对 vue 的基本原理和实现形式都能有一个清晰的意识了吧,连忙入手去撸一个 mini-vue 吧,这曾经是面试中必不可少的试题了
文中不足之处欢送大家斧正批评,有须要交换的问题也欢送大家踊跃留言。
清池 app 开发日记是记录清池 app 开发中学习过程和踩坑日记,清池 app 目前有 20w+ 注册用户,3000 日活,次要用户年龄在 16-23 之间
如果您对一款社交软件从 0 -0.1 的成长过程中遇到的趣事和技术问题感兴趣,欢送关注咱们的公众号,咱们一起成长
咱们的技术栈,伪全栈,前端 js,vue,uniapp,后端 java
清池 app 官网:www.qingchi1.com
对于和分割咱们:www.qingchi1.com/about
公众号:qingchiapp,(关注公众号获取清池 app 我的项目的开源代码,星空话缘,原谅这个名字是之前的,当前会改成清池 app 开发日记)
交友群 +v:qingchizh,群内男女比例 1:5-10,女生收费,男生免费