【记录】Vue3

vue-cli创建

vue create [project_name]

vite创建

npm init @vitejs/app [project_name]
npm install

项目结构

//main.js
import { createApp } from 'vue';
import App from './App.vue';

createApp(app).mount('#app');

Composition API

组合式api。

Vue2是Options API。

(1)setup

  • 在beforeCreate之前就执行一次。
  • 尽量不要和vue2中的data、methods、computed、watch…混用。
  • vue2中的data、methods、computed、watch可以访问到setup中的属性方法,反之setup不能访问到vue2中的。
  • 如果变量、函数重名,setup优先。
  • this = undefined

(2)ref

  • 定义一个响应式数据,将传入的值包装成引用对象(Reference Implement)。
  • 基本数据类型用Object.defineProperty实现,引用类型数据用reactive函数实现。
  • 操纵数据需要.value,模板中读取数据不需要.value。

(3)reactive

  • 定义一个对象类型的响应式数据。
  • 用proxy实现。
  • 操纵数据和模板中读取数据不需要.value。

(4)computed

(5)watch

(6)watchEffect

<template>
//vue3中根标签可以不用div包裹了。
	<div>{{name}}</div>
	<div>{{age}}></div>
	<button @click="changeInfo"></button>
</template>

<script>
import { ref, reactive, computed, watch, watchEffect } from 'vue';

export default{
	name: 'component',
	props: ['msg', 'school'],
	emits: ['hello'],
	setup(props, context){
		//context包含attrs emit slot
		
		
		//ref reactive
		let name = ref('张三');
		let age = ref(18);
		let job = reactive({
			type: '前端工程师',
			salary: '30k'
		});
		let hobby = reactive(['抽烟', '喝酒', '烫头']);
		
		function changeInfo(){
			name.value = '李四';
			age.value = 19;
			
			// ref: job.value.type = 'a';
			job.type = '后端工程师';
			
			hobby[0] = '学习';
		}
		
		
		
		//computed
		let person = reactive({
			firstName: '张',
			lastName: '三'
		});
		//person.fullName = computed(()=>{
		//	return person.firstName + person.lastName;
		//});
		person.fullName = computed(()=>{
			get(){
				return person.firstName + '-' +person.lastName;
			},
			set(value){
				const names = value.split('-');
				person.firstName = names[0];
				person.lastName = names[1];
			}
		});
		
		
		
		//watch
		let sum = ref(0);
		let msg = ref('msg');
		//监听ref定义的数据
		watch(sum, (newValue, oldValue)=>{
			...
		});
		//监听多个ref定义的数据
		watch([sum, msg], (newValueArr, oldValueArr)=>{
			...
		}, {immediate: true});
		//监听reative定义的数据的全部属性
		//无法正确获取oldValue。
		//强制开启深度监视,deep配置无效。
		watch(person, (newValue, oldValue)=>{
			...
		});
		//监听reactive定义的数据的某个属性
		watch(()=>person.name, (newValue, oldValue)=>{
			...
		});
		//监听reactive定义的数据的某些属性
		watch([()=>person.name, ()=>person.age], (newValueArr, oldValueArr)=>{
			...
		})
		//监听reactive定义的数据的对象属性
		//deep配置有效。
		watch(()=>person.job, (newValue, oldValue)=>{
			...
		}, {deep: ture});
		
		
		
		// 回调内部用到的数据发生变化,就执行重新执行回调。(类似computed
		// computed注重的是计算出来的值,要有返回值;watch注重的是过程,不用写返回值。
		watchEffect(()=>{
			
		});
			
		
		return {
			name,
			age,
			changeInfo,
			
			person
		}
	}
}
</script>

(7)toRef、toRefs

setup(){
	...
	const name = toRef(person, 'name');
	const salary = toRef(person.job.j1, 'salary');
	
	return{
		...toRefs(person)
	}
}

(8)shallowRef

类似Ref,基本数据类型能实现响应式,引用数据类型直接不处理。

(9)shallowReactive

只考虑第一层的响应数据。

(10)readonly

参数为ref或者reactive处理后的。

(11)shallowReadonly

(12)toRaw

把响应式数据变成普通数据。

(13)markRow

标记一个对象,使其永远不会再变成响应式对象。
给对象添加非响应式的数据。

(14)customRef

创建自定义ref,并对其依赖项跟踪和更新触发进行显式控制。

<template>
	<input type="text" v-model="keyword">
	<h3>{{keyword}}</h3>
</template>

<script>
import {ref, customRef} from 'vue';
export default{
	name: 'app',
	setup(){
		let keyword = myRef('hello', 1000);
		
		function myRef(value, delay){
			let timer;
			return customRef((track, trigger)=>{
				return {
					get(){
						track(); // 追踪数据数据的变化
						return value;
					},
					set(newValue){
						if(timer) clearTimeout(timer);
						timer = setTimeout(()=>{
							value =  newValue;
							trigger(); // 通知vue重新解析模板
						}, delay);
					}
				}
			})
		
		}
		
		
		return{
			keyword
		}
	}
}
</script>

响应式数据的判断

(1)isRef

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

(2)isReactive

检查一个对象是否由reactive创建的响应式代理。

(3)isReadonly

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

(4)isProxy

检查一个对象是否由reactive或readonly方法创建的代理。

响应式原理

通过proxy拦截对象中任意属性的变化。
通过reflect对源对象的属性进行操作。

let p = new Proxy(person, {
	get(target, propName){
		return Reflect.get(target, propName);
	},
	// 新增也走set
	set(target, propName, value){
		Reflet.set(target, propName, value);
	},
	deleteProperty(target, propName){
		return Reflet.deleteProperty(target, propName);
	}
});

生命周期

beforeCreate
Created
beforeMount
Mounted
beforeUpdate
Updated
beforeUnmount
Unmounted

<script>
/*
	生命周期 => 组合式API
	beforeCreate => setup()
	created => setup()
	beforeMount => onBeforeMount
	mounted => onMounted
	beforeUpdate => onBeforeUpdate
	updated => onUpdated
	beforeUnmount => onBeforeUnmount
	unmounted => onUnmounted
*/		
import {ref, onBeforeMount } from 'vue';
export default{
	name: 'demo',
	setup(){
		onBeforeMount(()=>{
			...
		});
	
	}
}
</script>

自定义hook

本质是一个函数,把setup()中的一些逻辑操作进行封装,供多个组件复用。

// hooks/usePoint.js
export default function(){
	...
	return data;
}

	
// components/demo.vue
<script>
import {ref} from 'vue';
import usePoint from '../hooks/usePoint';
export 	default{
	setup(){
		...
		let point = usePoint();
		...
	}
}
</script>

provide、inject

//祖组件
setup(){
	...
	let car = reactive({name: 'a', price: 1});
	provide('car', car);
	...
}


//孙组件
setup(){
	let car = inject('car');
}

组件

(1)Fragment

在vue2中组件必须有一个根标签。
在vue3中组件可以没有根标签,内部将多个标签包含在一个Fragment虚拟元素中。

减少标签层级,减少内存占用。

(2)Teleport

<template>
	// to="#a"
	<teleport to="body">
		...
	</teleport>
</template>

(3)Suspendse

<template>
	<div class="app">
		<h3>app组件</h3>
		<Suspense>
			<template v-slot:default>
				<Child/>
			</template>
			<template v-slot:fallback>
				<h3>loading...</h3>
			</template>
		</Suspense>
	</div>
</template>

<script>
// 异步引入组件
import {defineAsyncComponent} from 'vue';
const Child = defineAsyncComponent(()=>import('./components/Child.vue'));	
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值