目录

前言

这些内容是博主在学习过程中记录下来的,有一些不重要的点就跳过了,需要时自行查询文档。其实V2V3的学习成本不高,熟悉V2的话,看完这篇文章就可以上手V3

Vue3官网

在线源码编译地址

1,setup


setup是所有Composition API的容器,值为一个函数。组件中所用到的数据、方法等等,均要配置在setup中,它会在beforeCreate之前执行一次,注意:V3this不再是指向Vue实例,访问this会是undefined

1.1,返回值


  • 若返回一个对象,则对象中的属性、方法, 在模板中均可以直接使用。
  • 若返回一个渲染函数:则可以自定义渲染内容。

1.2,注意点


尽量不要与V2配置混用

V2配置(datamethoscomputed...)中可以访问到setup中的属性、方法。

但在setup中不能访问到V2配置(datamethodscomputed...)。

如果有重名, setup优先。

setup不能是一个async函数

因为返回值不再return的对象, 而是promise, 模板看不到return对象中的属性。(后期也可以返回一个Promise实例,但需要Suspense和异步组件的配合)

1.3,语法


  1. <script>
  2. import { ref, reactive } from 'vue'
  3. export default {
  4. name: 'Home',
  5. setup(props, context) {
  6. const title = ref('标题')
  7. const data = reactive({
  8. value: '哈哈哈'
  9. })
  10. return {
  11. title,
  12. data
  13. }
  14. }
  15. }
  16. </script>

1.4,setup的参数


  • props:值为对象,包含组件外部传递过来,且组件内部声明接收了的属性

  • context:上下文对象

    • attrs: 值为对象,包含组件外部传递过来,但没有在props配置中声明的属性, 相当于this.$attrs
    • slots: 收到的插槽内容, 相当于this.$slots
    • emit: 分发自定义事件的函数, 相当于this.$emit

2,ref 创建响应式数据


使用ref可以创建一个包含响应式数据的引用对象(reference对象,简称ref对象),可以是基本类型、也可以是对象。

语法

  1. // 创建
  2. const xxx = ref(value)
  3. // 使用
  4. xxx.value
  5. // 在模板中
  6. <div>{{xxx}}</div>

3,reactive 创建响应式数据


定义一个对象类型的响应式数据,内部基于ES6Proxy实现,通过代理对象操作源对象内部数据进行操作

语法

  1. // 创建
  2. const xxx = reactive({
  3. xxx: ''
  4. })
  5. // 使用
  6. xxx.xxx

4,computed 计算属性


V2computed配置功能一致

语法

  1. import { computed } from 'vue'
  2. setup(){
  3. // 简写语法
  4. let fullName = computed(() => {
  5. return person.firstName + '-' + person.lastName
  6. })
  7. // 完整语法
  8. let fullName = computed({
  9. get(){
  10. return person.firstName + '-' + person.lastName
  11. },
  12. set(value){
  13. const nameArr = value.split('-')
  14. person.firstName = nameArr[0]
  15. person.lastName = nameArr[1]
  16. }
  17. })
  18. return fullName
  19. }

5,watch 监听


V2watch配置功能一致,语法有点改动

语法

  • 情况一:监视ref定义的响应式数据
  1. watch(sum, (newValue, oldValue) => {
  2. console.log('sum变化了', newValue, oldValue)
  3. }, {immediate:true})
  • 情况二:监视多个ref定义的响应式数据
  1. watch([sum, msg], (newValue,oldValue) => {
  2. console.log('sum或msg变化了', newValue,oldValue)
  3. })
  • 情况三:监视reactive定义的响应式数据
  1. // 若watch监视的是reactive定义的响应式数据,则无法正确获得oldValue
  2. // 若watch监视的是reactive定义的响应式数据,则强制开启了深度监视
  3. watch(person, (newValue, oldValue) => {
  4. console.log('person变化了', newValue, oldValue)
  5. }, { immediate:true, deep:false }) // 此处的deep配置不再奏效
  • 情况四:监视reactive定义的响应式数据中的某个属性
  1. watch(() => person.job, (newValue, oldValue) => {
  2. console.log('person的job变化了', newValue, oldValue)
  3. }, { immediate:true, deep:true })
  • 情况五:监视reactive定义的响应式数据中的某些属性
  1. watch([() => person.job, () => person.name], (newValue, oldValue) => {
  2. console.log('person的job变化了', newValue, oldValue)
  3. }, { immediate:true, deep:true })
  • 特殊情况:此处由于监视的是reactive素定义的对象中的某个属性,所以deep配置有效
  1. watch(() => person.job, (newValue, oldValue) => {
  2. console.log('person的job变化了', newValue, oldValue)
  3. }, { deep:true })

6,watchEffect 监听回调


watch的区别是,watch既要指明监视的属性,也要指明监视的回调。而watchEffect,不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性,不用写返回值。

语法

  1. // 回调中用到的数据只要发生变化,则直接重新执行回调
  2. watchEffect(() => {
  3. const x1 = sum.value
  4. const x2 = person.age
  5. console.log('watchEffect配置的回调执行了')
  6. })

7,生命周期


生命周期全都写在setup

7.1,改变


  • beforeDestroy 改名为 beforeUnmount
  • destroyed 改名为 unmounted
  • beforeCreate => setup
  • created => setup
  • beforeMount => onBeforeMount
  • mounted => onMounted
  • beforeUpdate => onBeforeUpdate
  • updated => onUpdated
  • beforeUnmount => onBeforeUnmount
  • unmounted => onUnmounted

7.2,语法


  1. setup() {
  2. onMounted(() => {
  3. console.log('mounted')
  4. })
  5. }

8,toRef 创建ref


创建一个ref对象,其value值指向另一个对象中的某个属性

语法

  1. const state = reactive({
  2. foo: 1,
  3. bar: 2
  4. })
  5. const fooRef = toRef(state, 'foo')
  6. // 传递props
  7. export default {
  8. setup(props) {
  9. useSomeFeature(toRef(props, 'foo'))
  10. }
  11. }

9,toRefs 响应式转换


将响应式对象转换为普通对象,其中结果对象的每个property都是指向原始对象相应propertyref

语法

  1. const state = reactive({
  2. foo: 1,
  3. bar: 2
  4. })
  5. const stateAsRefs = toRefs(state)
  6. // 此时state和stateAsRefs是关联的

10,shallowReactive 响应式外层转换


只处理对象最外层属性的响应式(浅响应式)。适用于:一个对象数据,结构比较深, 但变化时只是外层属性变化

语法

  1. const state = shallowReactive({
  2. foo: 1,
  3. nested: {
  4. bar: 2
  5. }
  6. })

11,shallowRef 基本数据响应式


只处理基本数据类型的响应式, 不进行对象的响应式处理。适用于:一个对象数据,后续功能不会修改该对象中的属性,而是生新的对象来替换

语法

  1. const shallow = shallowRef({
  2. greet: 'Hello, world'
  3. })

12,readonly 响应式变只读


让一个响应式数据变为只读的(深只读),应用于不希望数据被修改时

语法

  1. const shallow = shallowRef({
  2. greet: 'Hello, world', // 只读
  3. nested: {
  4. bar: 2 // 只读
  5. }
  6. })

13,shallowReadonly 响应式变只读


让一个响应式数据变为只读的(浅只读),应用于不希望数据被修改时

语法

  1. const shallow = shallowReadonly({
  2. foo: 1, // 只读
  3. nested: {
  4. bar: 2 // 非只读
  5. }
  6. })

14,toRaw 响应式变非响应式


将一个由reactive生成的响应式对象转为普通对象,对这个普通对象的所有操作,不会引起页面更新。

语法

  1. const foo = {}
  2. const Foo = reactive(foo)
  3. console.log(toRaw(Foo) === foo) // true

15,markRaw 标记永远不响应式


标记一个对象,使其永远不会再成为响应式对象,有些值不应被设置为响应式的,例如复杂的第三方类库等,当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能。

语法

  1. const foo = markRaw({})
  2. console.log(isReactive(reactive(foo))) // false
  3. // 嵌套在其他响应式对象中时也可以使用
  4. const bar = reactive({ foo })
  5. console.log(isReactive(bar.foo)) // false

16,customRef 依赖更新控制


创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。它需要一个工厂函数,该函数接收tracktrigger函数作为参数,并且应该返回一个带有getset的对象。

语法

  1. <script>
  2. import { customRef } from 'vue'
  3. export default {
  4. name: 'Home',
  5. setup() {
  6. // 实现防抖函数
  7. const fn = function(value, delay = 500) {
  8. let timeout
  9. return customRef((track, trigger) => {
  10. return {
  11. get() {
  12. track()
  13. return value
  14. },
  15. set(newValue) {
  16. clearInterval(timeout)
  17. timeout = setTimeout(() => {
  18. console.log(newValue)
  19. value = newValue
  20. trigger()
  21. }, delay)
  22. }
  23. }
  24. })
  25. }
  26. const keyword = fn('', 500)
  27. return {
  28. keyword
  29. }
  30. }
  31. }
  32. </script>

17,provide & inject 通信


实现祖与后代组件间通信,父组件有一个provide选项来提供数据,后代组件有一个inject选项来开始使用这些数据

语法

  1. // 祖组件
  2. setup(){
  3. let car = reactive({ name:'奔驰', price:'40万' })
  4. provide('car', car)
  5. }
  6. // 后代组件
  7. setup(props, context){
  8. const car = inject('car')
  9. return { car }
  10. }

18,响应式数据的判断


18.1,isRef


检查一个值是否为一个ref对象

语法

  1. const val = ref('xxx')
  2. isRef(val) // true

18.2,isReactive


检查一个值是否为一个isReactive对象

语法

  1. const val = isReactive({})
  2. isRef(val) // true

18.3,isReadonly


检查一个对象是否是由readonly创建的只读代理

语法

  1. const state = reactive({
  2. name: 'John'
  3. })
  4. console.log(isReactive(state)) // true

18.4,isProxy


检查对象是否是由reactivereadonly创建的proxy

语法

  1. const state = reactive({
  2. name: 'John'
  3. })
  4. console.log(isProxy(state)) // true

19,teleport 移动dom组件


Teleport提供了一种干净的方法,允许我们控制在DOM中哪个父节点下渲染了HTML,而不必求助于全局状态或将其拆分为两个组件。

语法

  1. <teleport to="移动位置">
  2. <div v-if="isShow" class="mask">
  3. <div class="dialog">
  4. <h3>我是一个弹窗</h3>
  5. <button @click="isShow = false">关闭弹窗</button>
  6. </div>
  7. </div>
  8. </teleport>
  9. // to的格式
  10. <teleport to="#some-id" />
  11. <teleport to=".some-class" />
  12. <teleport to="[data-teleport]" />
  13. // disabled的格式
  14. <teleport to="#popup" :disabled="displayVideoInline">
  15. <video src="./my-movie.mp4">
  16. </teleport>

20,Suspense 异步渲染组件


等待异步组件时先渲染一些额外内容,让应用有更好的用户体验

语法

  1. <template>
  2. <div class="app">
  3. <h3>我是App组件</h3>
  4. <Suspense>
  5. <template #default>
  6. <Child/>
  7. </template>
  8. <template #fallback>
  9. <h3>加载中.....</h3>
  10. </template>
  11. </Suspense>
  12. </div>
  13. </template>
  14. import { defineAsyncComponent } from 'vue'
  15. const Child = defineAsyncComponent(() => import('./components/Child.vue'))
  16. components: {
  17. Child
  18. }

21,全局API调整


将全局的API,即:Vue.xxx调整到应用实例(app)上

V2的api V3的api
Vue.config.xxxx app.config.xxxx
Vue.component app.component
Vue.directive app.directive
Vue.mixin app.mixin
Vue.use app.use
Vue.prototype app.config.globalProperties

22,移除api


名称 现状
Vue.config.productionTip 已移除
config.keyCodes 已移除
$children 已移除
$listeners 已移除
$on 已移除
$off 已移除
$once 已移除
filters 已移除
.native 已移除

23,Ref 获取DOM


由于V3中不在存在this,所以ref的获取调整了

23.1,单个ref


语法

  1. <div ref="Qrcode" class="qr_codeode_url" />
  2. import { ref } from 'vue'
  3. export default {
  4. setup() {
  5. const Qrcode = ref(null)
  6. // 挂载后
  7. onMounted(() => {
  8. console.log(Qrcode.value)
  9. })
  10. return {
  11. Qrcode
  12. }
  13. }
  14. }

23.2,循环中的ref


V3中在for循环元素上绑定ref将不再自动创建$ref数组。要从单个绑定获取多个ref,请将ref绑定到一个更灵活的函数上

语法

  1. <div v-for="item in list" :ref="setItemRef"></div>
  2. import { onBeforeUpdate, onUpdated } from 'vue'
  3. export default {
  4. setup() {
  5. let itemRefs = []
  6. const setItemRef = el => {
  7. if (el) {
  8. itemRefs.push(el)
  9. }
  10. }
  11. onBeforeUpdate(() => {
  12. itemRefs = []
  13. })
  14. onUpdated(() => {
  15. console.log(itemRefs)
  16. })
  17. return {
  18. setItemRef
  19. }
  20. }
  21. }
  • itemRefs不必是数组:它也可以是一个对象,其ref可以通过迭代的key被设置
  • 如有需要,itemRef也可以是响应式的,且可以被侦听

24,emits 自定义事件


定义一个组件可以向其父组件触发的事件

  1. // 在子组件中
  2. <h1 @click="father">{{ msg }}</h1>
  3. export default {
  4. name: 'HelloWorld',
  5. props: {
  6. msg: {
  7. type: String,
  8. default: ''
  9. }
  10. },
  11. emits: ['close'],
  12. setup(props, { emit }) {
  13. const father = function() {
  14. emit('close', 'child')
  15. }
  16. return {
  17. father
  18. }
  19. }
  20. }
  21. // 在父组件中
  22. <HelloWorld :msg="msg" @click="fn" @close="fn2" />

25,$nextTick 异步更新


使用方式修改

  1. import { nextTick } from 'vue'
  2. nextTick(() => {
  3. // ...
  4. })

26,hook 生命周期事件


通过事件来监听组件生命周期中的关键阶段

语法

  1. // V2的语法
  2. <template>
  3. <child-component @hook:updated="onUpdated">
  4. </template>
  5. // V3的语法
  6. <template>
  7. <child-component @vnode-updated="onUpdated">
  8. </template>
  9. // 驼峰写法
  10. <template>
  11. <child-component @vnodeUpdated="onUpdated">
  12. </template

如果看了觉得有帮助的,我是@鹏多多,欢迎 点赞 关注 评论;END


PS:在本页按F12,在console中输入document.querySelectorAll('.diggit')[0].click(),有惊喜哦


公众号

往期文章

个人主页

助你上手Vue3全家桶之Vue3教程的更多相关文章

  1. 助你上手Vue3全家桶之Vue-Router4教程

    目录 1,前言 1,Router 2.1,跳转 2.2,打开新页面 3,Route 4,守卫 4.1,onBeforeRouteLeave 4.2,onBeforeRouteUpdate 4.3,路由 ...

  2. 助你上手Vue3全家桶之VueX4教程

    目录 1,前言 2,State 2.1,直接使用 2.2,结合computed 3,Getter 3.1,直接使用 3.2,结合computed 4,Mutation 4.1,直接使用 4.2,结合c ...

  3. 开箱即用 yyg-cli(脚手架工具):快速创建 vue3 组件库和vue3 全家桶项目

    1 yyg-cli 是什么 yyg-cli 是优雅哥开发的快速创建 vue3 项目的脚手架.在 npm 上发布了两个月,11月1日进行了大升级,发布 1.1.0 版本:支持创建 vue3 全家桶项目和 ...

  4. 基于 vite 创建 vue3 全家桶项目(vite + vue3 + tsx + pinia)

    vite 最近非常火,它是 vue 作者尤大神发布前端构建工具,底层基于 Rollup,无论是启动速度还是热加载速度都非常快.vite 随 vue3 正式版一起发布,刚开始的时候与 vue 绑定在一起 ...

  5. vue3 vite2 封装 SVG 图标组件 - 基于 vite 创建 vue3 全家桶项目续篇

    在<基于 vite 创建 vue3 全家桶>一文整合了 Element Plus,并将 Element Plus 中提供的图标进行全局注册,这样可以很方便的延续 Element UI 的风 ...

  6. Vue3 全家桶,从 0 到 1 实战项目,新手有福了

    前端发展百花放,一技未熟百技出.未知何处去下手,关注小编胜百书. 我是前端人,专注分享前端内容! 本篇文章主要是,使用 vite 创建一个vue3 项目,实践 vie-router4 vuex4 结合 ...

  7. ⚡ vue3 全家桶体验

    前置 从创建一个简单浏览器导航首页项目展开,该篇随笔包含以下内容的简单上手: vite vue3 vuex4 vue-router next 预览效果有助于理清这些内容,限于篇幅,不容易展开叙述.由于 ...

  8. Vue3全家桶升级指南一composition API

    1.setup() vue3中的composition API中最重要的就是setup方法了,相当于组件的入口,所有的composition API都必须放到setup()中的使用. setup是在组 ...

  9. Vue3全家桶升级指南二ref、toRef、toRefs的区别

    ref是对原始数据的拷贝,当修改ref数据时,模板中的视图会发生改变,但是原始数据并不会改变. toRef是对原始数据的引用,修改toRef数据时,原始数据也会发生改变,但是视图并不会更新. 在vue ...

随机推荐

  1. 深入xLua实现原理之Lua如何调用C#

    xLua是腾讯的一个开源项目,为Unity. .Net. Mono等C#环境增加Lua脚本编程的能力.本文主要是探讨xLua下Lua调用C#的实现原理. Lua与C#数据通信机制 无论是Lua调用C# ...

  2. CDI Features inJavaEE 的上下文和依赖注入

    基本的CDI的功能: 类型安全:CDI使用Java类型来解析注入,而不是通过(字符串)名称注入对象.当类型不足时, 可以使用限定符 注释.这允许编译器轻松检测错误,并提供简单的重构. POJO:几乎每 ...

  3. Jwt的新手入门教程

    Jwt的新手入门教程 1.Jwt究竟是什么东东? ​ 先贴官网地址:JSON Web Tokens - jwt.io ​ ​ 再贴官方的定义: What is JSON Web Token? JSON ...

  4. js 签字插件

    1.jq-signature  http://bencentra.github.io/jq-signature/    支持的jquery版本低 2.HTML5 canvas   http://www ...

  5. Shell系列(11)- 位置参数变量(4)

    作用 往shell脚本里面传递参数 位置参数变量 作用 $n n 为数字,$0 代表命令本身,$1-$9 代表第一到第九个参数,十以上的参数需要用大括号包含,如 ${10} $* 这个变量代表命令行中 ...

  6. Kotlin协程基础

    开发环境 IntelliJ IDEA 2021.2.2 (Community Edition) Kotlin: 212-1.5.10-release-IJ5284.40 我们已经通过第一个例子学会了启 ...

  7. 《exe应用程序UI自动化》

    前言:有很多公司做一些客户端的应用,每次发版都要耗费人力去手动回归比较费时,那么我们就想着去怎么去驱动人为的操作变为机器的操作过程,当然想着进行UI自动 那么我们就要考虑怎么去实现exe应用程序的自动 ...

  8. 使用Gitmoji进行git commit的快速查阅指南

    目录 前言 1. 查阅方法:脚本法 1.1 利用 VS Code 编辑多行文本快速写脚本文件 1.2 给脚本添加可执行权限 1.3 修改环境变量 PATH 使脚本在所有路径下都可以执行(全局执行) 2 ...

  9. 基于深度学习的建筑能耗预测01——Anaconda3-4.4.0+Tensorflow1.7+Python3.6+Pycharm安装

    基于深度学习的建筑能耗预测-2021WS-02W 一,安装python及其环境的设置 (写python代码前,在电脑上安装相关必备的软件的过程称为环境搭建) · 完全可以先安装anaconda(会自带 ...

  10. mysql从零开始之MySQL 教程

    MySQL 教程 MySQL 是最流行的关系型数据库管理系统,在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System:关系数 ...