首页>>前端>>Vue->Vue3 新特性

Vue3 新特性

时间:2023-12-01 本站 点击:0

Vue3 新特性

首先是向下兼容,Vue3 支持大多数 Vue2 的特性。甚至就拿 Vue2 的语法开发 Vue3,也是没有任何问题的。

性能的提升,每个人都希望使用的框架更快,更轻。Vue3 做到了,给开发者一个极致的体验。官方网站给出的数据是:打包大小减少 41%,初次渲染快 55%,更新快 133%,内存使用减少 54%。

新推出的Composition API ,在 Vue2 中遇到的问题就是复杂组件的代码变的非常麻烦,甚至不可维护。说白了就是封装不好,重用不畅。这个Composition API一推出,立马解决了这个问题。它是一系列 API 的合集。

其他新特性:Teleport(瞬移组件)、Suspense(解决异步加载组件问题)和全局 API 的修改和优化。

更好TypeScript支持,Vue3 的源代码就是使用TypeScript进行开发的。所以在新的版本上使用TS也更加顺畅无阻。

一、composition-api

Vue在2.x中编写代码要按照一定的模板,比如数据就只能放在data()中,方法只能放在methods中,按照模板编写代码对于新手来讲可能是好事,但是一旦项目变大,维护起来就显得很困难。

下图的左边图示,即Vue2使用的Options-api,图中相同的颜色对应是组件的一种功能,可以看到为了实现一种功能,Options-api所写的代码是非常分散的。

如果组件逻辑复杂,代码量多,我们添加新代码不光要不停的上下滑动,而且在后期代码维护中,阅读起来也变得十分的困难,因为实现一种功能的代码并没有集中在一起。另外就是作为一个新接手的开发人员,在茫茫的 method、data、computed 等选项中一目了然的发现这个变量是属于哪个功能是比较困难的 。

而在Composition-api中,我们可以把实现一种功能的代码写在一起,甚至还可以把它们单独抽取在一个js文件或者一个函数中。在js文件中也可以引用Composition-api的生命周期函数。这将极大的提高代码的可维护性。这样就可以更好的提取和重用多个组件之间的逻辑。

优劣比较:

在逻辑组织和逻辑复用方面,Composition API是优于Options API,因为Composition API几乎是函数,会有更好的类型推断。

Composition API对 tree-shaking 友好,代码也更容易压缩。

Composition API中见不到this的使用,减少了this指向不明的情况。

如果是小型组件,可以继续使用Options API,也是十分友好的。

1、setup

setup 函数是一个新的组件选项。作为在组件内使用 Composition API 的入口点。 新的 setup 选项在组件被创建之前执行,一旦 props 被解析完成,它就将被作为组合式 API 的入口。

setup函数的参数

我们先来研究一个setup函数的参数,它主要有两个参数:

第一个参数:props

第二个参数:context

props非常好理解,它其实就是父组件传递过来的属性会被放到props对象中,我们在setup中如果需要使用,那么就可以直接通过props参数获取:

对于定义props的类型,我们还是和之前的规则是一样的,在props选项中定义;

并且在template中依然是可以正常去使用props中的属性,比如message;

如果我们在setup函数中想要使用props,那么不可以通过 this 去获取(后面我会讲到为什么);

因为props有直接作为参数传递到setup函数中,所以我们可以直接通过参数来使用即可;

另外一个参数是context,我们也称之为是一个SetupContext,它里面包含三个属性:

attrs:所有的非prop的attribute;

slots:父组件传递过来的插槽(这个在以渲染函数返回时会有作用);

emit:当我们组件内部需要发出事件时会用到emit(因为我们不能访问this,所以不可以通过 this.$emit发出事件);

setup函数的返回值

setup既然是一个函数,那么它也可以有返回值,它的返回值用来做什么呢?

setup的返回值可以在模板template中被使用;

也就是说我们可以通过setup的返回值来替代data选项;

甚至是我们可以返回一个执行函数来代替在methods中定义的方法:

<template>  <div>    <div>{{ title }}</div>    <div @click="hanldeClick">点他</div>  </div></template><script>  export default {    setup() {      const title = 'this is a title'      const hanldeClick = () => {        alert('已点!')      }      return {        title,        hanldeClick      }    },  }</script>

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>9

setup不可以使用this

官方关于this有这样一段描述:

表达的含义是this并没有指向当前组件实例;

并且在setup被调用之前,data、computed、methods等都没有被解析;

所以无法在setup中获取this;

2、Ref 和 Reactive

在我看来 ref 和 reactice 都是用来创建响应式对象的。

reactive 接受的参数是一个对象或数组类型。如果是数组类型会转换成proxy对象。

ref 一般创建一个基本类型变量,有一个 .value属性,可以通过其对值进行读取或修改。

reactive 在组合函数返回时记得添加上 ’...toRefs(state)‘以保持响应性,对对象解构或展开后会失去响应性,所以需要使用roRefs()把reactive类型转为ref类型。

ref 可以用于子组件的ref属性使用。(后面会提到)

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>9

``` 以下是两种关于Ref ,Reactive的风格建议

就像你在普通 JavaScript 中区别声明基础类型变量与对象变量时一样区别使用 ref 和 reactive。我们推荐你在此风格下结合 IDE 使用类型系统。

所有的地方都用 reactive,然后记得在组合函数返回响应式对象时使用 toRefs。这降低了一些关于 ref 的心智负担,但并不意味着你不需要熟悉这个概念。

3、computed 、watch、watchEffect

<script>import {reactive, ref, toRefs, computed, watch} from "vue";export default {    setup() {        // computed        const count = ref(1)        const plusOne = computed(() => count.value + 1)        const state = reactive({            title: computed(() => {                return count.value + 1            }),        })        // watch        // watch 可以接收三个参数  第一个是要监听的对象 第二个是数据处理变化,第三个是配置项(options)        // options: immediate:true是刚一进去就监听一次        // 1:监听ref定义的响应式数据        const num = ref(0)        const msg = ref('watch')        watch(            num,            (newV, oldV) => {                console.log(newV)            },            { immediate:true }        )        // 2:监听多个ref声明的响应式数据        watch(            [num, msg],            (newV, oldV) => {                console.log(newV)            },            { immediate:true }        )        // 3:监听reactive定义的响应式的全部数据        // 注意:使用reactive定义的数据,无法正确获取odlV;并且强制开启了深度检测(deep配置无效)        const state = reactive({            age: 18,            name: 'fc'        })        watch(            state,            (newV, oldV) => {                console.log(newV)            },            { deep: true } // 此配置无效        )        // 4:监听reactive所定义的一个响应式数据的一个属性        watch(            () => state.age,            (newV, oldV) => {                console.log(newV)            }        )        // 5:监听reactive所定义的一个响应式数据的一些属性        watch(            [() => state.age, () => state.name],            (newV, oldV) => {                console.log(newV)            }        )        // 6:当监听的声明对象内的属性还是一个对象,因为不是使用reactive直接声明的        const person = {            job: {                j1: 1            }        }        watch(            () => peison.job,            (newV, oldV) => {                console.log(newV)            },            { deep: true }//此处由于监视的是reactive定义的对象内的某个属性,所以deep配置有效        )        return {            ...toRefs(state)        }    },  }</script>

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>9

watchEffect

watch是:既要指明监视的属性,也要指明监视的回调。

watchEffect是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。

这个函数的功能和计算属性差不多,但是

computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值。

watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值。

<script>import {watchEffect} from "vue";export default {    setup() {        watchEffect(() => {            if (state.value) {                // do something ...                setDates(state.value)            }        })    }}

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>9

4、生命周期

setup() :开始创建组件之前,在beforeCreate和created之前执行。创建的是data和method

onBeforeMount() : 组件挂载到节点上之前执行的函数。

onMounted() : 组件挂载完成后执行的函数。

onBeforeUpdate(): 组件更新之前执行的函数。

onUpdated(): 组件更新完成之后执行的函数。

onBeforeUnmount(): 组件卸载之前执行的函数。

onUnmounted(): 组件卸载完成后执行的函数

onActivated(): 被包含在

中的组件,会多出两个生命周期钩子函数。被激活时执行。

onDeactivated(): 比如从 A 组件,切换到 B 组件,A 组件消失时执行。

onErrorCaptured(): 当捕获一个来自子孙组件的异常时激活钩子函数。

onRenderTracked(): 直译过来就是状态跟踪,它会跟踪页面上所有响应式变量和方法的状态,也就是我们用return返回去的值,他都会跟踪。只要页面有update的情况,他就会跟踪,然后生成一个event对象,我们通过event对象来查找程序的问题所在。

onRenderTriggered(): 直译是状态触发,它不会跟踪每一个值,而是给你变化值的信息,并且新值和旧值都会给你明确的展示出来。

5、模板指令

组件上 v-model 用法已更改,支持双向绑定多个属性,例如v-model.title="title"

key 属性

Vue 3.x 不建议在 v-if/v-else/v-else-if 的分支中使用 key,如果非要使用,请设置唯一的key值。

Vue 3.x 可以将 key值 设置在template 上 (Vue2.x 需要将key值设置到子节点上)

v-if 与 v-for 的优先级对比

2.x 版本中在一个元素上同时使用 v-if 和 v-for 时,v-for 会优先作用。Vue2.x v-for 优先级高

3.x 版本中 v-if 总是优先于 v-for 生效。Vue3.x v-if 优先级高

v-bind 合并行为

在 2.x,如果一个元素同时定义了 v-bind=“object” 和一个相同的单独的 property,那么这个单独的 property 总是会覆盖 object 中的绑定。 单独的属性覆盖v-bind

在 3.x,如果一个元素同时定义了 v-bind=“object” 和一个相同的单独的 property,那么声明绑定的顺序决定了它们如何合并。

<!-- vue 2.x --><!-- template --><div id="red" v-bind="{ id: 'blue' }"></div<!-- result --><div id="red"></div><!-- vue 3.x --><!-- template --><div id="red" v-bind="{ id: 'blue' }"></div<!-- result --><div id="blue"></div><!-- template --><div v-bind="{ id: 'blue' }" id="red" ></div<!-- result --><div id="red"></div>

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>9

v-for 中的 Ref 数组

在 Vue 2 中,在 v-for 里使用的 ref attribute 会用 ref 数组填充相应的 $refs property。当存在嵌套的 v-for 时,这种行为会变得不明确且效率低下。

在 Vue 3 中,这样的用法将不再在 $ref 中自动创建数组。要从单个绑定获取多个 ref,请将 ref 绑定到一个更灵活的函数上 (这是一个新特性)

<div v-for="item in list" :key="item" :ref="setItemRef"></div>export default {  setup() {    let itemRefs = []    const setItemRef = el => {      if (el) {        itemRefs.push(el)      }    }    return {      setItemRef    }  },}</script>

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>9

- itemRefs 不必是数组:它也可以是一个对象,其 ref 会通过迭代的 key 被设置。- 如果需要,itemRef 也可以是响应式的且可以被监听。

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>9

6、props emit ref

直接上代码吧 ~

<!-- 父组件 --><template>  <div>    <h2>{{ title }}</h2>    <child :toChildTitle="toChildTitle" @handleChange="handleChange" ref="childRef"></child>  </div></template><script>import {onMounted, reactive, toRefs, ref} from "vue";export default {  setup() {    // 需要定义 ref 注意需要return出去    const childRef = ref()    const state = reactive({      title: '原来的title',      toChildTitle: 'fa传递过去title'    })    onMounted(() => {      // 父组件 获取/修改 子组件数据      console.log(childRef.value.val)      // 父组件 触发 子组件方法      childRef.value.childFun()    })    const handleChange = (val) => {      state.title = handleChange    }    return {      ...toRefs(state),      childRef,      handleChange    }  },}</script><!-- 子组件 --><template>  <div>    <h2>{{ toChildTitle }}</h2>    <div @click="changeBtn">点它</div>  </div></template><script>import {reactive, ref, toRefs, watch} from "vue";export default {  props: {    toChildTitle: String,  },  setup(props, context) {    const state = reactive({      toChildTitle: props.toChildTitle, // 将prop传递来的值转换成响应式数据,这样修改这个toChildTitle的时候 父组件的toChildTitle值也会变化      val: '其他参数', // 父组件需要使用的数据 需要return出去    })    // 触发父组件的方法    const changeBtn = () => {      context.emit('handleChange', '从child修改后的title')    }    // 父组件需要使用的方法 也需要return出去    const childFun = () => {        alert('child 的方法')    }    return {      ...toRefs(state),      changeBtn,      childFun    }  },}</script>

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>9

7、provide 和 inject

provide 和inject 是vue提供的一对API  这对API 可以实现组件之间的通信 无论层级有多深 都可以通过这对API 来实现

provide

在 setup() 中使用 provide 时,我们首先从 vue 显式导入 provide 方法。这使我们能够调用 provide 来定义每个 property。 provide 函数允许你通过两个参数定义 property:

name (

类型)

value

<script>import { provide } from 'vue'export default {  setup() {    provide('location', 'North Pole')    provide('geolocation', {      longitude: 90,      latitude: 135    })  }}</script>

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>9

inject

在 setup() 中使用 inject 时,也需要从 vue 显式导入。导入以后,我们就可以调用它来定义暴露给我们的组件方式。 inject 函数有两个参数:

要 inject 的 property 的 name

默认值 (可选)

<script>import { inject } from 'vue'export default {  setup() {    const userLocation = inject('location', 'The Universe')    const userGeolocation = inject('geolocation')    return {      userLocation,      userGeolocation    }  }}</script>

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>9

响应式

添加响应性: 为了增加 provide 值和 inject 值之间的响应性,我们可以在 provide 值时使用 ref 或 reactive。

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>0

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>9

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>1

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>9

修改响应式 property: 当使用响应式 provide / inject 值时,官方中建议尽可能将对响应式 property 的所有修改限制在定义 provide 的组件内部。

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>2

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>9

如果要确保通过 provide 传递的数据不会被 inject 的组件更改,官方建议对提供者的 property 使用 readonly。

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>3

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>9

8、

9、

TIP

通过 v-html 创建的 DOM 内容不会被作用域样式影响,但你仍然可以使用深度选择器来设置其样式。

module

自定义注入名称:

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>4

与组合式 API 一同使用:        注入的类可以通过 useCssModule API 在 setup() 和

这个语法同样也适用于

单文件组件状态驱动的 CSS 变量 (

10、getCurrentInstance

getCurrentInstance()是Vue3.x中的核心方法,用于访问实例上下文的router及vuex等。

概述:一个很重要的方法,获取当前组件的实例、上下文来操作router和vuex等。

引入:由vue提供,按需引入:import { getCurrentInstance} from 'vue';

使用:获取当前组件的上下文,推荐使用:const { proxy }  = getCurrentInstance()。

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>5

二、vue3周边生态

1、vue-router

vue2.x中,可以通过this.$router或者this.$route来获取或者操作路由。

在vue3.0中,引入了Composition-api。在setup函数中无法使用this获取组件实例。新版本的vue-router也提供了支持Composition-api的hooks,例如useRouter,useRoute函数。

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>6

另外,vue-router还提供了支持的Composition-api的两个路由守卫:update and leave

beforeRouteLeave:离开当前页面路由时触发,return false则阻止跳转,next中不能写参数

beforeRouteUpdate:动态路由 只有参数发生变化是才执行(通俗理解及跳转页面时)

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>7

2、vuex

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>8

三、其他

1、Teleport

Teleport 在国内大部分都翻译成了瞬间移动组件或任意传送门,也有把这个函数叫独立组件。 是一种能够将我们的模板移动到 DOMVue app 之外的其他位置的技术。

场景:像 modals,toast 等这样的元素,很多情况下,我们将它完全的和我们的 Vue 应用的 DOM 完全剥离,管理起来反而会方便容易很多。

原因在于如果我们嵌套在 Vue 的某个组件内部,那么处理嵌套组件的定位、z-index 和样式就会变得很困难。

另外,像 modals,toast 等这样的元素需要使用到 Vue 组件的状态(data 或者 props)的值。

这就是 Teleport 派上用场的地方。我们可以在组件的逻辑位置写模板代码,这意味着我们可以使用组件的 data 或 props。然后在 Vue 应用的范围之外渲染它。

使用

Teleport方法,可以把Dialog组件渲染到你任意想渲染的外部Dom上,不必嵌套再#app里了,这样就不会互相干扰了。你可以把Teleport看成一个传送门,把你的组件传送到你需要的地方。 teleport组件和其它组件没有任何其它的差异,用起来都是一样的。

首先我们在 index.html 中添加我们需要传送到的位置。

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>9

将编写的组件包装在 teleport 组件中,还需要指定一个 to 属性,为该属性分配一个查询选择器,以标识目标元素。

<script>import {reactive, ref, toRefs, computed, watch} from "vue";export default {    setup() {        // computed        const count = ref(1)        const plusOne = computed(() => count.value + 1)        const state = reactive({            title: computed(() => {                return count.value + 1            }),        })        // watch        // watch 可以接收三个参数  第一个是要监听的对象 第二个是数据处理变化,第三个是配置项(options)        // options: immediate:true是刚一进去就监听一次        // 1:监听ref定义的响应式数据        const num = ref(0)        const msg = ref('watch')        watch(            num,            (newV, oldV) => {                console.log(newV)            },            { immediate:true }        )        // 2:监听多个ref声明的响应式数据        watch(            [num, msg],            (newV, oldV) => {                console.log(newV)            },            { immediate:true }        )        // 3:监听reactive定义的响应式的全部数据        // 注意:使用reactive定义的数据,无法正确获取odlV;并且强制开启了深度检测(deep配置无效)        const state = reactive({            age: 18,            name: 'fc'        })        watch(            state,            (newV, oldV) => {                console.log(newV)            },            { deep: true } // 此配置无效        )        // 4:监听reactive所定义的一个响应式数据的一个属性        watch(            () => state.age,            (newV, oldV) => {                console.log(newV)            }        )        // 5:监听reactive所定义的一个响应式数据的一些属性        watch(            [() => state.age, () => state.name],            (newV, oldV) => {                console.log(newV)            }        )        // 6:当监听的声明对象内的属性还是一个对象,因为不是使用reactive直接声明的        const person = {            job: {                j1: 1            }        }        watch(            () => peison.job,            (newV, oldV) => {                console.log(newV)            },            { deep: true }//此处由于监视的是reactive定义的对象内的某个属性,所以deep配置有效        )        return {            ...toRefs(state)        }    },  }</script>0

2、Suspense

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

试验性

Suspense 是一个试验性的新特性,其 API 可能随时会发生变动。特此声明,以便社区能够为当前的实现提供反馈。

生产环境请勿使用。

以上是官方的警告!

使用:

首先我们先写一个异步组件 注意点:如果你要使用Suspense的话,要返回一个promise对象,而不是原来的那种JSON对象。

<script>import {reactive, ref, toRefs, computed, watch} from "vue";export default {    setup() {        // computed        const count = ref(1)        const plusOne = computed(() => count.value + 1)        const state = reactive({            title: computed(() => {                return count.value + 1            }),        })        // watch        // watch 可以接收三个参数  第一个是要监听的对象 第二个是数据处理变化,第三个是配置项(options)        // options: immediate:true是刚一进去就监听一次        // 1:监听ref定义的响应式数据        const num = ref(0)        const msg = ref('watch')        watch(            num,            (newV, oldV) => {                console.log(newV)            },            { immediate:true }        )        // 2:监听多个ref声明的响应式数据        watch(            [num, msg],            (newV, oldV) => {                console.log(newV)            },            { immediate:true }        )        // 3:监听reactive定义的响应式的全部数据        // 注意:使用reactive定义的数据,无法正确获取odlV;并且强制开启了深度检测(deep配置无效)        const state = reactive({            age: 18,            name: 'fc'        })        watch(            state,            (newV, oldV) => {                console.log(newV)            },            { deep: true } // 此配置无效        )        // 4:监听reactive所定义的一个响应式数据的一个属性        watch(            () => state.age,            (newV, oldV) => {                console.log(newV)            }        )        // 5:监听reactive所定义的一个响应式数据的一些属性        watch(            [() => state.age, () => state.name],            (newV, oldV) => {                console.log(newV)            }        )        // 6:当监听的声明对象内的属性还是一个对象,因为不是使用reactive直接声明的        const person = {            job: {                j1: 1            }        }        watch(            () => peison.job,            (newV, oldV) => {                console.log(newV)            },            { deep: true }//此处由于监视的是reactive定义的对象内的某个属性,所以deep配置有效        )        return {            ...toRefs(state)        }    },  }</script>1

使用suspense组件

<script>import {reactive, ref, toRefs, computed, watch} from "vue";export default {    setup() {        // computed        const count = ref(1)        const plusOne = computed(() => count.value + 1)        const state = reactive({            title: computed(() => {                return count.value + 1            }),        })        // watch        // watch 可以接收三个参数  第一个是要监听的对象 第二个是数据处理变化,第三个是配置项(options)        // options: immediate:true是刚一进去就监听一次        // 1:监听ref定义的响应式数据        const num = ref(0)        const msg = ref('watch')        watch(            num,            (newV, oldV) => {                console.log(newV)            },            { immediate:true }        )        // 2:监听多个ref声明的响应式数据        watch(            [num, msg],            (newV, oldV) => {                console.log(newV)            },            { immediate:true }        )        // 3:监听reactive定义的响应式的全部数据        // 注意:使用reactive定义的数据,无法正确获取odlV;并且强制开启了深度检测(deep配置无效)        const state = reactive({            age: 18,            name: 'fc'        })        watch(            state,            (newV, oldV) => {                console.log(newV)            },            { deep: true } // 此配置无效        )        // 4:监听reactive所定义的一个响应式数据的一个属性        watch(            () => state.age,            (newV, oldV) => {                console.log(newV)            }        )        // 5:监听reactive所定义的一个响应式数据的一些属性        watch(            [() => state.age, () => state.name],            (newV, oldV) => {                console.log(newV)            }        )        // 6:当监听的声明对象内的属性还是一个对象,因为不是使用reactive直接声明的        const person = {            job: {                j1: 1            }        }        watch(            () => peison.job,            (newV, oldV) => {                console.log(newV)            },            { deep: true }//此处由于监视的是reactive定义的对象内的某个属性,所以deep配置有效        )        return {            ...toRefs(state)        }    },  }</script>2

处理异步请求错误

在异步请求中必须要作的一件事情,就是要捕获错误,因为我们没办法后端给我们返回的结果,也有可能服务不通,所以一定要进行捕获异常和进行处理。

在vue3.x的版本中,可以使用onErrorCaptured这个钩子函数来捕获异常。在使用这个钩子函数前,需要先进行引入.

<script>import {reactive, ref, toRefs, computed, watch} from "vue";export default {    setup() {        // computed        const count = ref(1)        const plusOne = computed(() => count.value + 1)        const state = reactive({            title: computed(() => {                return count.value + 1            }),        })        // watch        // watch 可以接收三个参数  第一个是要监听的对象 第二个是数据处理变化,第三个是配置项(options)        // options: immediate:true是刚一进去就监听一次        // 1:监听ref定义的响应式数据        const num = ref(0)        const msg = ref('watch')        watch(            num,            (newV, oldV) => {                console.log(newV)            },            { immediate:true }        )        // 2:监听多个ref声明的响应式数据        watch(            [num, msg],            (newV, oldV) => {                console.log(newV)            },            { immediate:true }        )        // 3:监听reactive定义的响应式的全部数据        // 注意:使用reactive定义的数据,无法正确获取odlV;并且强制开启了深度检测(deep配置无效)        const state = reactive({            age: 18,            name: 'fc'        })        watch(            state,            (newV, oldV) => {                console.log(newV)            },            { deep: true } // 此配置无效        )        // 4:监听reactive所定义的一个响应式数据的一个属性        watch(            () => state.age,            (newV, oldV) => {                console.log(newV)            }        )        // 5:监听reactive所定义的一个响应式数据的一些属性        watch(            [() => state.age, () => state.name],            (newV, oldV) => {                console.log(newV)            }        )        // 6:当监听的声明对象内的属性还是一个对象,因为不是使用reactive直接声明的        const person = {            job: {                j1: 1            }        }        watch(            () => peison.job,            (newV, oldV) => {                console.log(newV)            },            { deep: true }//此处由于监视的是reactive定义的对象内的某个属性,所以deep配置有效        )        return {            ...toRefs(state)        }    },  }</script>3

有了onErrorCaptured就可以直接在setup()函数中直接使用了。钩子函数要求我们返回一个布尔值,代表错误是否向上传递。这里的false一方面表示:错误不会冒泡给父组件;另一方面表示vue将停止该错误的传播。

3、片段(Fragment)

在 Vue2.x 中, template中只允许有一个根节点:

        <template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>9

但是在 Vue3.x 中,你可以直接写多个根节点:

    <template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>9

最后的最后

最后的最后给大家推荐几个vue3相关网址

第一个vue3的官网:https://staging-cn.vuejs.org/

一个集合了vue3很多相关技术栈的网址:https://vue3js.cn/

一个前端技术栈博主J技术胖:https://www.jspang.com/article/64#toc0

<template><div> <h2>{{ title }}</h2> <h2>{{ rTitle }}</h2> <div @click="hanldeClick">点他</div></div></template>9


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/Vue/6551.html