vue
基础知识
原理
Vue2.0/3.0 双向数据绑定原理
各自的好处,到掘金上面寻找一些文章。
Vue2.0 使用 ES5 方法:defineProperty
数据劫持
Object.defineProperty(obj, 'key', { get() {}, set() {}, });
Vue3.0 使用 ES6 方法:Proxy
let obj = {};
obj = new Proxy(obj, { get(target, prop) {}, set(target, prop, value) {} });
vue-router
vuex
单元测试
服务器渲染
组件库
- vdom
- 模板渲染
组件化 响应式 vdom 和 diff 模板编译 渲染过程 前端路由
重点:整体流程是否全面,热门技术是否有深度。
关于 vue 的一些问题
- v-for 为什么要使用 key? 答:diff 算法通过 tag 和 key,来判断是否是相同的 node。目的是为了减少渲染次数,提高渲染性能。
组件化
引入一个组件,传入相关信息。
如何理解 MVVM 模型?
数据驱动视图。 只需要修改数据,框架就会根据数据的变化更新视图。
M = Modul V = View VM = ViewModul
View <=> ViewModul <=> Modul
Vue3.0 - Proxy
3.0:使用 Proxy 实现数据响应式。
2.0:使用 defineProperty 实现数据响应式。
Object.defineProperty 的缺点
- 深度监听需要一次性递归,有性能瓶颈。
- 无法监听新增属性和删除属性,需要使用 Vue.set 等方法。
- 无法原生监听数组,需要特殊处理。
Proxy 基本使用
new Proxy(data, {
get(target, key, receiver) {
const result = Reflect.get(target, key, receiver);
return result;
},
set(target, key, val, receiver) {
const result = Reflect.set(target, key, val, receiver);
return result;
},
deleteProperty(target, key) {
const result = Reflect.deleteProperty(target, key);
return result;
}
})
2
3
4
5
6
7
8
9
10
11
12
13
14
虚拟 DOM(Virtual DOM)
问:什么是 vdom? 答:vdom 是真实 DOM 的一种映射。使用 JS 模拟出来的一种 DOM 结构。
问:vdom 有什么用? 目的是为了提高性能。DOM 操作本身非常耗费性能,JS 本身运行却很快,为了减少复杂度,减少性能消耗,所以使用 JS 模拟 DOM 结构,先计算出最小变更,再操作 DOM。
用 JS 模拟 DOM 结构
<div id="root">
<h1 class="title">title name</h1>
<ul class="list">
<li class="list-item">item</li>
</ul>
</div>
2
3
4
5
6
const vdom = {
tag: 'div',
props: {
id: 'root'
},
children: [
{
tag: 'h1',
props: {
className: 'title',
},
children: 'title name'
},
{
tag: 'ul',
props: {
className: 'list'
},
children: [
{
tag: 'li',
props: {
className: 'list-item'
},
children: 'item'
}
]
}
]
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
diff 算法
问:什么是 diff 算法? 答:diff 算法是 JS 对虚拟 DOM 对比的过程。
问:diff 算法有什么用? 答:通过这个算法,计算对比出 vdom 的最小变更。
问:diff 的比较规则是什么? 答: 1.只比较同一级别,不跨级比较。 2.同一级中 tag 不相同,则直接删除重建,不深度比较。 3.同一级中 tag 和 key,两者都相同,则认为是相同节点,不深度比较。
key 的作用
vue3
搭建项目
必备插件
- Vue3 + script setup + ts + Vite + Volar
- CSS 预处理器: sass
- PostCSS: autoprefixer、postcss-pxtorem
- amfe-flexible
目录结构
响应性 API
- reactive
- ref
- toRef
- toRefs
- shallowRef
reactive
返回对象的响应式副本。将解包所有深层的 refs
,同时维持 ref
的响应性。
ref
接受一个内部值并返回一个响应式且可变的 ref
对象,里面仅有一个 .value
property,指向该内部值。
toRef
可以用来为源响应式对象上的某个 property 新创建一个 ref
。然后,ref
可以被传递,它会保持对其源 property 的响应式连接。 当你要将 prop
的 ref
传递给复合函数时,toRef
很有用。
toRefs
将响应式对象转换为普通对象,其中结果对象的每个 property 都是指向原始对象相应 property 的 ref
。
shallowRef
创建一个跟踪自身 .value
变化的 ref 但不会使其值也变成响应式的。
用法
ref
通常用来处理简单的基本类型数据,返回一个响应式 Ref 对象。reactive
用来定义更加复杂的数据类型,但是定义后里面的变量取出来就不再是响应式 Ref 对象,所以需要使用toRefs
转化为响应式 Ref 对象。
如果只修改引用类型的一个属性,推荐用reactive
;如果需要给变量重新赋值,推荐使用ref
。
toRef
将传入的props
其中一个属性转成响应式toRefs
将传入的props
所有属性转成响应式
组合式 API
- setup
- 生命周期钩子
- Provide / Inject
把同一功能的代码放到一起维护,也可以抽离到一个组建中。
teleport
v-model
小技巧
列表渲染
你可以用 of 替代 in 作为分隔符,因为它更接近 JavaScript 迭代器的语法:
<div v-for="item of items"></div>
还可以用第三个参数作为索引:
<li v-for="(value, name, index) in myObject">
{{ index }}. {{ name }}: {{ value }}
</li>
2
3
key
使用 key 强制替换元素或组件,而不是重复使用它,达到一些特别的目的。
比如:
- 完整地触发组件的生命周期钩子
- 触发过渡
<transition>
<span :key="text">{{ text }}</span>
</transition>
2
3
当 text
发生改变时,<span>
总是会被替换而不是被修改,因此会触发过渡。
ref
ref
为我们的值创建了一个响应式引用。在整个组合式 API 中会经常使用引用的概念。
import { ref } from 'vue'
const counter = ref(0)
console.log(counter) // { value: 0 }
console.log(counter.value) // 0
counter.value++
console.log(counter.value) // 1
2
3
4
5
6
7
8
9
Provide / Inject
Proxy
Vue Class Component
Vue Class Componentopen in new window
使用技巧
defineComponent
可以创建一个自定义组件。
可以创建一个只有在需要时才会加载的异步组件。
import { defineComponent } from 'vue'
export default defineComponent({
props: {},
created() {
console.log('defineComponent')
},
setup() {
return {}
},
})
2
3
4
5
6
7
8
9
10
setup 中使用 emit
setup(props, context) {
function handle() {
context.emit('change', 123)
}
}
2
3
4
5