Продвинутый взгляд с Ю Юси

Vue.js

Над картинкой нет картинки, нет правды

vue

Я купил его за 400 океановfrontedmastersЧленство на один месяц - это просто посмотреть учебник Vue о боге-мужчине, китайских субтитров нет, и я мучительно настаиваю на том, чтобы закончить его.. Людям с деньгами и хорошим английским рекомендуется купить членство напрямую и перейти к официальному сайт, чтобы посмотреть видео, особенно боги красавцы, Уровень бизнеса высокий, а английский супер-так. Недостаток английских пыток в том, что мой уровень письма и бизнеса действительно ограничен. Я не могу вести разбор принципа и выполнение кода шаг за шагом.Я могу только вставить код и объяснить его в меру своих возможностей.Насколько я могу понять зависит от каждого.Уровень,это не считается недобросовестными торговцами,не включить послепродажное обслуживание, ха-ха.

Эта серия статей познакомит вас со следующими аспектами vue.

  1. реактивность (отзывчивость)
  2. плагин (плагин)
  3. рендеринг (функция рендеринга)
  4. маршрутизация
  5. государственное управление
  6. международный (многоязычная поддержка)

1 reactivity

Я полагаю, что студенты, знакомые с vue, знают, что vue — это инфраструктура MVVM.Самая большая особенность — двусторонняя привязка данных.После изменения модели данных представление представления будет автоматически обновлено, и представление также может синхронизировать изменения модель представления в модель через v-model.

Вопрос, который предстоит обсудить в этой статье: как меняются данные vue monitor для автоматического обновления представления, то есть как реализована отзывчивость vue, давайте рассмотрим это пошагово.

1.1. getter and setter

Рассмотрим следующий код, вычисляющий простое алгебраическое соотношение, b зависит от a, b от 10-кратного

    var a= 10;
    var b = a*10;
    a = 20
    //b = ? 如何监听b的变化

Пожалуйста, подумайте об этом внимательно, а затем посмотрите вниз: когда значение a меняется каждый раз, как отслеживать изменение a и обновлять b, чтобы гарантировать, что их математическое соотношение b в 10 раз больше, чем a?









Я оставил пустых строк для всех 10. Интересно, вы серьезно думали над вышеуказанными вопросами?

Давайте не продавать, мы можем напрямую использовать два значения, мы не можем это отслеживать в настоящее время, мы можем изменить образ мышления, напрямую контролировать числовую переменную не получится, мы можемОтслеживайте изменения свойств объекта, собирайте его зависимости при изменении свойств, а затем инициируйте обновление зависимостей.

js имеет метод Object.defineProperty, который может перехватить геттер и сеттер чтения свойства, давайте посмотрим на пример

  let obj = {
        a:10
    };
    observer(obj, 'a');
    obj.a = 20;
    let b = obj.a;
    obj.a = 30;
    // 实现一个函数,可以监控到对象属性的变化
    function observer(obj, key) {
        Object.defineProperty(obj, key, {
            configurable: true, // 可以被delete
            enumerable: true, // for in迭代
            set(val) {
                console.log(`对象的属性${key}被赋值了${val}`);
            },
            get() {
                console.log(`对象的属性${key}被读取了`);
            }
        });
    }
    //对象的属性a被赋值了20
    //对象的属性a被读取了
    //对象的属性a被赋值了30

Как видно из приведенного выше примера, мы используем только переопределение свойств объекта. Object.defineProperty геттер и сеттер читатель может изменить контролируемое свойство объекта, приведенный выше код может отслеживать только изменение атрибута, все свойства для объектов необходимы чтобы пройти преобразование, преобразовать какой метод наблюдателя (здесь рассмотрим только одну цель, глубоко укоренившуюся потребность в рекурсивном обходе, для мониторинга массивов также необходимо написать другой метод, заинтересованный в просмотре исходного кода vue)

 function observer(obj) {
        Object.keys(obj).forEach(key => {
            let internalValue = obj[key]
            Object.defineProperty(obj, key, {
                get() {
                    console.log(`getting key "${key}": ${internalValue}`)
                    return internalValue
                },
                set(newVal) {
                    console.log(`setting key "${key}" to: ${internalValue}`)
                    internalValue = newVal
                }
            })
        })
    }

Теперь, когда мы можем отслеживать изменения всех атрибутов объекта, половина проблемы, поднятой в начале, решена.Следующая проблема, которую необходимо решить, — как собрать его зависимости и запустить обновление зависимостей при изменении атрибутов? Это тема нашей статьи, как реализовать простую отзывчивую систему.

Идея такова: собирать зависимости при чтении свойств и запускать обновления зависимостей при изменении значений свойств.

  1. Реализовать наблюдатель, перехватывающий геттеры и сеттеры свойств объекта.
  2. Реализовать глобальную Dep-подписку, которая может добавлять подписчиков и уведомлять об обновлениях зависимостей.
  3. Добавлять текущую зависимость к Dep при чтении свойств и циклически запускать обновления зависимостей при установке свойств.

В соответствии с этой идеей практикуйте простую отзывчивую систему.

   // 全局的依赖收集器Dep
   window.Dep = class Dep {
       constructor() {
           this.subscribers = new Set(); // 保证依赖不重复添加
       }
       // 追加订阅者
       depend() {
           if(activeUpdate) { // activeUpdate注册为订阅者
               this.subscribers.add(activeUpdate)
           }

       }
       // 运行所有的订阅者更新方法
       notify() {
           this.subscribers.forEach(sub => {
              sub();
          })
       }
   }
   let activeUpdate
   // js单线程语言,任一时刻只能有一个函数执行,也就是任一时刻,只可能有一个依赖在更新 //用一个全局变量activeUpdate来标志,这里有点不好理解,大家多想想就会明白autorun的巧妙之处了
   // autorun接受一个更新函数
   function autorun(update) {
       function wrapperUpdate() {
           activeUpdate = wrapperUpdate
           update() // wrapperUpdate, 闭包
           activeUpdate = null;
       }
       wrapperUpdate();
   }
   function observer(obj) {
       Object.keys(obj).forEach(key => {
           var dep = new Dep(); // 为每个key创建订阅器Dep
           let internalValue = obj[key]
           Object.defineProperty(obj, key, {
               get() {
                   // console.log(`getting key "${key}": ${internalValue}`)
                   // 将当前正在运行的更新函数追加进订阅者列表
                   if(activeUpdate) { 
                       dep.depend() //收集依赖
                   }
                   return internalValue
               },
               set(newVal) {
               	//console.log(`setting key "${key}" to: ${internalValue}`)
               	// 加个if判断,数据发生变化再触发更新
               	if(internalValue !== newVal) {
               	       internalValue = newVal
                       dep.notify() // 触发依赖的更新
               	}
               }
           })
       })
   }
   let state = {
       count:0
   }
   observer(state);
   autorun(() => {
       console.log('state.count发生变化了', state.count)
   })
   state.count = state.count + 5;
   // state.count发生变化了 0
   // state.count发生变化了 5

Эта статья будет обновлена ​​здесь первыми, и последующий контент будет успеть продолжать обновлять. Хотя время обновления является неопределенным, планируется обновить в конце месяца. Я надеюсь, что это друзья, которые любят это, Оплатите больше внимания и поддержки, спасибо.