前言
UI造轮子Vue2版官网初步部署上线了,决定暂时告一段落,先学习Vue3的造轮子课。这个阶段的学习总结以Vue3新特性为主,以及这其中踩到的坑,节奏依然是写轮子–>看文档–>写总结,然后会将Vue3的学习笔记做一个整体的总结。加油~(ง •_•)ง
效果预览

API设计
value
- 组件内部,用
value控制开关的开与关 —computed计算属性控制开关状态的样式 value应该是由父组件传入 — 父组件用ref声明变量,子组件用props接受值(父子通信)- 当父组件调用该子组件时,应该知道当前子组件的状态 —
v-model实现父子双向绑定
disable loading
- disable 禁用属性,loading,加载状态,处在该状态下开关无法进行操作
- 样式类型的属性,因此也是使用
computed计算属性控制样式
Vue3笔记
组件注册
Vue2.x
1 | new Vue({ |
Vue3.x
1 | import { createApp } from 'vue' |
Composition API(组合式API)
为什么
总结一下就是:避免逻辑关注点过于碎片化,提高代码的可读性和可维护性。
在Vue2中,我们如果要实现一个需求,那么这些逻辑会被分散在data、methods、computed等各个Options API,而在Vue3中,我们可以将同一个需求的各个逻辑模块整合起来,放在Composition API。如果用颜色来区分各个逻辑块,那么下图可以直观地展示这种区别。

setup
一个接受
props和context的函数,从setup返回的内容都将暴露给组件的其余部分- props: 传入组件的属性:setup 中接收的
props是响应式的, 当传入新的 props 时,会及时被更新。由于是响应式的, 所以不可以使用 ES6 解构,解构会消除它的响应式 - context:暴露
attrs、slots、emit这三个组件的property
- props: 传入组件的属性:setup 中接收的
在创建组件之前,初始化 props 之后调用执行,因此
setup中无法访问组件实例this1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16beforeCreate() {
console.log('beforeCreate');
},
created() {
console.log('created');
},
mounted() {
console.log('mounted');
},
setup (props, context) {
console.log('setup');
}
// setup
// beforeCreate
// created
// mounted我刚开始使用
setup的时候,也产生过疑惑,这样不是将所有的代码都塞到setup里面,让它变得非常庞大臃肿吗?官方文档给出了解决方案——将各逻辑模块分别提取到独立的组合式函数
带ref 的响应式变量 (响应式引用)
在setup中直接声明的变量是非响应式的,因此需引入
ref函数ref接受参数并返回一个包装对象,包装对象具有valueproperty ,可使用该 property 访问或更改响应式变量的值:1
2
3
4
5
6
7
8
9
10import { ref } form 'vue'
export default {
const visible = ref(false)
console.log(visible) // { value: false }
console.log(visible.value) // false
visible.value = true
console.log(visible.value) // true
}-
提供一个让我们能够在函数之间以引用的方式传递任意类型值的容器。这个容器可以在封装了逻辑的组合函数中将状态以引用的方式传回给组件。组件负责展示(追踪依赖),组合函数负责管理状态(触发更新)
1
2
3
4
5
6
7
8
9
10
11
12setup() {
const valueA = useLogicA() // valueA 可能被 useLogicA() 内部的代码修改从而触发更新
const valueB = useLogicB()
return {
valueA,
valueB
}
}
// 作者:摸鱼架构师
// 链接:https://juejin.cn/post/6844904042242523144
// 来源:掘金
toRefs
解构的同时保持props内部变量的响应式
1 | import { toRefs } from 'vue' |
computed属性
使用从 Vue 导入的
computed函数在 Vue 组件外部创建计算属性1
2
3
4
5
6
7
8import { ref, computed } from 'vue'
const counter = ref(0)
const twiceTheCounter = computed(() => counter.value * 2)
counter.value++
console.log(counter.value) // 1
console.log(twiceTheCounter.value) // 2computed函数返回一个只读的响应式引用,由一个作为computed的第一个参数传递的 getter 类回调输出。为了访问新创建的计算变量的 value,我们需要像使用ref一样使用.valueproperty。
v-model
使用:value和@input进行父子组件双向通信
其实v-model就是一个语法糖,我们可以先拆解出来它具体做了什么,以switch组件为例:

父组件:
1 | <x-switch :value="checked" @input="visible = $event"></x-switch> |
子组件:
1 | import { ref } from 'vue' |
Vue2的v-model
Vue2.x中,在组件上使用
v-model相当于绑定valueprop 和input事件1
2
3
4
5<x-switch v-model="checked" />
<!-- 简写: -->
<x-switch :value="checked" @input="checked = $event" />如果想更改绑定的属性名,或绑定多个变量,可使用
.sync子组件:
1
this.$emit('update:value', newValue)
父组件:
1
<x-switch :value.sync="checked" />
Vue3的v-model
- 属性名任意,假设为 x
- 事件名必须为
'update:x'
1 | <x-switch v-model:value="checked" /> |
总结
- 使用 ref 创建内部数据
- 使用 :value 和 @input 让父子组件进行交流(组件通信)
- 使用 v-model
- Vue 2 和 Vue 3 的区别
- 新
v-model:prop代替以前的v-model和.sync - 新增 context.emit,与 this.$emit 作用相同
- 新