ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

VUE3 手册

2021-11-26 11:01:57  阅读:282  来源: 互联网

标签:const name import 手册 reactive VUE3 组件 router


setup

setup函数,是在beforeCreate之前执行(创建实例前$el)。由于在执行setup 时尚未创建组件实例,因此在 setup 选项中没有 this。

setup 参数
使用setup时,它接受两个参数:

  1. props: 组件传入的属性
  2. context:包含3个属性

props是响应式的, 当传入新的props 时,会及时被更新。由于是响应式的, 所以不可以使用ES6解构,解构会消除它的响应式。这段代码会让props不再支持响应式:

import { defineComponent } from 'vue'
export default defineComponent ({
	props: { name: '冷冬' },
    setup(props, context) {
        let name = props.name
        console.log(name);
        return { name }
    },
})

context提供了最常用的三个属性:attrsslotemit,分别对应Vue2中的 a t t r 属 性 、 s l o t 插 槽 和 attr属性、slot插槽 和 attr属性、slot插槽和emit发射事件。

	context.attrs:传入组件中但是未被props接收的对象。
	context.emit:用于触发当前组件实例上的传值事件。
	context.slots:用来访问被插槽分发的内容(一般用于使用渲染函数来书写一个组件时)

数据定义

  1. ref:创建响应式的数据变量。传入的为基本数据类型,例如字符串、数字、boolean 等,返回值是一个响应式的对象,这个对象上只包含一个 value 属性
  2. isRef:判断生成的响应式数据是否是通过 ref 方法生成的(是true、否false)
import { ref } from 'vue'
setup() {
	//定义
    const msg = ref('你好') 
    //修改
    const changeMsg =()=>{
      msg.value ='msg被改了'
    }
    console.log("isRef:",isRef(msg));    // isRef:true
    //导出
    return { 
     msg,
     changeMsg
    }
  }
  1. reactive:创建响应式的数据对象。传入的为引用类型,例如数组、对象等,但不能代理基本类型值,返回一个响应式的数据对象。
  2. isReactive: 判断生成的响应式数据是否是通过 isReactive 方法生成的,还能判断readonly代理的对象是否是由reactive创建(是true、否false)
  3. toRefs:将一个 reactive 对象转化为属性全部为 ref 对象的普通对象
  4. JSON.parse(JSON.stringify(Array)):阻止数据响应式的发生。
<div>{{ msg }}</div>

import { reactive } from 'vue'
setup() {
        //定义
        const state = reactive({
            msg: '你好'
        })
        //修改
        const changeMsg = () => {
            state.msg = 'msg被改了'
        }
        console.log("state:",isReactive(state));   // state:true
        //导出
        return {
            ...toRefs(state),
            changeMsg
        }
    }
  1. readonly:创建一个只读代理,对变量创建只读。
  2. isReadonly:检查代理是否由readonly创建(是true,否false)。
import { readonly } from 'vue';
export default {
    setup() {
        const user = { name: 'ul', age: 20 };
        const copy = readonly(user);
        
		const users = reactive({ name: 'li', age: 30 });
        const copys = readonly(users);
        
		function getClick(){
			user.age++;		// 21
			copy.age++;     // warning! target is readonly.
			users.age++;	// 31
			copys.age++;    // warning! target is readonly.
		}
        return { copy,copys,getClick  };
    }
}
  1. isProxy:对象是否由reactive创建或者是readonly创建的代理(是true,否false)。
	// ref创建
	const refVal = ref(123);
	isProxy(refVal) // false
	
	// reactive创建
	const reactiveVal = reactive({ age: 20 });
	isProxy(reactiveVal) // true
  1. toRaw:返回reactive或者是readonly代理的原始对象。
	import { toRaw, reactive, readonly, isProxy } from 'vue';
	const user = { name:'立冬' };
	const reactiveUser = reactive(user);
	const readonlyUser = readonly(reactiveUser);
	
	console.log(toRaw(reactiveUser) === user) // true
	console.log(toRaw(readonlyUser) === user) // true
	console.log(isProxy(toRaw(reactiveUser))) // false
	console.log(isProxy(toRaw(readonlyUser))) // false
  1. markRaw: 标记一个对象,被标记后,该对象永远不会被转换为代理。
import { markRaw, reactive, isReactive } from 'vue';
const user = markRaw({});
const reactiveUser = reactive(user);
console.log(isReactive(reactiveUser)) // false

const reactiveUser1 = reactive({ user });
console.log(isProxy(toRaw(reactiveUser1))) // true 
console.log(isProxy(toRaw(reactiveUser1.user))) // false
// 在reactive创建代理时,被markRaw标记的嵌套对象不会被reactive创建代理
  1. shallowReactive:创建一个反应式代理,但是只是浅度创建。
import { isReactive, shallowReactive } from 'vue';
const data = shallowReactive({
    count: 10,
    content: {
        age: 20
    }
})
data.count++ // 11 逻辑层数据已发生变化,视图重新渲染
isReactive(data.content) // false 因为data.content属于深度嵌套,未被代理
data.content.age++ // 21 逻辑层数据已发生变化,但是视图层不会被更新渲染
  1. shallowReadonly:创建一个只读代理,但是只是浅度创建。
import { isReadonly, shallowReadonly } from 'vue';
const data = shallowReadonly({
    count: 10,
    content: {
        age: 20
    }
})
data.count++ // warning! target is readonly.
isReadonly(data.content) // false 因为data.content属于深度嵌套,未被代理
data.content.age++ // 21 深度嵌套未被代理,所以操作成功。

自定义指令:directive

	beforeMount() {},  		// 挂载前
	mounted() {},			// 挂载后
	beforeUpdate() {},		// 新增,更新前
	updated() {},			// 更新后
	beforeUnmount() {}, 	// 新增,卸载前
	unmounted() {}			// 卸载后

创建自定义指令

	//定义文档的标题: <div v-title>编辑框</div>
	const title = {
	   mounted(el:any) {
	       document.title = el.innerText;
	       el.remove();
	   },
	};

main.js 初始化自定义指令

	import * as directives from "./common/directives"   // 批量定义加载全局自定义指令
	Object.keys(directives).forEach((key:any) => {
	    app.directive(key, directives[key]);
	});

依赖注入

  1. provide:父组件创建
	<son-com ref="sonRef" :customForm=custom/>  
	
	setup(){
		// 使用ref给子组件传值
		const sonRef = ref(null);
		function popUpShow(){
			let item = {};
            sonRef.value.mySes = '懂经济';
		}

		// 给子组件传值
		const custom = reactive({
			name: '紫色'
		});
		
		// 使用依赖注入(provide )给子组件传值
		const person = reactive({name: 'bob', age:32});
		provide('person', person);
		
		return {
			sonRef, custom, popUpShow
		}
	}
  1. inject:子组件获取
	<div>{{ customForm.name }}</div>
    export default {
    	props: {
            customForm: Object
        },
	 	setup(props,context) {
	 		// 获取ref给子组件传的值	
			let mySes = ref(null);
			
			// 可以直接在html中使用customForm.name,在setup中使用要props.customForm
			console.log("父组件传的参数:",props.customForm);

			// 在所有子组件中都能获取provide中的数据
			const person = inject('person');
			return {
				mySes,
				loadDate,
				person
			}
		}
	}

监听属性

	watch(count, (val, old) => { 				// 监听字符串
		console.log("count改变了");
	});
	watch(()=>search.status, (val, old) => { 	// 监听对象
		console.log("count改变了");
	});
	// watch监听器:变化前,变化后的值都能获取。一次监听多个数据(对象,字符串)
	watch([()=>search.status, count], ([name, count], [preName, preCount]) => {
		console.log("search.status的数据变化:",name,preName,',count的数据变化:',count,preCount);
	});
	// watchEffect监听器:只能获取变化后的值,初始化时会执行一次回调函数来自动获取依赖(监控所有的响应式数据)
	watchEffect(() => {
		console.log(search.status);
		onInvalidate(() => {});   // 在watchEffect(重新运行/停止的时候)执行
	});

路由

路由的useRoute,useRouter 相当于vue2的 this. r o u t e ( ) , t h i s . route(),this. route(),this.router()。

	import { useRoute, useRouter } from 'vue-router'
	export default {
	  setup () {
	    const route = useRoute()
	    const router = useRouter()
	    
 		router.push({ name: 'home' })
	
	    return {}
	  },
	}
  1. useRoute:获取当前的路由信息
	 $route.path      	字符串,对应当前路由的路径,总是解析为绝对路径,如"/foo/bar"。
	 $route.params    	一个 key/value 对象,包含了动态片段和全匹配片段,如果没有路由参数,就是一个空对象。
	 $route.query     	一个 key/value 对象,表示 URL 查询参数。如果没有查询参数,则是个空对象。
	 $route.hash      	当前路由的hash值 (不带#) ,如果没有 hash 值,则为空字符串。
	 $route.fullPath  	完成解析后的 URL,包含查询参数和hash的完整路径。
	 $route.matched   	数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。
	 $route.name		当前路径名字
	 $route.meta  		路由元信息
  1. useRouter:全局路由的实例,是router构造方法的实例。
 	$router.push('/home/index')				// 	/home/index
    $router.push({path:'/home/index'})		// 	/home/index
    $router.push({name:'user', params:{userId:123}})  			//  跳转到路由的名称
    $router.push({path:'/register/index',query:{plan:'123'}})   //  /register/index?plan=123
    
    <router-link :to="{path:`/home/edit/${ props.item.id }`}" tag="a" target="_blank" ></router-link>
    注意:push方法其实和<router-link></router-link>是等同的。
    push方法的跳转会向 history 栈添加一个新的记录,当我们点击浏览器的返回按钮时可以看到之前的页面。

	$router.go(1)   // 前进
	$router.go(-1)  // 后退
	$router.replace('/search');  // 

 	{ path: '/:pathMatch(.*)*' }   // 没有匹配的路由

自定义 Hooks

vue3 的 hook 函数 相当于 vue2 的 mixin, 不同在与 hooks 是函数。

	import { getCurrentInstance,ref } from 'vue'
	import { useRouter } from 'vue-router';
	const right = () => {
		let index = ref('123');
		return {
			index
		}
	}
	export { right }

getCurrentInstance

获取当前组件的实例、上下文。

	import { getCurrentInstance } from 'vue';
	
	// 获取当前组件实例
	const instance = getCurrentInstance();

	// 获取当前组件的上下文,下面两种方式都能获取到组件的上下文。
	const { ctx }  = getCurrentInstance();  //  方式一,这种方式只能在开发环境下使用,生产环境下的ctx将访问不到
	const { proxy }  = getCurrentInstance();  //  方式二,此方法在开发环境以及生产环境下都能放到组件上下文对象(推荐)
	// ctx 中包含了组件中由ref和reactive创建的响应式数据对象,以及以下对象及方法;
	proxy.$attrs
	proxy.$data
	proxy.$el
	proxy.$emit
	proxy.$forceUpdate
	proxy.$nextTick			// 开启异步任务
	proxy.$options
	proxy.$parent
	proxy.$props
	proxy.$refs
	proxy.$root			// proxy.$root.$route   proxy.$root.$router
	proxy.$slots
	proxy.$watch

修饰符

	.stop		// 阻止冒泡行为,不让当前元素的事件继续往外触发
	.prevent	// 阻止事件本身行为,如阻止超链接的点击跳转,form表单的点击提交
	.capture	// 改变js默认的事件机制,默认是冒泡,capture功能是将冒泡改为倾听模式
	.self		// 只有是自己触发的自己才会执行,如果接受到内部的冒泡事件传递信号触发,会忽略掉这个信号
	.once		// 点击事件将只会触发一次
	.passive	//	滚动事件的默认行为 (即滚动行为) 将会立即触发,而不会等待 onScroll 完成。这个 .passive 修饰符尤其能够提升移动端的性能。
	.keyup		// 按键修饰符
	.exact 		// 修饰符允许你控制由精确的系统修饰符组合触发的事件。

	.passive 和 .prevent 不能一起使用(.prevent 将会被忽略)
	.self 和 .stop 区别:
		self只响应当前元素自身触发的事件,不会响应经过冒泡触发的事件,并不会阻止冒泡继续向外部触发。
		stop是从自身开始不向外部发射冒泡信号
		

全局命令

ref

	<p v-for="(item,index) in renderData" :key="index" ref="nodes"></p>
	console.log(this.$refs.nodes) // vue3 返回所有循环的p元素节点
	console.log(this.$refs.nodes) // vue2 返回循环后最后一个P元素节点

v-if和v-for优先级

	当v-if和v-for同时作用于一个元素上时:
	Vue2.x中v-for的优先级会高于v-if;
	Vue3.x中v-if的优先级会高于v-for;
	使用禁忌:Vue3.x中不能将v-for和v-if放在同一个元素上。只能使用v-for嵌套v-if使用
	使用建议:官方建议使用计算属性来处理,即提高性能,又能兼容Vue3.x。

mount(节点挂载)

	在 main.js 挂载
	import { createApp } from 'vue';
	const app = createApp({});
	app.mount('#my-app');

unmount(取消挂载)

	在main.js 中取消挂载
	import { createApp } from 'vue';
	const app = createApp({})
	// 挂载
	app.mount('#my-app');
	// 取消挂载
	setTimeout(() => app.unmount('#my-app'), 2000);

use(插件)

与Vue 2.x类似,如果参数为对象,则需要提供一个install的方法;如果参数本身就是一个方法,那么这个方法将默认为安装插件的方法;在进行方法的调用时,Vue将作为第一个参数传入方法中。

	注意:同一个插件多次调用use时,该插件也只能被安装一次。
	
	import { createApp } from 'vue';
	const app = createApp({})
	import router from './router/index';
	app.use(router);
	app.mount('#my-app');

config:Vue应用配置

config:包含Vue应用程序全局配置的对象,在挂载应用之前配置相应的属性。

devtools(类型: Boolean,默认: true):配置是否允许开启vue-devtools检查,一般在开发环境中是true,生产环境中为false。

errorHandler(类型:Function,参数err:错误内容,vm:对应的实例,info:Vue特定的错误信息,如某个生命周期中出现的错误):为组件在实例化或渲染过程中捕获到的错误进行处理的方法。

warnHandler(类型:Function, 参数msg:警告内容,vm:对应的实例,trace:组件的层次追踪):为Vue在运行时捕获到的警告进行处理的方法。

globalProperties(类型:any):用于添加到应用程序中任何组件都能使用的全局属性,当与组件内部的属性冲突时,将优先使用组件内部的属性值。可代替Vue2中的Vue.prototype。

isCustomElement(类型:(tag: string) => boolean):用于来识别Vue之外的自定义元素(如,三方web组件api),如果组件或元素符合这个条件,则组件不会被实例化,Vue也不会对组件或元素发出警告信息。

optionMergeStrategies(类型:[key: string] : Function):为Vue自定义选项定义合并策略。

performance(类型:boolean,默认:false):设置此项为true时,将在浏览器的devtool性能/时间线面板中启用组件的初始化,编译,渲染及修补程序跟踪。仅在开发模式和支持performance.mark api的浏览器中工作

生命钩子

在这里插入图片描述

let {  onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted, one rrorCaptured, onRenderTracked, onRenderTriggered} = Vue;
setup() {
    // vue3.x生命周期写在setup中
    onBeforeMount(() => {      });   	// 挂载开始之前被调用
    onMounted(() => {          });   	// 实例被挂载后调用,不会保证所有的子组件也被挂载完
    onBeforeUpdate(() => {     });   	// 更新渲染DOM前
    onUpdated(() => {          });		// 更新渲染DOM完成,不会保证所有的子组件也都一起被重绘
    onBeforeUnmount(() => {    });		// 销毁组件实例之前,此时实例仍然是完全正常的
    onUnmounted(() => {        });    	// 销毁组件实例完成,组件实例的所有指令被解除绑定、事件侦听器被移除、子组件实例被卸载。
    one rrorCaptured(() => {    });  	// 当捕获一个来自子孙组件的错误时被调用
    
	onRenderTriggered((event) => {    });  // 状态触发(它会跟踪你变化值的信息,并且新值和旧值都会给你明确的展示出来)
	onRenderTracked((event) => {      });  // 状态跟踪(所有我们用return返回去的值,它都会跟踪)
},

如果把 onRenderTracked 比喻成散弹枪,每个值都进行跟踪,那 onRenderTriggered 就是狙击枪,只精确跟踪发生变化的值,进行针对性调试。

	event对象属性的详细介绍:
		- key 那边变量发生了变化
		- newValue 更新后变量的值
		- oldValue 更新前变量的值
		- target 目前页面中的响应变量和函数

标签:const,name,import,手册,reactive,VUE3,组件,router
来源: https://blog.csdn.net/weixin_40565328/article/details/121244042

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有