笔记文件,记录用,学习参考: 哔哩哔哩尚硅谷VUE

创建Vue3.0工程

1. 使用vue-cli创建

#检查vue脚手架版本
vue ---version
#若无,则需要安装或者升级
npm install -g @vue/cli
# 创建项目选择vue3
vue create xx
# 进入目录,运行
cd xx
npm run serve

2. 使用vite创建

官方文档: https://v3.cn.vuejs.org/guild/installation.html#vite

vite官网: https://vitejs.cn

优势

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

一些变化

常用Composition API

setup

  1. Vue3.0中的一个新的配置项(与vue2中的data、method等类似),值为一个函数。
  2. setup中可使用vue3中的Composition API(组合API)
  3. 组件中所用到的:数据、方法等等,均要配置在setup中
  4. setup函数的两种返回值:
    1. 若返回一个对象,则对象中的属性,方法,在模板中均可以直接使用
    2. 若返回一个渲染函数,则可以自定义渲染内容
  5. 注意
    1. 尽量不要与vue2混用。setup中无法访问vue2的配置(data、methods等),vue2配置中可以访问setup中的属性、方法;重名则setup优先
    2. setup不能是一个async函数,因为async返回值为promise对象,无法被模板使用。(需要Suspense和异步组件的配合)
<script>
export default {
  name: 'page-header',
  setup(){
    //数据
    let name = "name"
    //需要返回之后才能在模板中使用
    return{
      name,
    }
  }
}
</script>

ref

<script>
import {ref} from 'vue';
export default {
    name: 'page-aside',
    setup(){
        //创建引用实现对象
        let name = ref("导航");
        //修改后,会触发vue更新视图;ref创建的数据,需要使用.value才能使用,模板中不需要.value
        name.value = "nav";
        return{
            name,
        }
    }
}
</script>

reactive

<script>
import {ref,reactive} from 'vue';
export default {
    name: 'page-aside',
    setup(){
        //创建引用实例对象
        let name = ref("导航");
        let routers = reactive([
            {name:'推荐',icon:'icon-home',url:'/home'},
            {name:'最近',icon:'icon-recent',url:'/recent'},
        ])
  
        //响应式修改
        name.value = "nav";
        //reactive创建,无需.value
        routers[1].name = 'haha'
  
        return{
            name,
            routers
        }
    }
}
</script>

vue3.0中的响应式原理

vue2.x

vue3.0

//模拟vue3中实现响应式
let person = {
	name: 'xx',
	age: 18,
}
// 参数:被代理对象, 配置(可为空)
// 增(set)删(deleteProperty)改(set)查(get)
const p = new Proxy(person,{
	set(target,propName,value){
		console.log(`修改${propName},开始更新页面`)
		Reflect.set(target,propName,value);
	},
	get(target,propName){
		console.log(`读取${propName}`);
		return Reflect.get(target,propName);
	},
	deleteProperty(target,propName){
		console.log(`删除${propName}属性,更新页面`);
		return Reflect.deleteProperty(target,propName)
	}
})

p.name = 'tom'

reactive对比ref

setup的注意点

计算属性与监视

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];
		}
	})
}

watch函数

import {watch} from 'vue';
setup(){
	//1. 监视ref定义的响应式数据
	watch(sum,(newValue,oldValue)=>{
		console.log("sum变化了",newValue,oldValue);
	});

	//2. 监视多个ref定义的响应式数据,此时newValue和oldValue都是数组形式
	watch([sum,msg],(newValue,oldValue)=>{
		console.log("sum或msg变化了",newValue,oldValue);
	});

	//3. 监视reactive定义的响应式数据,无法正确获取oldValue,且强制开启深度监视
	watch(person,(newValue,oldValue)=>{
		console.log("person变化了",newValue,oldValue);
	},{immediate:true,deep:false});

	//4. 监视reactive定义的响应式数据中的某个属性;写成函数形式(如果直接写person.name则监视的只是一个拷贝后的字符串,无法做到响应)
	watch(()=>person.name,(newValue,oldValue)=>{
		console.log("person的name变化了",newValue,oldValue);
	})

	//5. 监视多个reactive定义的数据的属性
	watch([()=>person.name,()=>person.age],(newValue,oldValue)=>{
		console.log("person的name或age变化了",newValue,oldValue);
	});

	//6. 特殊:此处监视的为person的属性job,为一个正常对象,而非reactive定义过的Proxy对象,所以深度监视配置项是有效的(默认非深度监视)
	watch(()=>person.job,(newValue,oldValue)=>{
		console.log("person的job变化了",newValue,oldValue);
	},{deep:true})

}

watchEffect函数

watchEffect(()=>{
	const x1 = sum.value;
	const x2 = person.value;
	console.log("person或sum被修改")
})

生命周期

vue2中的生命周期

vue3中的生命周期

自定义hook函数

//useHelloWorld.js
import {onMounted} from 'vue';
export default function(){
	onMounted(()=>{
		console.log("Hello World!");
	})
}



//xx.vue
import useHelloWorld from './useHelloWorld.js'
...
setup(){
	useHelloWorld();
}

toRef&toRefs

setup(){
	const person = reactive({
		name: 'xx',
		age: 12,
	});
	const p2 = reactive({
		name2: 'xxx',
		age2: '25'
	})

	//对此name的修改相当于对person.name的修改(如果此处用person.name,则return的name为其字符串拷贝,无法实现响应式)
	return{
		name: toRef(person,'name'),
		...toRefs(p2); //返回p2所有属性的ref对象数组,使用...展开
	}
}

其他Composition API

shallowReactive与shallowRef

readonly与shallowReadonly

toRaw与markRaw

customRef

防抖:

import {ref,customRef} from 'vue';
...
setup(){
	function myRef(value,delay){
		let timer;
		//返回一个customRef函数定义的对象(相当于ref()返回的对象)
		return customRef((track,trigger)=>{
			return{
				get(){
					track();  //标记/收集依赖,当此数据触发更新时,使用此数据的位置皆可更新
					return value;
				},
				set(newValue){
					clearTimeout(timer);
					timer = setTimeout(()=>{
						value = newValue;
						trigger();  //触发更新
					},delay)
				}
			}
		})
	}
	//使用
	let keyword = meRef('hello',500)
	return {keyword}
}

provide 与 inject

//father.vue
let p = reactive({name:"ss",age:18});
provide('person',p);


//child.vue
const p = inject('person');
return{p}

响应式数据的判断

新的组件

Fragment

Teleport

<teleport to="body">
	<div class="dialog">DIALOG</div>
	<!-- 此html结构会被插入到body内 -->
</teleport>

Suspense

异步引入组件

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

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

<template>
	<div class="app">
		<div>App</div>
		<Suspense>
			<template v-slot:default>
				<Child/>
			</template>
			<template v-slot:fallback>
				<h3>加载中...</h3>
			</template>
		</Suspense>
	</div>
</template>

其他变化

全局API转移

Vueapp
Vue.config.xxxapp.config.xxx
Vue.config.productionTip移除
Vue.componentapp.conponent
Vue.directiveapp.directive
Vue.mixinapp.mixin
Vue.useapp.use
Vue.prototypeapp.config.globalProperties

其他改变

/*vue2*/
.v-enter,.v-leave-to{}
.v-leave,.v-enter-to{}
/*vue3*/
.v-enter-from,.v-leave-to{},
.v-leave-from,.v-enter-to{}
DORAKIKA
我是一个喜欢折腾的前端工程师,对一切新鲜事物充满好奇,希望我的文章能给你带来思考和帮助
👋我是DORAKIKA
分享作者『DORAKIKA』发表的文章『Vue3学习笔记』https://blog.dorakika.cn/post/20220529/
© 请您在需要时著名本文内容来源信息,若在文末注明“参考、扩展”等字样涉及转载第三方内容,请您一同复制
设计模式之单例模式
设计模式之单例模式
单例模式时一种较为简单的设计模式,在js中可使用全局对象进行创建,而无需像其他语言中需要先定义类再创建实例等复杂操作。
添加一个留言弹幕页面
添加一个留言弹幕页面
搞得像直播间弹幕一样,TuT