vue3快速上手

2023-12-15 18:34:08

一 创建Vue3.0工程

1.使用vue-cli创建

## 查看@vue/cli版本,确保@vue/cli版本在4.5.0以上
vue --version
##  安装或者升级@vue/cli
npm install -g @vue/cli
## 创建
vue create vue_test
## 启动
cd vue_test
npm run serve

2.使用vite创建

## 创建工程
npm init vite-app <project-name>
## 进入工程目录
cd <project-name>
## 安装依赖
npm install
## 运行
npm run dev

二 常用composition API

1.setup

1.理解:vue3.0中的一个新的配置项,值为一个函数
2.setup是所有composition api(组合式API)的起始
3.组件中所用到的:数据 方法等,均需要配置在setup中
4.setup函数的两种返回值:
i:若返回一个对象,则对象中的属性 方法,在模板中均可以直接使用
ii:若返回一个渲染函数;则可以自定义渲染内容
5.注意点:
i:尽量不要与vue2.x配置混用
 	vue2.x配置(data,methods,computed...)中可以访问到setup中的属性 方法。
 	但在setup中不能访问到vue2.x配置(data,methods,computed...)
 	如果有重名,setup优先
 ii:setup不能是一个async函数,因为返回值不再是return的对象,而是promise,模板看不到return对象中的属性

2.ref函数

作用:定义一个响应式的数据
语法:`const xxx = ref(initValue)`
	创建一个包含响应式数据的引用对象(reference对象,简称ref对象)
	js中操作数据:xxx.value
	模板中读取数据:不需要.value,直接`<div>{{xxx}}</div>`
备注:
	接收的数据可以是:基本类型 也可以是对象类型
	基本类型的数据:响应式依然是靠Object.defineProperty()的get与set完成的
	对象类型的数据:内部求助了vue3.0中的一个新函数-reactive函数

3.reactive函数

作用;定义一个对象类型的响应式数据(基本类型不要用它,要用ref函数)
语法:const 代理对象= reactive(源对象) 接收一个对象(或数组),返回一个代理对象
reactive定义的响应式数据是深层次的
内部基于es6的proxy实现,通过代理对象操作源对象内部数据进行操作

4.vue3.0中的响应式原理

1.vue2.x的响应式
实现原理;
	对象类型:通过Object.defineProperty()对属性的读取,修改进行拦截(数据劫持)
	数组类型:通过重写更新数组的一系列方法来实现拦截。(对数组的变更方法进行了包裹)
	```js
	Object.defineProperty(data,'count',{
		get(){},
		set(){}
})
	存在问题:
		新增属性 删除属性,界面不会更新。
		直接通过下标修改数组,界面不会自动更新
#####  2.vue3.0的响应式
实现原理:
	通过proxy代理:拦截对象中任意属性的变化,包括:属性值的读写,属性的添加,属性的删除等。
	通过Reflect反射:对源对象的属性进行操作
```js
new Proxy(data,{
	//拦截读取属性值
	get(target,prop){
		return Reflect.get(target,prop)
	},
	//拦截设置属性值或添加新属性
	set(target,prop,value){
		return Reflect.set(target,prop,value)
	},
	//拦截删除属性
	deleteProperty(target,prop){
		return Reflect.deleteProperty(target,prop)
	}
})
proxy.name = 'tom'

5.reactive对比ref

从定义数据角色对比:
ref用来定义:基本类型数据。
reactive用来定义:对象(或数组)类型数据。
备注:ref也可以用来定义对象(或数组)类型数据,它内部会自动通过reactive转为代理对象。
从原理角度对比;
ref通过Object.defineProperty()的get与set来实现响应式(数据劫持)。
reactive通过使用proxy来实现响应式(数据劫持),并通过reflect操作源对象内部的数据。
从使用角度对比:
ref定义的数据:操作数据需要.value,读取数据时模板中直接读取不需要.value。
reactive定义的数据:操作数据与读取数据:均不需要.value。

6.setup的两个注意点

setup执行的时机:
在beforeCreate之前执行一次,this是undefined。
setup的参数:
props:值为对象,包含;组件外部传递过来,且组件内部声明接收了的属性
context:上下文对象
attrs:值为对象,包含:组件外部传递过来,但没有在props配置中声明的属性,相当于:this. a t t r s s l o t : 收到的插槽内容,相当于 t h i s . attrs slot:收到的插槽内容,相当于this. attrsslot:收到的插槽内容,相当于this.slots
emit:分发自定义事件的函数,相当于this.$emit

7.计算属性与监视

1.computed函数

与vue2.x中computed配置功能一致。
写法:

import {computed} from 'vue'
setup(){
	...
	//计算属性——简写
	let fullName = computed(()=>{
		return person.firstName+'-'+person.lastName;
	})
	//计算属性——完整
	let fullName = computed({
		get(){
			return person.firstName+'-'+person.lastName
		},
		set(value){
			const nameArr = value.split('-');
			person.firstName = nameArr[0];
			person.lastName = nameArr[1]
		}
	})
}
2.watch函数

与vue2.x中watch配置功能一致
两个小坑:
监视reactive定义的响应式数据时,oldValue无法正确获取,强制开启了深度监视(deep配置无效)
监视reactive定义的响应式数据中某个属性时,deep配置有效

//情况一:监视ref定义的响应式数据
watch(sum,(newValue,oldValue)=>{
	console.log('sum变化了',newValue,oldValue)
},{immediate:true})
//情况二:监视多个ref定义的响应式数据
watch([sum,msg],(newValue,oldValue)=>{
	console.log('sum或msg变化了',newValue,oldValue)
})
//情况三:监视reactive定义的响应式数据
//若watch监视的是reactive定义的响应式数据,则无法正确获得oldValue
//若watch监视的是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})
//特殊情况
watch(()=>person.job,(newValue,oldValue)=>{
	console.log('person的job变化了',newValue,oldValue);
},{deep:true})//此处由于监视的是reactive定义的对象中的某个属性,所以deep配置有效
3.watchEffect函数
watch的套路是:既要指明监视的属性,也要指明监视的回调
watchEffect的套路是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性
watchEffect有点像computed:
	但computed注重的计算出来的值,所以必须要写返回值
	而watchEffect更注重的是过程,所以不用写返回值

8.生命周期

1.shallowReactive与shallowRef

shallowReactive:只处理对象最外层属性的响应式(浅响应式)
shallowRef:只处理基本数据类型的响应式,不进行对象的响应式处理
什么时候使用?
如果有一个对象数据,结构比较深,但变化时只是外层属性变化===》shallowReactive
如果有一个对象数据,后续功能不会修改该对象中的属性,而是生成新的对象来替换 --》shallowRef

2.toRaw与markRaw

toRaw:将一个由reactive生成的响应式对象转为普通对象
使用场景;用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面的更新变化
markRaw:标记一个对象,使其永远不会再成为响应式对象
有些值不应被设置为响应式的,例如复杂的第三方类库等
当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能。

3.customRef

创建一个自定义的ref,并对其依赖项跟踪和更新触发进行显式控制。
实现防抖效果:

<template>
	<input type='text' v-model="keyword">
	<h3>{{keyword}}</h3>
</template>
<script>
import {ref,customRef} from 'vue';
export default{
	name:'Demo',
	setup(){
		//let keyword = ref('hello')//使用vue准备好的内置ref
		//自定义一个myRef
		function myRef(value,delay){
			let timer
			//通过customRef去实现自定义
			return customRef((track,trigger)=>{
				return{
					get(){
						track()//告诉vue这个value值是需要追踪的
						return value
					},
					set(newValue){
						clearTimeout(timer);
						timer = setTimeout(()=>{
							value = newValue;
							trigger();//告诉vue去更新界面
						},delay)
					}
				}
			})
		}
		let keyword = myRef('hello',500)//使用程序员自定义的ref
		return{
			keyword
		}
	}
}
</script>
4.provide与inject

作用:实现祖辈与后代组件间的通信
套路:父组件有一个provide选项来提供数据,后代组件有一个inject选项来开始使用这些数据
具体写法:
i:祖辈组件中:

setup(){
	let car = reactive({name:'奔驰',price:'40万'})
	provide('car',car);
}

ii:后代组件中:

setup(){
	const car = inject('car');
	return{car}
}

三 新的组件

1.teleport

teleport是一种能够将我们的组件html结构移动到指定位置的技术

<teleport to="移动位置">
	<div v-if="isShow" class="mask">
		<div class="dialog">
			<h3>我是一个弹窗</h3>
			<button @click="isShow=!isShow">关闭</button>
		</div>
	</div>
</teleport>

2.suspense

等待异步组件时渲染一些额外的内容,让应用有更好的用户体验
使用步骤;
异步引入组件:

import {defineAsyncComponent} from 'vue';
const Child = defineAsyncComponent(()=>import('./components/Child.vue'))

使用suspense包裹组件,并配置好default与fallback

<template>
	<div class="app">
		<h3>我是app组件</h3>
		<Suspense>
			<template v-slot:default>
				<child />
			</template>
			<template v-slot:fallbacl>
				<h3>加载中...</h3>
			</template>
		</Suspense>
	</div>
</template>

四 其它

1.全局API的转移

vue2.x有许多全局api和配置
例如:注册全局组件,注册全局指令等

//注册全局组件
Vue.component('MyButton',{
	data:()=>({
		count:0
	}),
	template>'<button @click="count++">clicked {{count}} times.</button>'
})
//注册全局指令
Vue.directive('focus',{
	inserted:el=>el.focus()
})

文章来源:https://blog.csdn.net/yehaocheng520/article/details/134925301
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。