文章目录
青训营实战班的课程也结束了,今天先来撸一遍周五杨村长带来的mini-vue课程。错过课程的小伙伴一定不要错过这篇超级详细且稍微拓展的笔记哟~
相关代码可以看我的gitee仓库
关于Vue3的一些内容,可以看我之前博文 带你快速上手Vue3
一、前端框架设计理念
1. 用Vue来举例
-
简单、易上手
-
数据驱动
- 减少DOM操作
- data-driven
- 数据响应式(reactive、effect)
- 声明式渲染、render
- vdom
- patch
-
渐进式progressive(min、vuex、router、element3)
2. Vue3的动机
- (类型支持)为什么用函数的方式?
-
函数:vue3,react
-
class: Angular, vue2(decorator)
函数签名比较明确,这样输入输出的内容就比较明确
- Composition API 的优势
- 消灭
this
- 声明响应式数据
- 复用性、可读性、可维护性
<div id="app">{
{title}}</div>
<script src="http://unpkg.com/vue@next"></script>
<script>
const app = Vue.createApp({
data() {
return {
title: 'vue3, YK菌, data'
}
},
setup() {
// Composition API 的优势
// 消灭this
// 声明响应式数据
// 复用性、可读性、可维护性
const state = Vue.reactive({
title: 'vue3, YK菌, setup'
})
return state
}
})
app.mount('#app')
</script>
结果可以看到 setup
的优先级更高
3. 小结
- 类型支持
- 实例方法和属性 tree-shaking
- 复用性
hook
- 维护性
Composition API
- API简化
- 一致性(指令中的生命周期 和 组件的生命周期 不同)
- 删除相同功能的API(
v-model
、.sync
(Vue3弃))
<comp v-model="foo"></comp> <comp :foo.sync="foo"></comp> <comp :value="foo" @update:value="foo = $event"></comp>
- render
// Vue2 写法 render(h){ return h('div', { attrs: { title: this.title } }, 'xxx') } // Vue3 写法 render(){ return Vue.h('div', { title: this.title }, 'xxx') }
- 拓展性:自定义渲染器
Vue.createRenderer()
- 性能优化——响应式基于
Proxy
- 递归效率问题
- 数组问题(单独一套实现)
- API影响(动态属性新增删除
Vue.delete
/set
) - 不支持 class collection 数据结构
- 兼容性(vue2.7)
二、实现 mini-vue
直接读源码还是一件很难下手的事情,新手经常分不清重点,容易在一些边边角角的地方遇到阻碍,浪费很多时间,所以今天我们来写的mini-vue只关注最核心的部分
1. 初始化
<div id="app">{
{title}}</div>
<script>
// 待填充代码
</script>
<script>
const app = Vue.createApp({
data() {
return {
title: 'hello, vue3 YK菌'
}
}
})
app.mount('#app')
</script>
① 基本结构
const Vue = {
createApp(options) {
// 返回app对象
return {
mount(selector) {
// 待填充代码 [如何挂载]
}
}
}
}
② 如何挂载元素
我们应该想的是 Vue 的 mount
做了哪些事情?
- 找到宿主元素
- 渲染页面
- 处理
template
:使用compile
编译 - 用户直接编写
render
- 处理
- 追加到宿主
根据上面的思路,我们来编写代码
// 1. 基本结构
const Vue = {
createApp(options) {
// 返回app对象
return {
mount(selector) {
// 1. 找到宿主元素
const parent = document.querySelector(selector)
// 2. 渲染页面
if (!options.render) {
// 2.1 处理template: 编译
options.render = this.compile(parent.innerHTML)
}
// 2.2 用户直接编写render
// 执行render函数(这里指定render函数