предисловие
предыдущий постVue1.x рукописной серии VueПозвольте вам реализовать основные принципы Vue1 с нуля, включая следующие функции:
-
Перехват данных
-
нормальный объект
-
множество
-
-
Обновление с учетом данных
-
Коллекция зависимостей
-
Dep
-
Watcher
-
-
переводчик
-
текстовый узел
-
v-on:click
-
v-bind
-
v-model
-
-
В конце также подробно объясняется рождение Vue1 и существующие проблемы: Vue1.x будет хорошо работать в системах малого и среднего размера, а узлы DOM можно целенаправленно обновлять, но в крупномасштабных системах этого недостаточно. много Наблюдателей, что приводит к чрезмерному использованию ресурсов и снижению производительности. Таким образом, Vue2 решает эту проблему, вводя VNode и Diff.
Итак, следующая серия контента должна обновить предыдущую статью.lyn-vueframework, обновите его с Vue1 до Vue2. Поэтому рекомендуется читать и учить по порядку во всей серии.Если читать насильно, то можно почувствовать себя туманом в облаках, и при половинных усилиях вы получите вдвое больший результат.
Также добро пожаловатьСледуй, любимыйВ случае потери цикл статей будет включен вЗнание принципа исходного кода стека технологий VueКолонка, вы также можете обратить внимание на эту колонку.
Цель
Обновленная платформа должна запускать следующий пример кода
Пример
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Lyn Vue2.0</title>
</head>
<body>
<div id="app">
<h3>数据响应式更新 原理</h3>
<div>{{ t }}</div>
<div>{{ t1 }}</div>
<div>{{ arr }}</div>
<h3>methods + computed + 异步更新队列 原理</h3>
<div>
<p>{{ counter }}</p>
<div>{{ doubleCounter }}</div>
<div>{{ doubleCounter }}</div>
<div>{{ doubleCounter }}</div>
<button v-on:click="handleAdd"> Add </button>
<button v-on:click="handleMinus"> Minus </button>
</div>
<h3>v-bind</h3>
<span v-bind:title="title">右键审查元素查看我的 title 属性</span>
<h3>v-model 原理</h3>
<div>
<input type="text" v-model="inputVal" />
<div>{{ inputVal }}</div>
</div>
<div>
<input type="checkbox" v-model="isChecked" />
<div>{{ isChecked }}</div>
</div>
<div>
<select v-model="selectValue">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<div>{{ selectValue }}</div>
</div>
<h3>组件 原理</h3>
<comp></comp>
<h3>插槽 原理</h3>
<scope-slot></scope-slot>
<scope-slot>
<template v-slot:default="scopeSlot">
<div>{{ scopeSlot }}</div>
</template>
</scope-slot>
</div>
<script type="module">
import Vue from './src/index.js'
const ins = new Vue({
el: '#app',
data() {
return {
// 原始值和对象的响应式原理
t: 't value',
t1: {
tt1: 'tt1 value'
},
// 数组的响应式原理
arr: [1, 2, 3],
// 响应式更新
counter: 0,
// v-bind
title: "I am title",
// v-model
inputVal: 'test',
isChecked: true,
selectValue: 2,
}
},
// methods + 事件 + 数据响应式更新 原理
methods: {
handleAdd() {
this.counter++
},
handleMinus() {
this.counter--
}
},
// computed + 异步更新队列 的原理
computed: {
doubleCounter() {
console.log('evalute doubleCounter')
return this.counter * 2
}
},
// 组件
components: {
// 子组件
'comp': {
template: `
<div>
<p>{{ compCounter }}</p>
<p>{{ doubleCompCounter }}</p>
<p>{{ doubleCompCounter }}</p>
<p>{{ doubleCompCounter }}</p>
<button v-on:click="handleCompAdd"> comp add </button>
<button v-on:click="handleCompMinus"> comp minus </button>
</div>`,
data() {
return {
compCounter: 0
}
},
methods: {
handleCompAdd() {
this.compCounter++
},
handleCompMinus() {
this.compCounter--
}
},
computed: {
doubleCompCounter() {
console.log('evalute doubleCompCounter')
return this.compCounter * 2
}
}
},
// 插槽
'scope-slot': {
template: `
<div>
<slot name="default" v-bind:slotKey="slotKey">{{ slotKey }}</slot>
</div>
`,
data() {
return {
slotKey: 'scope slot content'
}
}
}
}
})
// 数据响应式拦截
setTimeout(() => {
console.log('********** 属性值为原始值时的 getter、setter ************')
console.log(ins.t)
ins.t = 'change t value'
console.log(ins.t)
}, 1000)
setTimeout(() => {
console.log('********** 属性的新值为对象的情况 ************')
ins.t = {
tt: 'tt value'
}
console.log(ins.t.tt)
}, 2000)
setTimeout(() => {
console.log('********** 验证对深层属性的 getter、setter 拦截 ************')
ins.t1.tt1 = 'change tt1 value'
console.log(ins.t1.tt1)
}, 3000)
setTimeout(() => {
console.log('********** 将值为对象的属性更新为原始值 ************')
console.log(ins.t1)
ins.t1 = 't1 value'
console.log(ins.t1)
}, 4000)
setTimeout(() => {
console.log('********** 数组操作方法的拦截 ************')
console.log(ins.arr)
ins.arr.push(4)
console.log(ins.arr)
}, 5000)
</script>
</body>
</html>
Точка знаний
Знания, задействованные в примере кода, включают:
-
Компилятор на основе разбора шаблона
-
Разберите шаблон, чтобы получить AST
-
Создание функции рендеринга на основе AST
-
render helper
-
_c, создайте VNode с указанной меткой
-
_v, VNode, создающий текстовый узел
-
_t, виртуальный узел, создавший узел слота
-
-
VNode
-
-
patch
-
Первоначальный рендеринг нативных меток и компонентов
-
v-model
-
v-bind
-
v-on
-
-
diff
-
-
Принцип слота
-
computed
-
Асинхронная очередь обновлений
Эффект
Окончательный эффект выполнения примера кода выглядит следующим образом:
иллюстрировать
Эта структура предназначена только для объяснения основных принципов Vue, и в ней нет никакой надежности.Возможно, вы можете сообщить об ошибках и не запуститься, если вы измените пример кода, но этого достаточно для обучения.В основном, основные принципы Vue (точка знаний) реализуются снова.
Итак, давайте начнем официальное обучение, давай! !
Сфокусируйся на
Приветствую всех, чтобы следовать за мнойСчет наггетса такжеСтанция Б, если контент полезен для вас, ставьте лайк, добавляйте в избранное + подписывайтесь