/这是跟着B站的学习笔记,也加入了学习过程中自己的理解。感谢up主的讲解 /
五大新特性:
- 新的单文件组件特性:
- Web Components
- 性能提升
- 服务端渲染
- Effect 作用域API
- setup语法糖 + TS + Volar === 真香
前置知识
- 因为学习VUE3.2需要有vue3.0的前置知识,所以在学习过程中,我会把涉及到的前缀知识补充在这里
-
Options API 和 Composition API 的区别
- 二者的比较
- Options API就是VUE2中那种把组件分成data、methods、props、各种生命周期这种一板一眼的方式,每个部分该写什么是很明确的,这样易于用户上手;但是一个组件过大以后,就会很麻烦,比如data里有很多数据,一个methods中可能包含20多个方法,你往往分不清哪个方法对应着哪个功能,难以区分每个数据要用在哪里,而且要去找对应的methods也很麻烦。
- Composition API 就是根据逻辑相关性组织代码的,所以所以在代码组织上就要多花点心思了。但能提高可读性和可维护性;而且其有更好的类型推断,对ts更友好。
- 使用场景:Vue3首推Composition API; 如果是中低复杂度的项目,可以用options API,如果是大型、高扩展、长期维护的项目就用Composition API。
-
运行时声明和类型声明
- 运行时声明:即运行后才能声明,一开始无法确定。如vue2中子组件使用props接收值,但是只有运行后才能知道接收到了啥
- 类型声明:ts的类型约束发生在编译的时候,这时还没有运行,所以可以先一步判断
- 比较:ts类型声明拥有更完美的类型检验。我要学ts
-
Compiler Macros(编译时宏命令)
- 宏(Macro),是一种批量批处理的称谓。一般说来,宏是一种规则或模式,或称语法替换 。解释器或编译器在遇到宏时会自动进行这一模式替换。
-
css module是啥?以前怎么没听过呀
-
css中的var函数
项目搭建
- 使用vite搭建项目
npm init vite@latest . -- --template vue-ts
(呜呜,太感人了,一个命令就把项目搭建起来了) npm run dev
运行项目(秒开,太顺滑了,呜呜,感谢祖师爷赏饭吃!)
setup 语法糖
基本用法:将setup写在script代码块上 <script setup lang="ts"></script>
- 优点:
- 写法更简洁
- 顶层绑定将自动暴露给模板,不需要return了
- 原理:将模板内容转化为虚拟node节点,放在了setup函数中,这样即使setup函数没有return数据出去,但是我把你拿进来是一样的呀!
山不向我走来,我就向山走去
- 原本是:需要手动写setup()函数的
<script lang="ts"> import { defineComponent, ref } from "vue" export default defineComponent({ setup() { const count = ref(1); const add = () => { count.value += 1 } // 这里用return,模板中才能进行使用 return { count, add } } })
- 现在:加一个标签就好了,里面的代码会被自动编译成setup()函数的内容
<script setup lang="ts"> import {ref} from 'vue' const count = ref(1); const add = () => { count.value += 1 } </script>
setup 语法糖下组件的使用
- 自动组件名推断:vue3中无法显式设置组件名,在命名缺省的情况下,vue3会自动根据文件名命名组件
- 普通组件的使用:在vue2中引入组件还需要注册后才能使用,vue3中引入即可使用
- 动态组件:还是用
- 递归组件:递归即自己使用自己,因为vue3会自动命名组件,所以如果遇到import引入的同名组件优先级更高,所以引入的同名组件要取别名哦:
import {Foo as newFoo} from './components'
- 命名空间组件: 即将多个组件写入同一个
导出组件
,然后在目标页面一次性引入该导出组件
即可,使用的时候就像对象那样
setup 语法糖下props的使用
-
props的使用————defineProps(这就是一个宏命令)
- 使用运行时声明: 从编译后的结果可以看到,还是放到了传统的props中去
<script setup lang="ts"> defineProps({ title: { type:String, required:true, defaults:'默认值' }, list: { // 注意这个type是vue提供的,不能像ts那样约束数组里的内容 type: Array, required: true } }) </script>
- 类型声明: 从编译后的结果可以看到,还是放到了传统的props中去
<script setup lang="ts"> const props = defineProps<{ title?:type:string list:{id:number, content:string}[] }>() // 可以通过变量接收defineProps的返回值,并在script中使用 console.log(props); </script>
- 注意,两种声明不能混用
-
props的默认值————widthDefaults
- 运行时声明可以添加默认值
- 类型声明的ts需要widthDefaults,所以写法变成了下面这样
<script setup lang="ts"> const props = widthDefaults(defineProps<{ title?:type:string list:{id:number, content:string}[] }>(), { title:'ts的默认值' }) // 可以通过变量接收defineProps的返回值,并在script中使用 console.log(props); </script>
setup 语法糖下自定义事件————defineEmits的使用
- 作用——在vue2中我一直把它理解为是子组件向父组件传值的一种方法
- 两种用法:普通写法在子组件中没有对数据类型进行约束;类型声明式则更好一点。
- 普通写法:
const emits = defineEmits(['parentClick','parentChange']) const handleClick = () => { // 子组件中对参数没有约束 emits("parentClick",2) } const handleChange = () => { emits("parentChange") }
- 类型声明式:既提供了类型的约束,也提供了类型的提示
const emits = defineEmits<{ // 这里对数据类型进行了约束! (e:'parentClick', data: number): void, (e:'parentChange'): void }>() const handleClick = () => { emits("parentClick",2) } const handleChange = () => { emits("parentChange") }
显示地暴露 ———— defineExpose
useSlots-useAttrs-await(插槽)
style v-bind
- css module 原来我在vue2中是这样写样式的:
<script setup lang="ts">
</script>
<template>
// 通过类名选择器来使用
<p class="red">使用css module功能</p>
</template>
<style>
.red{
color:red
}
</style>
使用css module: 可以理解为css module维护了一个对象$style,类名是它的元素,所以template中可以访问到类名
<script setup lang="ts">
</script>
<template>
<p :class="$style.red">使用css module功能</p>
</template>
<style module>
.red{
color:red
}
</style>
- module模块可以具名
- 具名的好处,一是可以区分;二是可以在script中通过useCssModule来获取它。进而通过js,操作样式(我想多了,没办法修改它)
<script setup lang="ts">
import { useCssModule } from 'vue';
const box = useCssModule('box');
function changeStyle() {
console.log(box);
}
</script>
<template>
<p :class=[$style.red,box.outLook]>使用css module功能</p>
<button @click="changeStyle">点击修改样式:暂时没法修改的</button>
</template>
<style module>
.red{
color:red
}
</style>
<style module="box">
.outLook{
border:1px solid red;
width: 200px;
height: 20px;
background-color: pink;
}
</style>
- 状态驱动的动态css
- vue2中是怎么样动态修改样式的?通过修改变量 + 三目运算符 + 切换不同的样式
- 可以看到style中冗余了多余的样式,再者template中进行计算和判断的内容,没有很好的解耦
<script setup lang="ts">
import {ref} from 'vue'
const flag = ref(false);
</script>
<template>
<button :class="flag?'active':'no'" @click="flag = !flag">
点击修改样式
</button>
</template>
<style>
.active {
color: red;
}
.no {
color:blue;
}
</style>
- vue3中: 形式简洁、也解耦了
<script setup lang="ts">
import {ref} from 'vue'
const fontColor = ref('blue');
</script>
<template>
<button class="active" @click="fontColor = 'red'">点击修改样式</button>
</template>
<style>
.active {
color: v-bind(fontColor);
}
</style>
Web components
- web components入门
- 背景:写一个组件,可以跨框架使用,即vue、react都能使用。既然是独立于框架的,为啥这里又可以用vue来写呢?因为vue提供了一个API供快速写 Web components,写完以后,将其导出,还是通用的一个组件。
- 基本使用:写一个ts文件,在该文件中写通用组件,所写的ts文件最终要在main.ts中导入,供全局使用。可见这种写法还是很繁琐的,跟原生的web components没区别
import { defineCustomElement } from "vue"; // 步骤1:使用defineCustomElement写一个html页面 const MyCustomElement = defineCustomElement({ props: {}, template: "<div class='color'>MyCustomElement</div>", styles: ['.color{color:red}'] }); // 步骤二:使用customElements.define将页面变成组件my-custom-element customElements.define("my-custom-element", MyCustomElement);
- 使用sfc来创建 Web components
- 优点:可以用写vue组件的形式写上面defineCustomElement里的那一大串内容,注意这个组件的后缀名要是'.ce.vue'
// Loading
- 注意在vite.config.ts中进行配置,获取带有运行时解析的vue文件
resolve: { alias: [ { find: "vue", replacement: "vue/dist/vue.esm-bundler.js", }, ] }
性能提升
- v-memo指令
服务端渲染
- @vue/server-renderer
Effect 作用域API
- effectScope用于直接控制响应式API(computed和watch)的执行时机
volar插件
- 很好地支持了vue3的新特性、支持ts
-
语法糖提示,如ref sugardengdeng,这个要在volar插件中进行设置的
-
把编辑器分成三分