非非非题目党,干货预警!!!
介绍
大家好,我是清池交友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实现数据变动更新视图的性能
代码实现
接下来看代码如下:
//实例化vueconst 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,女生收费,男生免费