Vue 是个声明式的框架
- 声明式:告诉 Vue 如何渲染,而不是告诉 Vue 如何去做,声明式框架更关注结果。
- 命令式:如 Jquery,每一行都可以明确的知道干嘛了,命令式更加关注过程
- 响应式:数据发生变化,视图也会跟着变化。
- 虚拟 DOM,通过 JavaScript 对象来描述 UI,其实就是虚拟 DOM
const vnode = {
tag: 'div',
props: {
id: 'app',
class: 'container',
onClick: () => {
console.log('clicked')
}
},
children: [
{
tag: 'p',
text: 'Hello, Vue!'
}
]
}
渲染器
- 渲染器是 Vue 的核心,它负责将虚拟 DOM 渲染成真实 DOM。
- 渲染器是一个函数,它接受一个虚拟 DOM 对象作为参数,创建、更新、删除真实 DOM 对象。
const renderer = (vnode, container) => {
const el = document.createElement(vnode.tag)
for (const key in vnode.props) {
if (/^on/.test(key)) {
el.addEventListener(key.substr(2).toLowerCase(), vnode.props[key])
} else {
el.setAttribute(key, vnode.props[key])
}
}
if (typeof vnode.children === 'string') {
el.textContent = vnode.children
} else if (Array.isArray(vnode.children)) {
vnode.children.forEach((child) => renderer(child, el))
}
container.appendChild(el)
}
- 组件、对象渲染(渲染一个组件、对象)
- Vue 单独状态的组件就是对象格式创建的
const Component = () => {
return {
div: 'div',
props: {
id: 'app',
class: 'container',
onClick: () => {
console.log('clicked')
}
},
children: 'hello world'
}
}
const obj = {
render: () => {
div: 'div',
props: {
id: 'app',
class: 'container',
onClick: () => {
console.log('clicked')
}
},
children: 'hello world'
}
}
const vnode = {
tag: Component || obj
}
const rendererComponent = (vnode, container) => {
if (typeof vnode.tag === 'function') {
const component = vnode.tag()
renderer(component, container)
} else if (typeof vnode.tag === 'object') {
const component = vnode.tag.render()
renderer(component, container)
} else {
renderer(vnode, container)
}
}
编译器
- 编译器是 Vue 的另一个核心,它负责将模板字符串编译成虚拟 DOM 对象。
- 编译器是一个函数,它接受一个模板字符串作为参数,返回一个虚拟 DOM 对象。
<template>
<div id="app">
<p>{{ message }}</p>
</div>
</template>
// 把上面的模板最终渲染成这样, 这就是编译器的作用
<script>
export default {
data() {
return {
message: 'Hello, Vue!'
}
},
render() {
return h('div', { id: 'app' }, h('p', {}, this.message))
}
}
</script>
组合器(.vue 文件渲染到页面上)
- vue 文件 编译成 js 文件(编译器)
- js 文件 执行 render 函数编译(渲染器)生成虚拟 DOM 节点。
- 虚拟 DOM 被转换成实际的 DOM,并插入到页面中。Vue 通过 diff 算法优化这个过程,只更新有变化的部分。