Во время интервью ваших друзей волнует вопрос строительства ракет?
Я не хочу жаловаться, потому что я был вроде позволил интервьюеру сделал интервьюеру Rocket :)
Эта статья проанализирует причины этой ситуации из основной логики и выдвинут искренние предложения.
видеоурок
Сельский староста специально записал поддерживающее видео и повелел всем показать своеmini vue:
От рукописного Vue до анализа стратегии интервью
добро пожаловать друзьяТройной + подписка, Ваша поддержка - самая большая мотивация, которой я придерживаюсь.
Почему интервью делают ракеты
Поскольку соотношение между спросом и предложением на рынке изменилось, раньше это была Бритни, а теперь миссис Ню. Особенно младшие и средние фронтенды не похожи на случайные поиски работы 6 или 7 лет назад. Чем больше конкурентов, тем критичнее будет работодатель, и за те же деньги, конечно, будут отобраны более способные и мотивированные сотрудники. В то же время интервьюеры обнаружили, что резюме у всех одинаковое: умелое использование vue framework и familybucket, умелое использованиеelement-ui,iViewи другие библиотеки компонентов, квалифицированное использованиеaxiosПолучить данные сервера и т. д. В это время, если сложность интервью не увеличивается, трудно различить способности интервьюера.
Что мне делать, если у меня есть проблема ракеты?
Например, интервьюер спросил:
- Зачем нам нужно быстрое реагирование на данные?
vueКак это достигается? - Почему виртуальный
dom?diffКаков процесс?
Маленькие друзья решают найти ответ и запомнить его. Вы не можете решить проблему таким образом, потому что ответ, который вы запомнили, мертв, и он не выдерживает проверки. После нескольких вопросов он будет раскрыт.
Я думаю, что каждый должен воспользоваться этой возможностью, чтобы изучить исходный код не только для того, чтобы найти ответ на вопрос, углубить понимание API, но и изучить множество алгоритмов, шаблонов проектирования и инженерных знаний, что очень полезно. повысить уровень программирования.
Исходный код очень сложно научиться делать
Многие мелкие партнеры также хотят учиться, читая исходный код, но исходный код обычно очень большой и сложный, и их легко убедить уйти. Рекомендуется начать сminiреализация версии. Заложите сначала хороший фундамент, а потом уже переходить к исходникам после освоения будет намного проще.
построить ракету
Я возьмуVueНапример, напишитеminiВерсия, тогда мы рассмотрим сделанную ракетой задачу.
Философия дизайна Vue
Прежде чем мы начнем, давайте взглянем на концепцию дизайна Vue, чтобы ее было легче понять, когда она будет написана позже:
Простой для понимания, дружелюбный, хорошая производительность, простой в обслуживании, тестируемый
Почувствуй это в коде
не использовалVue, 01-no-vue.html:
<div id="app"></div>
<script>
// 需求:
// 1.有个title标题,想要显示在h3标签中
// 2.2秒后title会变化
const title = '我就是个标题'
const h3 = document.createElement('h3')
h3.textContent = title
app.appendChild(h3)
setTimeout(() => {
h3.textContent = '我还是那个标题,但我变了'
}, 2000);
</script>
Особенность:
- Пользователь должен напрямую связаться с dom
- dom операции также являются частью бизнеса
- Умственная нагрузка пользователя тяжелее, а эффективность разработки низкая.
использоватьVue, 02-с-vue.html:
<div id="app">
<h3>{{title}}</h3>
</div>
<script src="http://unpkg.com/vue"></script>
<script>
// 需求:
// 1.有个title标题,想要显示在h3标签中
// 2.2秒后title会变化
new Vue({
data() {
return {
title: '我就是个标题'
}
},
mounted() {
setTimeout(() => {
this.title = '我还是那个标题,但我变了'
}, 2000);
},
}).$mount('#app')
</script>
Важным изменением является то, что наше приложение управляется данными и позволяет избежать манипуляций с DOM, поэтому наша цель ясна:
- Чтобы быть в курсе изменений данных
- Возможность выполнять обновления просмотра после изменений
Построить колесо
Базовая структура:Vueконструктор и$mountметод
<div id="app"></div>
<script>
function Vue(options) {}
Vue.prototype.$mount = function() {}
</script>
использоватьdefinePropertyРеализуйте реакцию на данные, мониторингdataизменение данных
function Vue(options) {
// 响应式
this.$options = options
this.$data = options.data()
observe(this.$data)
}
Vue.prototype.$mount = function () {}
// 遍历obj所有key做响应式处理
function observe(obj) {
Object.keys(obj).forEach(key => {
defineReactive(obj, key, obj[key])
})
}
// 所谓响应式就是拦截对象属性访问
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() { return val },
set(newVal) { val = newVal }
}
})
}
Mount: подготовьте функцию обновления, отвечающую за инициализацию представления и последующие обновления.
<script>
Vue.prototype.$mount = function (sel) {
// 创建更新函数
this.update = function () {
const child = this.$options.render.call(this)
const parent = document.querySelector(sel)
if (!this.isMounted) {
// init
parent.appendChild(child)
this.isMounted = true
if (this.$options.mounted) {
this.$options.mounted.call(this)
}
} else {
// update
parent.innerHTML = ''
parent.appendChild(child)
}
}
this.update()
}
function observe(obj) {}
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {},
set(newVal) {
if (newVal !== val) {
// 触发更新
app.update();
}
}
})
}
</script>
<script>
const app = new Vue({
// 添加render函数负责渲染dom
render() {
const h3 = document.createElement('h3')
h3.textContent = this.$data.title
return h3
}
})
</script>
Проблема: каждое обновление — это полное обновление представления
на основеvnodeРеализовано, чтобы избежать полного обновления
<script>
Vue.prototype.$mount = function (sel) {
this.update = function () {
// 执行render获取vnode
const vnode = this.$options.render.call(this, this.createElement)
if (!this.isMounted) {
// init patch:传入parent是dom
const parent = document.querySelector(sel)
this.patch(parent, vnode)
} else {
// update patch:传入两个vnode做diff
this.patch(this._vnode, vnode)
}
this._vnode = vnode
}
this.update()
}
// 加一个vnode生成函数
Vue.prototype.createElement = function (tag, props, children) {
return { tag, props, children }
}
// patch用于初始化或更新时转换vnode为dom
Vue.prototype.patch = function (n1, n2) {
if (n1.nodeType) {
// init
const child = this.createElm(n2)
n1.appendChild(child)
n2.$el = child
} else {
// update
}
}
// 递归创建元素
Vue.prototype.createElm = function (vnode) {
const {tag, props, children} = vnode
const el = document.createElement(tag)
// 创建children
if (Array.isArray(children)) {
// element
children.forEach(child => el.appendChild(createElm(children)))
} else {
// text
el.textContent = children
}
vnode.$el = el
return el
}
</script>
<script>
const app = new Vue({
// render返回vnode
render(h) {
return h('h3', null, this.$data.title)
}
})
app.$mount('#app')
</script>
Логика обновления: в основном смотрите на типы дочерних элементов с обеих сторон и целенаправленно выполняйте операции DOM.Здесь решается только текст в тестовом примере.
Vue.prototype.patch = function (n1, n2) { if (n1.nodeType) {} else { // 获取待操作dom const el = n2.$el = n1.$el // children更新 if (n1.tag === n2.tag) { // 是否相同节点,节点复用 if (typeof n1.children === 'string') { if (typeof n2.children === 'string') { // text update if (n1.children !== n2.children) { el.textContent = n2.children } } else { // replace text with elements } } else { if (typeof n2.children === 'string') { // replace elements with text } else { // update children } } } else { // replace } }
Прийти, чтобы подумать о стратегии ответа
可使用四段体:介绍概念,说必要性,源码如何实现,实践中如何使用。 Например:
-
Зачем нам нужно быстрое реагирование на данные? Как это сделать?
Введение в концепцию: Реагирование на данные — это механизм обнаружения изменений данных в таких фреймворках, как MVVM, и эти три фреймворка различны (используйте его, если знаете).
Необходимость: наиболее важной задачей MVVM является обеспечение управления данными.Для достижения управления данными необходимо знать, когда данные изменяются, и реагировать соответствующим образом, что требует механизма реагирования на данные.
Реализация исходного кода: defineProperty в основном используется в vue 2.x, а Proxy в основном используется в vue 3.x (не упоминайте, если не знаете). Возьмем в качестве примера vue 2.x: обходя свойства объекта, определяя get/set и выполняя перехват свойств, можно обнаружить будущие изменения данных и вызвать функцию обновления для обновления представления.
В сочетании с практикой: на практике реквизиты свойств, методы и данные данных, которые мы передаем в компонент, будут единообразно обрабатываться при инициализации Vue, поэтому при их изменении представление будет повторно отображаться и обновляться. Есть также некоторые особые случаи, такие как добавление или удаление новых свойств, вам необходимо использовать API, такие как Vue.set/delete.
Конечно же, маленьким друзьям предстоит и дальше узнавать множество деталей, таких как:
- Как уведомить об обновлении представления (сбор зависимостей, асинхронное обновление и другие точки знаний)
- Как обновляется представление (виртуальный дом и патч)
- Что не так с отзывчивостью в vue 2.x (эффективность, дополнительный API, обработка массивов и т.д.)
- Зачем вам нужны такие API, как Vue.set/delete
Вы можете видеть, что все это выведено из точки отзывчивости Если ответ правильный, он в основном правильный.
Пример исходного кода
Обратите внимание на общественный номер»村长学前端"
видеоурок
Сельский староста специально записал поддерживающее видео и повелел всем показать своеmini vue:
От рукописного Vue до анализа стратегии интервью
добро пожаловать друзьяТройной + подписка, ваша поддержка - самая большая мотивация для меня продолжать ❤️