mini 您所在的位置:网站首页 vue开发安卓app前期准备工作 mini

mini

2023-05-21 06:07| 来源: 网络整理| 查看: 265

mini-vue代码已放到github上。

数据驱动 数据响应式、双向绑定、数据驱动 数据响应式 数据模型仅仅是普通的javascript对象,而当我们修改数据时,视图会进行更新,避免了繁琐的DOM操作,提高开发效率。 双向绑定 数据改变,视图改变,视图改变,数据也随之改变 我们可以使用v-model在表单元素上创建双向数据绑定 数据驱动时Vue最独特的特性之一 开发过程中仅需要关注数据本身,不需要关心数据是如何渲染到视图 vue2.x响应式原理

当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property,并使用 Object.defineProperty 把这些 property 全部转为 getter/setter。Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。

下面我们来演示下Object.defineProperty如何使用

hello // 模拟vue中的data let data = { msg: 'hello' } // 模拟vue实例 let vm = {} // 数据劫持: 当访问或者设置vm中的成员的时候,做一些干预操作 Object.defineProperty(vm, 'msg', { // 可枚举 enumerable: true, // 可配置 configurable: true, // 取值操作 get() { console.log('get:', data.msg) return data.msg }, // 设置值操作 set(newValue) { if(newValue === data.msg) { return } data.msg = newValue document.querySelector('#app').textContent = data.msg } }) 复制代码

上述代码我们演示了单个属性的转化方法,如果多个属性的话即需要循环的给属性添加defineProperty即可,这块不做演示了

vue3.x响应式原理

vue3.x中使用proxy来进行监听对象,而不是属性,此外proxy IE不支持。

下面我们通过代码来演示下proxy

// 模拟vue中的data let data = { msg: 'hello' } // 模拟vue实例 let vm = new Proxy(data, { // 当访问vm对象的时候执行get方法 get(target, key) { return target(key) }, // 当设置vm的成员是会执行set方法 set(target, key, newValue) { if(target[key] === newValue) { return } target[key] = newValue document.querySelector('#app').textContent = target[key] } }) 复制代码 发布订阅模式

我们假定存在一个‘信号中心’,某个任务执行完成,就向信号中心发布(publish)一个信号,其他任务可以向信号中心‘订阅(subscibe)’这个信号,从而知道什么时候自己可以开始执行,这就叫做‘发布/订阅模式’(publish-subscribe pattern)

我们用兄弟组件通信过程来演示下发布订阅模式

// eventBus.js // 事件中心 let eventBus = new Vue(); // ComponentA.vue // 发布者 addTodo: function() { // 发布消息 eventBus.$emit('add-todo', {text: '发布新消息了'}) } // ComponentB.vue // 订阅者 create: function() { //订阅消息 eventBus.$on('add-todo', () => {}) } 复制代码

下面我们来模拟下vue自定义事件

let vm = new Vue(); vm.$on('dataChange', () => { console.log('dataChange') }) vm.$emit('dataChange') 复制代码 class EventEmitter { constructor() { this.subs = Object.create(null); } $on(eventType, handler) { this.subs[eventType] = this.subs[eventType] || []; this.subs[eventType].push(handler) } $emit(eventType) { if(this.subs[eventType] && Array.isArray(this.subs[eventType])) { this.subs[eventType].forEach(handler => { handler() }) } } } 复制代码 观察者模式 观察者(订阅者)--Watcher update() 当事件发生时,具体要做的事情 目标(发布者)--Dep subs数组 存储所有观察者 addSub() 添加观察者 notify() 当事件发生时,调用所有观察者的update方法 没有事件中心

下面我们用一段代码演示观察者模式

// 发布者-目标 class Dep { constructor() { this.subs = [] } addSub(sub) { if(sub && sub.update) { this.subs.push(sub) } } notify() { this.subs.forEach(sub => { sub.update() }) } } // 订阅者 Watcher class Watcher() { update() { console.log('update') } } 复制代码

总结:

观察者模式是有具体的目标调度,比如事件触发,Dep就会去调用观察者方法,所以观察者模式的订阅者与发布者之间时存在依赖的 发布/订阅模式由统一调度中心调用,因此发布者和订阅者不需要知道对方的存在。


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有