当前位置: 首页 > news >正文

wordpress 登陆后查看/seo优化外包

wordpress 登陆后查看,seo优化外包,有什么类似凡科建站,网站搭建策划书1. 说明 compile 编译,即模板解析器,能够对模板中的指令和插值表达式进行解析observer 数据劫持,即数据监听器,能够对数据对象(data)的所有属性进行监听watcer 监听者,将compile的解析结果,与observer所观察…

1. 说明

  1. compile 编译,即模板解析器,能够对模板中的指令和插值表达式进行解析
  2. observer 数据劫持,即数据监听器,能够对数据对象(data)的所有属性进行监听
  3. watcer 监听者,将compile的解析结果,与observer所观察的对象连接起来,建立关系,在observer观察到数据对象变化时,接收通知,并更新DOM

gitbub

2. 实现MVVM原理

2.1 目录结构

2.2 index.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head><body><div id="app"><input type="text" v-model="message.a"><div>{{b}}</div><ul><li>{{message.a}}</li></ul>{{b}}</div><!-- <script src="https://cdn.jsdelivr.net/npm/vue"></script> --><script src="./watcher.js"></script><script src="./observer.js"></script><script src="./compile.js"></script><script src="./mvvm.js"></script><script>let vm = new MVVM({el: '#app',data: {message: {a: 'aa'},b: 'bb'}})</script>
</body></html>
复制代码

3. mvvm

  1. 整合编译和数据劫持
  2. 代理,使vm.$data.message => vm.message

3.1 完整mvvm.js

class MVVM {constructor(options) {// 实例上的dom元素,<div id="app"></div>this.$el = options.el;// 实例上的所有数据,datathis.$data = options.data;// 如果有这个dom元素,才开始if (this.$el) {// 数据劫持,就是对数据的所有属性,改成set和get的方法,以至可以在数据获取前和改变后,触发其它方法(做点事情)new Observer(this.$data);this.proxyData(this.$data)// 编译元素,例如<input type="text" v-model="message.a">,根据message.a,找到data中对应的message.a的数据,赋值给input的valuenew Compile(this.$el, this)}}// proxy代理: vm.$data.message => vm.messageproxyData(data) {Object.keys(data).forEach(key => {Object.defineProperty(this, key, {get() {return data[key]},set(newValue) {data[key] = newValue;}})})}
}
复制代码

4. compile

4.1 nodeType

nodeType 属性返回节点类型。

  1. 如果节点是一个元素节点,nodeType 属性返回 1。

  2. 如果节点是属性节点, nodeType 属性返回 2。

  3. 如果节点是一个文本节点,nodeType 属性返回 3。

4.2 createDocumentFragment()

  1. DocumentFragments 是DOM节点。它们不是主DOM树的一部分。通常的用例是创建文档片段,将元素附加到文档片段,然后将文档片段附加到DOM树。在DOM树中,文档片段被其所有的子元素所代替。
  2. 因为文档片段存在于内存中,并不在DOM树中,所以将子元素插入到文档片段时不会引起页面回流(对元素位置和几何上的计算)。因此,使用文档片段通常会带来更好的性能。

4.3 reduce

4.3.1 说明

接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值

4.3.2 有一个字符串message.a.b,有一个对象{"message":{"a":{"b":"我是bb"}}},想要找到字条串中的b,在对象中key为b,对应的value

        //对象var dataObj = {message: {a: {b: '我是bb'}},};//字符串var dataStr = 'message.a.b';// 字符串转成数组var dataArray = dataStr.split('.')console.log(dataArray)//找到字条串中的b,在对象中key为b,对应的valuevar result = dataArray.reduce((prev, next) => {return prev[next]}, dataObj)console.log(result)
复制代码

4.4 /\{\{([^}]+)\}\}/g;

将{{a}} => a

        let expr = "{{message.a.b}}"; // 取文本中的内容let reg = /\{\{([^}]+)\}\}/g; // {{a}} {{b}} {{c}} var result = expr.replace(reg, 'a');console.log(result)
复制代码

4.5 ...运算符

        function sub(...arg) {let sum = 0;arg.forEach(item => {sum += item;})return sum;}var a = sub(1, 2, 3)var b = sub(1, 2, 3, 4)console.log(a)   //6console.log(b)   //10
复制代码

4.6 setVal()

监听input输入框的值,根据<input type="text" v-model="message.a">(message.a),然后把值赋给vm.data里对应的键(vm.data.message.a = 值),再更新视图上的显示modelUpdater

    model(node, vm, expr) { let updateFn = this.updater['modelUpdater'];node.addEventListener('input', (e) => {let newValue = e.target.value;this.setVal(vm, expr, newValue)})updateFn && updateFn(node, this.getVal(vm, expr));},
复制代码
    setVal(vm, expr, value) { // [message,a]expr = expr.split('.');return expr.reduce((prev, next, currentIndex) => {if (currentIndex === expr.length - 1) {return prev[next] = value;}return prev[next];}, vm.$data);},
复制代码
    updater: {modelUpdater(node, value) {node.value = value;}}
复制代码

4.6 完整compile.js代码

class Compile {constructor(el, vm) {this.el = this.isElementNode(el) ? el : document.querySelector(el);this.vm = vm;if (this.el) {let fragment = this.node2fragment(this.el);this.compile(fragment);this.el.appendChild(fragment)}}isElementNode(node) {return node.nodeType === 1;}isDirective(name) {return name.includes('v-')}compileElement(node) {let attrs = node.attributes;Array.from(attrs).forEach(attr => {let attrName = attr.name;if (this.isDirective(attrName)) {let expr = attr.value;let [, type] = attrName.split('-');CompileUtil[type](node, this.vm, expr)}})}compileText(node) {let expr = node.textContent;let reg = /\{\{([^}]+)\}\}/g;if (reg.test(expr)) {CompileUtil['text'](node, this.vm, expr)}}compile(fragment) {let childNodes = fragment.childNodes;Array.from(childNodes).forEach(node => {if (this.isElementNode(node)) {this.compileElement(node)this.compile(node)} else {this.compileText(node)}})}node2fragment(el) {let fragment = document.createDocumentFragment();let firstChild;while (firstChild = el.firstChild) {fragment.appendChild(firstChild);}return fragment;}
}CompileUtil = {getVal(vm, expr) {expr = expr.split('.');return expr.reduce((prev, next) => {return prev[next]}, vm.$data)},getTextVal(vm, expr) {return expr.replace(/\{\{([^}]+)\}\}/g, (...argument) => {return this.getVal(vm, argument[1])})},setVal(vm, expr, value) {expr = expr.split('.');return expr.reduce((prev, next, currentIndex) => {if (currentIndex === expr.length - 1) {return prev[next] = value}return prev[next]}, vm.$data)},model(node, vm, expr) {let updateFn = this.updater['modelUpdater'];let value = this.getVal(vm, expr);new Watcher(vm, expr, (newValue) => {updateFn && updateFn(node, this.getVal(vm, expr))})node.addEventListener('input', (e) => {let newValue = e.target.value;this.setVal(vm, expr, newValue)})updateFn && updateFn(node, value)},text(node, vm, expr) {let updateFn = this.updater['textUpdater'];let value = this.getTextVal(vm, expr);expr.replace(/\{\{([^}]+)\}\}/g, (...argument) => {new Watcher(vm, argument[1], (newValue) => {updateFn && updateFn(node, this.getTextVal(vm, expr))})})updateFn && updateFn(node, value)},updater: {modelUpdater(node, value) {node.value = value;},textUpdater(node, value) {node.textContent = value;}}
}
复制代码

5. observer

5.1 this.subs=[]

<div id="app"></div>下面的节点为准,{{b}}算1个,message.a算2个

3个watcher

    <div id="app"><input type="text" v-model="message.a"><div>{{b}}</div></div>
复制代码
    addSub(watcher) {this.subs.push(watcher)console.log(this.subs)}
复制代码

5个watcher

    <div id="app"><input type="text" v-model="message.a"><div>{{b}}</div>{{message.a}}</div>
复制代码

5.2完整observer.js代码

class Observer {constructor(data) {this.observer(data)}observer(data) {if (!data || typeof data !== 'object') {return;}Object.keys(data).forEach(key => {this.defineReactive(data, key, data[key]);this.observer(data[key])})}defineReactive(obj, key, value) {let that = this;let dep = new Dep();Object.defineProperty(obj, key, {enumerable: true,configurable: true,get() {Dep.target && dep.addSub(Dep.target);return value;},set(newValue) {if (newValue != value) {that.observer(newValue)value = newValue;dep.notify();}}})}
}class Dep {constructor() {this.subs = [];}addSub(watcher) {this.subs.push(watcher);}notify() {this.subs.forEach(watcher => watcher.update())}
}
复制代码

6. watcer

6.1 new Watcher()

<div id="app"></div>下面的节点(有expr),一个expr对应一个watcher,一个watcher后续变化都保存到一个dep.subs[]里

6.2 完整watcer.js代码

class Watcher {constructor(vm, expr, cb) {this.vm = vm;this.expr = expr;this.cb = cb;this.value = this.get();}getVal(vm, expr) {expr = expr.split('.'); // [message,a]return expr.reduce((prev, next) => { // vm.$data.areturn prev[next];}, vm.$data);}get() {Dep.target = this;let value = this.getVal(this.vm, this.expr);Dep.target = null;return value;}update() {let newValue = this.getVal(this.vm, this.expr);let oldValue = this.value;if (newValue != oldValue) {this.cb(newValue)}}
}
复制代码

7. 效果

GifCam录制gif

7.1 修改数据,视图变化

  1. 操作前,根据表达式v-model="message.a",得到vm.data里的数据,compile,渲染到页面
  2. vm.data里的数据变化,触发observer.set(),
  3. 因为新旧数据不一样,触发dep.notify()
  4. 触发watcher里的this.cb(newValue)
  5. 触发compile里的CompileUtil.updater()

7.2 修改视图,数据变化

  1. node.addEventListener('input'),监听输入框,得到新值newValue
  2. setVal(),使用vm.data里的数据等于新值
  3. 重复上面操作

转载于:https://juejin.im/post/5c835e546fb9a049fc0454a1

http://www.jmfq.cn/news/5083021.html

相关文章:

  • 顺德网站建设收费标准/万网域名官网
  • 公司网站建设费/游戏代理推广渠道
  • 南昌网站建设过程/东莞做网站推广公司
  • 个人做门户网站/百度软件中心官网
  • 微商怎么引流推广/厦门百度seo公司
  • 企业网站建设与实现的论文/百度seo技术优化
  • 做网站不推广/个人网站seo
  • 二手房网签合同在哪个网站做/广州网络营销
  • 宣城做网站公司/宁波seo网络推广产品服务
  • 网站开发需要数据库技术/关键词seo公司
  • 商城网站建设公司/搜索百度网页版
  • 想学设计怎么入门在家自己学/重庆关键词seo排名
  • 云南做网站价格/品牌营销策略有哪些
  • 网站推广是做什/石家庄头条今日头条新闻
  • 建设学院网站的通知书/产品推广策略
  • 广告行业网站建设方案/广告营销案例分析
  • 烟台网站制作策划/营销型网站设计制作
  • 海外代购网站怎么做/常见的网站推广方式
  • 河北高端网站建设/运营是做什么的
  • 如何做公众号小说网站赚钱/直通车怎么开
  • 做网站的公司多少钱/福建seo推广方案
  • 政府网站建设如何做/北京seo相关
  • 网站建设 商城/免费友情链接
  • 西安本地十家做网站建设的公司/营销型网站定制
  • 网站群建设项目招标公告/网络营销的缺点及建议
  • 汕头网站设计制作公司/链接下载
  • 中国铁建华南建设有限公司网站/深圳疫情防控最新消息
  • 如何做自己的在线作品网站/百度怎么发免费广告
  • 做网站认证违法吗/免费网页制作平台
  • 网站申请注册 免备案/加强服务保障 满足群众急需需求