Только что прошла конференция vueconf (2018hangzhou), автор vue You Da показал нам прогресс vue 3.0 и внес некоторые изменения в vue 3.0, самое ожидаемое из которых - переписывание механизма мониторинга данных.
Просмотрите двустороннюю привязку данных vue2.x.
Когда дело доходит до двусторонней привязки данных Vue, первое, о чем мы можем подумать, это ES5.Object.defineProperty
, используя переопределенные свойстваget
,set
, мы можем завершить мониторинг захвата данных, использовать режим наблюдателя и уведомлять подписчиков об обновлении статуса при изменении данных.
мы стремимся кObserver
Часть наблюдателя написала простой код следующим образом:
function Observer (data) {
this.data = data
this.walk(data)
}
Observer.prototype = {
walk: function (data) {
let me = this
Object.keys(data).forEach(function (key) {
me.convert(key, data[key])
})
},
convert: function (key, val) {
this.defineReactive(this.data, key, val)
},
defineReactive: function (data, key, val) {
let dep = new Dep()
let childObj = observe()
Object.defineProperty(data, key, {
enumerable: true,
configurable: false,
get: function () {
if (Dep.target) {
dep.depend() // 添加订阅者
}
return val
},
set: function (newVal) {
if (newVal === val) return
val = newVal
childObj = observe(newVal)
dep.notify() // 通知订阅器
}
})
}
}
function observe (value, vm) {
if (!value || typeof value !== 'object') {
return
}
return new Observer(value)
}
В приведенном выше коде мы определяемObserver
Конструктор, наблюдатель. использоватьObject.defineProperty
Мониторинг данных будем производить по всем атрибутам (в т.ч. субатрибутам) входящего объекта, а вget
метод, добавьте подписку на подписчика. Как только свойство изменится, уведомите подписчиков.
Код подписчика Dep, инструкции Compile и подписчика Watcher больше не анализируется, общую структуру mvvm можно увидеть на следующем рисунке.
Весь процесс состоит из четырех частей: наблюдатель, подписчик, подписчик и командир, каждая из которых выполняет свои обязанности.Краткое введение в прокси
Прокси — это недавно добавленный конструктор в ES6. Его можно понимать как настройку уровня «перехвата» перед целевым объектом. Весь доступ к объекту из внешнего мира должен проходить через этот уровень перехвата. Поэтому он предоставляет механизм для доступа к перезаписи фильтра. Первоначальное значение Proxy — прокси, и здесь мы можем понимать его как «прокси» для некоторых операций.
var obj = new Proxy({}, {
get: function (target, key, receiver) {
console.log(`proxy get ${key}`)
return Reflect.get(target, key, receiver)
},
set: function (target, key, value, receiver) {
console.log(`proxy set ${key}`)
return Reflect.set(target, key, value, receiver)
}
})
Приведенный выше код устанавливает уровень перехвата пустого объекта, мы можем передать второй параметр Proxy.handler
Объект, в котором можно определить поведение перехвата.
существуетget
а такжеset
, мы использовалиReflect
.Reflect
объект сProxy
Как и объекты, это также новый API, предоставляемый ES6 для управления объектами.Reflect
методы объекта иProxy
Методы объекта соответствуют взаимно однозначному, напримерProxy
перехват методаtarget
Поведение присвоения свойств объектам. он принимаетReflect.set
Методы присваивают значения свойствам объекта, гарантируя, что исходное поведение выполняется до развертывания дополнительных функций.
По приведенному выше коду пишем тестовый код:
obj.text = 'hello world!'
// proxy set text
var _text = obj.text
// proxy get text
Наблюдатель переопределения прокси
Используя вышеизложенноеProxy
Некоторые особенности, модифицируем код следующим образом:
function observe (value, vm) {
if (!value || typeof value !== 'object') {
return
}
let dep = new Dep()
return new Proxy(value, {
get: function (target, key, receiver) {
if (Dep.target) {
dep.depend()
}
return Reflect.get(target, key, receiver)
},
set: function (target, key, value, receiver) {
dep.notify()
return Reflect.set(target, key, value, receiver)
}
})
}
Мы заменяем входящий объект напрямую наProxy
объект, вводhandler
изget
а такжеset
Логика добавления подписчика и подписчика уведомлений остается прежней.
Никаких других избыточных суждений не было сделано в течение всего процесса.Поскольку Vue3.0 еще не выпущен, нет фактического исходного кода для справки, поэтому вышеизложенное является просто простой версией личной реализации (полный код). Примените весь mvvm к html, после запуска будет следующий эффект (без gif, просто сделайте его):
Преимущества переопределения механизма мониторинга данных
- сдаться
Object.defineProperty
, основанный на механизме прокси-наблюдателя для полного охвата языков и повышения производительности. Благодаря изменениям оптимизации других методов vue3.0 может удвоить скорость/половину использовать память; -
Observer
Модули будут доступны по отдельности в виде библиотеки.
возможные проблемы
К сожалению, ES6Proxy
Невозможно перенести в ES5, поэтому он не будет поддерживаться IE. Для этой проблемы Vue3.0 даст совместимое решение для IE11, то есть под IE11 все еще используетсяObject.defineProperty
механизм.
использованная литература
Начало работы с ECMAScript 6 (Ифэн Жуань):es6.ruanyifeng.com/#docs/proxy
План обновления vue 3.0: быстрее, меньше, проще для разработчиков:Woohoo.OSCHINA.net/news/101906…
Почему Proxy может оптимизировать механизм мониторинга данных vue:nuggets.capable/post/684490…