vue3的新特性
2022/3/1 6:24:43
本文主要是介绍vue3的新特性,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
vue3的新特性
- 一、setup
- 二、ref
- 三、reactive
- 三、计算属性computed
- 三、计算属性watch
- 四、watchEffect函数
- 五、生命周期钩子
- 六、自定义hook函数
- 七、toRef和toRefs
- 八、其他新特性
- 1、shallowReactive 与 shallowRef
- 2、readonly 与 shallowReadonly
- 3、toRaw 与 markRaw
- 4、customRef
- 5、provide 与 inject
- 6、响应式数据的判断
- 九、新的组件
- 1、Fragment
- 2、Teleport
- 3、Suspense
- 十、其他变化
- 1、data选项应始终被声明为一个函数
- 2、过渡类名的更改
- 3、移除keyCode作为 v-on 的修饰符,同时也不再支持config.keyCodes
- 4、移除v-on.native修饰符
- 5、移除过滤器(filter)
一、setup
1、是vue3.0的中的一个新增配置项,值为一个函数。
2、setup是所有composition API(组合式api)展示的舞台。
3、setup函数的两种返回值:
若返回一个对象,则对象中的属性、方法, 在模板中均可以直接使用。(重点关注!)
若返回一个渲染函数:则可以自定义渲染内容。(了解) (不常用)
注意点:
1、尽量不要和vue2.x版本混用。
- vue2.x版本可以访问到setup里的属性。
- setup访问不到vue2.x版本的属性。
- 如果有重名,setup优先
2、setup不能是一个async函数,因为返回值不再是对象, 而是promise, 模板看不到return对象中的属性。
3、setup执行顺序在beforeCreat,并且在setup中this为undefined
4、setUp(props, contex)接受两个参数
- props:值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性(其实就是vue2.0的props功能)
- context:上下文对象(其中可以获取到1、attrs组件外部传递过来,但没有在props配置中声明的属性。2、slots:插槽内容3、emit:分发自定义事件的函数,并且以后在setup中不能写this.$emit,要写context.emit)
<template> <h2>姓名:{{name}}</h2> <h2>年龄:{{age}}</h2> <button @click="sayInfo">显示信息</button> </template> <script> export default { name: "App", setup(){ //此时的数据不具有双向绑定的功能 let name = "小明" let age = 18 // 方法 function sayInfo(){ alert(`你好${name},你太厉害了吧`) } // 想要在模板中使用setup中的方法或者数据,必须return return { name,age, gender,sayInfo } // return ()=> h('h1','试试') } }; </script>
二、ref
作用:定义一个响应式数据。
语法:let xxx = ref(xxx)
注意点:
- ref(),括号中可以填基本数据类型和也可以是对象类型
- 填基本数据类型会返回一个RefImpl的实例对象,RefImpl类中有getter和setter可以检测到数据的变化。
- 填对象类型的数据:其实就是使用了Vue3.0中的一个新函数—— reactive函数。
- js操作值的方法是xxx.value,模板中直接{{xxx}}
- 使用之前要先引入。
<template> <h2>姓名:{{ name }}</h2> <h2>年龄:{{ age }}</h2> <button @click="changeInfo">修改信息</button> </template> <script> import { ref } from "vue"; export default { name: "App", setup() { // 数据 let name = ref("小明"); let age = ref(18); // 方法 function changeInfo() { name.value = "小明"; age.value = 48; } return { name, age, changeInfo, }; }, }; </script>
三、reactive
作用:定义一个响应式对象。
语法:let xxx = reactive(xxx)
注意点:
- reactive(),括号要填对象类型
- 填基本数据类型会返回一个proxy实例对象。
- 填对象类型的数据:其实就是使用了Vue3.0中的一个新函数—— reactive函数。
- js操作值的方法是xxx.value,模板中直接{{xxx}}
- 使用之前要先引入。
- 上面ref()方法虽然也可以填对象,但是他的本质还是调用了reactive方法,并且js操作时还需要xxx.value,多此一举。而且使用reactive()定义的响应式对象是深层次的,不会出现vue2对象数据层级过深,不改变的情况。
<template> <h2>姓名:{{ yk.name }}</h2> <h2>年龄:{{ yk.age }}</h2> <h2>爱好:{{ yk.hobby }}</h2> <h3>测试数据:{{ yk.job.a.b.c }}</h3> <button @click="changeInfo">修改信息</button> </template> <script> import { reactive } from "vue"; export default { name: "App", setup() { // 数据 let yk = reactive({ age: 18, hobby: ["吃饭", "睡觉", "打豆豆"], job: { a: { b: { c: 666, }, }, }, }); // 方法 function changeInfo() { yk.age = 48; yk.job.a.b.c = 888; // 直接通过数组下标修改,可以触发响应式 yk.hobby[0] = "打豆豆"; } return { yk, changeInfo, }; }, }; </script>
三、计算属性computed
与vue2.x相比,功能几乎一样,但是写法有些许变动。
<template> 姓:<input v-model="person.firstName"></input> 名: <input v-model="person.lastName"></input> 姓名:<input v-model="person.fullName"></input> </template> <script> //先引入 import {computed,reactive } from 'vue' export default { name: "App", setup() { let person = reactive({ firstName :"小", lastName:"明", fullName:"" }) //计算属性 —— 简写 //let fullName = computed(()=>{ // return person.firstName + '-' + person.lastName //}) //计算属性 —— 完整 person.fullName = computed({ get(){ return person.firstName + '-' + person.lastName }, set(value){ const nameArr = value.split('-') person.firstName = nameArr[0] person.lastName = nameArr[1] } }) return { person }; }, }; </script>
三、计算属性watch
和计算属性差不多,在vue3中和只是语法上上的改变。
注意点:
- 监视reactive定义的响应式数据时:oldValue无法正确获取、强制开启了深度监视(deep配置失效)
- 监视reactive定义的响应式数据中某个属性时(这个属性需是对象):deep配置有效
//情况一:监视ref定义的响应式数据 watch(sum,(newValue,oldValue)=>{ console.log('sum变化了',newValue,oldValue) }) //如果用ref定义了一个对象 watch(person.value,(newValue,oldValue)=>{ console.log('person变化了',newValue,oldValue) }) //情况二:监视多个ref定义的响应式数据 watch([sum,msg],(newValue,oldValue)=>{ console.log('sum或msg变化了',newValue,oldValue) }) //情况三:监视reactive定义的响应式数据 watch(person,(newValue,oldValue)=>{ console.log('person变化了',newValue,oldValue) },{immediate:true,deep:false}) //此处的deep配置不再奏效 //情况四:监视reactive定义的响应式数据中的某个属性 watch(()=>person.job,(newValue,oldValue)=>{ console.log('person的job变化了',newValue,oldValue) },{immediate:true,deep:true}) //情况五:监视多个reactive定义的响应式数据中的某些属性 watch([()=>person.job,()=>person.name],(newValue,oldValue)=>{ console.log('person的job变化了',newValue,oldValue) },{immediate:true,deep:true}) //特殊情况 //person.job中的job也是一个对象 watch(()=>person.job,(newValue,oldValue)=>{ console.log('person的job变化了',newValue,oldValue) },{deep:true}) //此处由于监视的是reactive素定义的对象中的某个属性,所以deep配置有效
四、watchEffect函数
watch是:既要指明监视的属性,也要指明监视的回调。
watchEffect是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。
这个函数的功能和计算属性差不多,但是
- 但computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值。
- 而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值。
//watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调。 watchEffect(()=>{ const x1 = sum.value const x2 = person.age console.log('watchEffect配置的回调执行了') })
五、生命周期钩子
1、vue3.0中可以继续使用vue2.x中的生命周期钩子,但是有两个被更名:
- beforeDestroy改成beforUnmount
- destroyed改成 unmounted
2、vue3.0也提供了composition API形式的生命周期钩子,与vue2.x钩子对应关系如下:
- beforeCreate======>setup()
- created==========>setup()
- beforeMount======>onBeforeMount
- mounted=========>onMounted
- beforeUpdate=====>onBeforeUpdate
- updated =========>onUpdated
- beforeUnmount ===>onBeforeUnmount
- unmounted ======>onUnmounted
六、自定义hook函数
- 什么是hook?-------本质是一个函数,把setup中使用的compositionAPI进行了封装。
- 类似于vue2.x中的mixin。
- 自定义hook的优势:复用代码,让setup中的逻辑更清晰。
- emmmm感觉就是模块导入,和vue2.x 的mixin也有些许差别。
创建一个hook文件夹,里面创建文件point.js
import { reactive, onMounted, onBeforeUnmount } from "vue"; export default function() { //实现鼠标“打点”相关的数据 let point = reactive({ x: 0, y: 0, }); //实现鼠标“打点”相关的方法 function savePoint(event) { point.x = event.pageX; point.y = event.pageY; console.log(event.pageX, event.pageY); } //实现鼠标“打点”相关的生命周期钩子 onMounted(() => { window.addEventListener("click", savePoint); }); onBeforeUnmount(() => { window.removeEventListener("click", savePoint); }); return point; }
在组件中使用
<template> <h2>当前点击时鼠标的坐标为:x:{{point.x}},y:{{point.y}}</h2> </template> <script> import usePoint from '../hook/point.js' export default { name:'HelloWorld', setup(){ const point = usePoint() return {point} } } </script>
七、toRef和toRefs
- 作用:创建一个 ref 对象,其value值指向另一个对象中的某个属性。
- 语法:const name = toRef(person,‘name’)
- 应用: 要将响应式对象中的某个属性单独提供给外部使用时。
- 扩展:toRefs与toRef功能一致,但可以批量创建多个 ref 对象,语法:toRefs(person)
<template> <h4>{{person}}</h4> <h2>姓名:{{name}}</h2> <h2>年龄:{{age}}</h2> <h2>薪资:{{job.j1.salary}}K</h2> <button @click="name+='~'">修改姓名</button> <button @click="age++">增长年龄</button> <button @click="job.j1.salary++">涨薪</button> </template> <script> import {ref,reactive,toRef,toRefs} from 'vue' export default { name: 'HelloWorld', setup(){ let person = reactive({ name:'张三', age:18, job:{ j1:{ salary:20 } } }) // const name1 = person.name // console.log('%%%',name1) // const name2 = toRef(person,'name') // console.log('####',name2) const x = toRefs(person) console.log('******',x) return { person, // name:toRef(person,'name'), // age:toRef(person,'age'), // salary:toRef(person.job.j1,'salary'), ...toRefs(person) } } } </script>
八、其他新特性
1、shallowReactive 与 shallowRef
- shallowReactive:只处理对象最外层属性的响应式(浅响应式)。
- shallowRef:只处理基本数据类型的响应式, 不进行对象的响应式处理。
- 什么时候使用?
1、如果有一个对象数据,结构比较深, 但变化时只是外层属性变化 ===> shallowReactive。
2、如果有一个对象数据,后续功能不会修改该对象中的属性,而是生新的对象来替换 ===> shallowRef。
2、readonly 与 shallowReadonly
- readonly: 让一个响应式数据变为只读的(深只读)。
- shallowReadonly:让一个响应式数据变为只读的(浅只读)。
- 应用场景: 不希望数据被修改时。
3、toRaw 与 markRaw
toRaw
作用:将一个由reactive生成的响应式对象转为普通对象。
使用场景:
- 用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新。
markRaw
作用:标记一个对象,使其永远不会再成为响应式对象。
应用场景:
- 有些值不应被设置为响应式的,例如复杂的第三方类库等。
- 当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能
4、customRef
作用:创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。
实现防抖效果
<template> <input type="text" v-model="keyWord" /> <h3>{{ keyWord }}</h3> </template> <script> import { customRef } from "vue"; export default { name: "App", setup() { //自定义一个ref——名为:myRef function myRef(value, delay) { let timer; return customRef((track, trigger) => { return { get() { console.log(`有人从myRef这个容器中读取数据了,我把${value}给他了`); track(); // 通知Vue追踪value的变化(提前和get商量一下,让他认为这个value是有用的) return value; }, set(newValue) { console.log(`有人把myRef这个容器中数据改为了:${newValue}`); clearTimeout(timer); timer = setTimeout(() => { value = newValue; trigger(); // 通知Vue去重新解析模板 }, delay); }, }; }); } // let keyWord = ref('hello') //使用Vue提供的ref let keyWord = myRef("hello", 500); //使用程序员自定义的ref return { keyWord }; }, }; </script>
5、provide 与 inject
作用:实现祖与后代组件间通信
套路:父组件有一个 provide 选项来提供数据,后代组件有一个 inject 选项来开始使用这些数据
具体写法
祖组件中:
setup(){ ...... let car = reactive({name:'奔驰',price:'40万'}) provide('car',car) // 给自己的后代组件传递数据 ...... }
后代组件中:
setup(props,context){ ...... const car = inject('car') // 拿到祖先的数据 return {car} ...... }
6、响应式数据的判断
isRef: 检查一个值是否为一个 ref 对象。
isReactive: 检查一个对象是否是由 reactive 创建的响应式代理。
isReadonly: 检查一个对象是否是由 readonly 创建的只读代理。
isProxy: 检查一个对象是否是由 reactive 或者 readonly 方法创建的代理。
九、新的组件
1、Fragment
在Vue2中: 组件必须有一个根标签
在Vue3中: 组件可以没有根标签, 内部会将多个标签包含在一个Fragment虚拟元素中
好处: 减少标签层级, 减小内存占用
2、Teleport
Teleport 是一种能够将我们的组件html结构移动到指定位置的技术。
3、Suspense
等待异步组件时渲染一些额外内容,让应用有更好的用户体验
使用步骤:
异步引入组件
import {defineAsyncComponent} from 'vue' const Child = defineAsyncComponent(()=>import('./components/Child.vue'))
使用Suspense包裹组件,并配置好default与 fallback
<template> <div class="app"> <h3>我是App组件</h3> <Suspense> //default:就是组件要显示的内容 <template v-slot:default> <Child/> </template> //fallback:就是组件没加载完全的“备胎” <template v-slot:fallback> <h3>加载中.....</h3> </template> </Suspense> </div> </template>
十、其他变化
1、data选项应始终被声明为一个函数
2、过渡类名的更改
//Vue2.x写法 .v-enter, .v-leave-to { opacity: 0; } .v-leave, .v-enter-to { opacity: 1; } //Vue3.x写法 .v-enter-from, .v-leave-to { opacity: 0; } .v-leave-from, .v-enter-to { opacity: 1; }
3、移除keyCode作为 v-on 的修饰符,同时也不再支持config.keyCodes
4、移除v-on.native修饰符
5、移除过滤器(filter)
哔哩哔哩的尚硅谷教学视频-笔记
链接:https://www.bilibili.com/video/BV1Zy4y1K7SH?p=158
这篇关于vue3的新特性的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-16Vue3资料:新手入门必读教程
- 2024-11-16Vue3资料:新手入门全面指南
- 2024-11-16Vue资料:新手入门完全指南
- 2024-11-16Vue项目实战:新手入门指南
- 2024-11-16React Hooks之useEffect案例详解
- 2024-11-16useRef案例详解:React中的useRef使用教程
- 2024-11-16React Hooks之useState案例详解
- 2024-11-16Vue入门指南:从零开始搭建第一个Vue项目
- 2024-11-16Vue3学习:新手入门教程与实践指南
- 2024-11-16Vue3学习:从入门到初级实战教程