定制开发vue3的新特性

的新特性

一、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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

二、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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

三、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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

三、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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

三、计算属性watch

和计算属性差不多,在vue3中和只是语法上上的改变。
注意点:

  • 监视ref定义的响应式数据时: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配置有效
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

四、函数

watch是:既要指明监视的属性,也要指明监视的回调。
watchEffect是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。
这个函数的功能和计算属性差不多,但是

  • 但computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值。
  • 而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值。
//watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调。watchEffect(()=>{    const x1 = sum.value    const x2 = person.age    console.log('watchEffect配置的回调执行了')})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

五、生命周期钩子

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;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

在组件中使用

<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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

七、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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

八、其他新特性

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

5、provide 与 inject

作用:实现祖与后代组件间通信

套路:父组件有一个 provide 选项来提供数据,后代组件有一个 inject 选项来开始使用这些数据

具体写法
祖组件中:

setup(){	......    let car = reactive({name:'奔驰',price:'40万'})    provide('car',car) // 给自己的后代组件传递数据    ......}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

后代组件中:

setup(props,context){	......    const car = inject('car') // 拿到祖先的数据    return {car}	......}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

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'))
  • 1
  • 2
  • 3

使用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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

十、其他变化

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;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

3、移除keyCode作为 v-on 的修饰符,同时也不再支持config.keyCodes

4、移除v-on.native修饰符

5、移除过滤器(filter)

哔哩哔哩的尚硅谷教学视频-笔记
链接:https://www.bilibili.com/video/BV1Zy4y1K7SH?p=158

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发