(zichao)VUE3基础(仅作简单整理,未深入探究)

目录

  • 一、创建Vue3.0工程
  • 二、setup
    • (一)理解:
    • (二)作用
    • (三)setup函数的两种返回值:
    • (四)注意点
    • (五)声明一个setup
  • 三、ref函数
    • (一)作用
    • (二)语法
    • (三)操作数据
    • (四)注意
  • 四、reactive函数
    • (一)作用
    • (二)语法
    • (三)深层次的
  • 五、setup的两个注意点
    • (一)setup执行的时机
    • (二)setup的参数
      • 1、props
      • 2、context
  • 六、计算属性
    • (一)写法
  • 七、watch函数
    • (一)写法
    • (二)watchEffect函数
  • 八、生命周期
  • 九、自定义hook函数
  • 十、toRef和toRefs
  • 十一、其它 Composition API
    • (一)shallowReactive 与 shallowRef
    • (二)readonly 与 shallowReadonly
    • (三)toRaw 与 markRaw
    • (四)provide 与 inject
      • 1、作用
      • 2、实现
  • 十二、响应式数据的判断
  • 十三、新的组件
  • (一)Fragment
  • (二)Teleport
  • 十四、其他
    • (一)全局API的转移
    • (二)过度类名的更改
    • (三)移除过滤器(filter)

一、创建Vue3.0工程

//查看@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

二、setup

(一)理解:

Vue3.0中一个新的配置项,值为一个函数。

(二)作用

setup是所有父亲,组件中所用到的:数据、方法等等,均要配置在setup中。

(三)setup函数的两种返回值:

若返回一个对象,则对象中的属性、方法, 在模板中均可以直接使用。(重点关注!)

(四)注意点

  1. 尽量不要与Vue2.x配置混用,如果有重名, setup优先。
  2. setup不能是一个async函数,因为返回值不再是return的对象, 而是promise, 模板看不到return对象中的属性。(后期也可以返回一个Promise实例,但需要Suspense和异步组件的配合)

(五)声明一个setup

setup(){
	//数据
	let name = '张三'
	let age = 18
	let a = 200
	//方法
	function sayHello(){
		alert(`我叫${name},我${age}岁了,你好啊!`)
	}
	//返回一个对象(常用)
	return {
		name,
		age,
		sayHello,
		a
	}
}

三、ref函数

(一)作用

定义一个响应式的数据

(二)语法

//引入
import {ref} from 'vue'
//创建一个包含响应式数据
const xxx = ref(initValue)

(三)操作数据

//JS中操作数据
xxx.value
 
//模板中读取数据
<div>{{xxx}}</div>

(四)注意

  1. 接收的数据可以是:基本类型、也可以是对象类型。
  2. 基本类型的数据:响应式依然是靠Object.defineProperty()getset完成的。
  3. 对象类型的数据:内部求助 了Vue3.0中的一个新函数—— reactive函数。

四、reactive函数

(一)作用

定义一个对象类型的响应式数据(基本类型不要用它,要用ref函数)

(二)语法

const 代理对象= reactive(源对象)接收一个对象(或数组),返回一个代理对象(Proxy的实例对象,简称proxy对象)

//引入reactive
import {reactive} from 'vue'
let person = reactive({
	name:'张三',
	age:18,
	job:{
		type:'前端工程师',
		salary:'30K',
		a:{
			b:{
				c:666
			}
		}
	},
	hobby:['抽烟','喝酒','烫头']
})

(三)深层次的

reactive定义的响应式数据是“深层次的”,对象和数组的增删改查都可以侦测到

五、setup的两个注意点

(一)setup执行的时机

在beforeCreate之前执行一次,this是undefined。

所以内部不能使用this

(二)setup的参数

1、props

值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性。

2、context

上下文对象

  1. attrs: 值为对象,包含:组件外部传递过来,但没有在props配置中声明的属性, 相当于 this.$attrs
  2. slots: 收到的插槽内容, 相当于 this.$slots
  3. emit: 分发自定义事件的函数, 相当于 this.$emit

六、计算属性

(一)写法

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

七、watch函数

(一)写法

//情况一:监视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})
  1. 监视reactive定义的响应式数据时:oldValue无法正确获取、强制开启了深度监视(deep配置失效)。
  2. 监视reactive定义的响应式数据中某个属性时:deep配置有效。

(二)watchEffect函数

不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。

import {watchEffect} from 'vue'
//watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调。
watchEffect(()=>{
	const x1 = sum.value
    const x2 = person.age
    console.log('watchEffect配置的回调执行了')
})

八、生命周期

Vue3.0也提供了 Composition API 形式的生命周期钩子,与Vue2.x中钩子对应关系如下:

  • beforeCreate===>setup()
  • created=======>setup()
  • beforeMount ===>onBeforeMount
  • mounted=======>onMounted
  • beforeUpdate===>onBeforeUpdate
  • updated =======>onUpdated
  • beforeUnmount ==>onBeforeUnmount
  • unmounted =====>onUnmounted
export default {
	name: 'Demo',
	setup(){
		console.log('---setup---')
		//数据
		let sum = ref(0)

	//通过组合式API的形式去使用生命周期钩子
	onBeforeMount(()=>{
		console.log('---onBeforeMount---')
	})
	onMounted(()=>{
		console.log('---onMounted---')
	})
	onBeforeUpdate(()=>{
		console.log('---onBeforeUpdate---')
	})
	onUpdated(()=>{
		console.log('---onUpdated---')
	})
	onBeforeUnmount(()=>{
		console.log('---onBeforeUnmount---')
	})
	onUnmounted(()=>{
		console.log('---onUnmounted---')
	})
	return {sum}
}

九、自定义hook函数

  1. 什么是hook?—— 本质是一个函数,把setup函数中使用的Composition API进行了封装。

  2. 类似于vue2.x中的mixin。

  3. 自定义hook的优势: 复用代码, 让setup中的逻辑更清楚易懂。

//创建hooks文件夹下创建usePoint
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
}
//组件直接使用
import usePoint from '../hooks/usePoint'
export default {
	name:'Test',
	setup(){
		const point = usePoint()
		return {point}
	}
}
<h2>我是Test组件</h2>
<h2>当前点击时鼠标的坐标为:x:{{point.x}},y:{{point.y}}</h2>

十、toRef和toRefs

  1. 作用:创建一个 ref 对象,其value值指向另一个对象中的某个属性。
  2. 语法:const name = toRef(person,'name')
  3. 应用: 要将响应式对象中的某个属性单独提供给外部使用时。
import {ref,reactive,toRef,toRefs} from 'vue'
export default {
	name: 'Demo',
	setup(){
		//数据
		let person = reactive({
			name:'张三',
			age:18,
			job:{
				j1:{
					salary:20
				
			}
		})
		//返回一个对象(常用)
		return {
			person,
			name:toRef(person,'name'),
			age:toRef(person,'age'),
			salary:toRef(person.job.j1,'salary'),
			...toRefs(person)//返回所有属性
		}
	}
}

十一、其它 Composition API

(一)shallowReactive 与 shallowRef

  1. shallowReactive:只处理对象最外层属性的响应式(浅响应式)。
  2. shallowRef:只处理基本数据类型的响应式, 不进行对象的响应式处理。

(二)readonly 与 shallowReadonly

  1. readonly: 让一个响应式数据变为只读的(深只读)。
  2. shallowReadonly:让一个响应式数据变为只读的(浅只读)。

(三)toRaw 与 markRaw

  1. toRaw:将一个由reactive生成的响应式对象普通对象。
  2. markRaw:标记一个对象,使其永远不会再成为响应式对象。

(四)provide 与 inject

1、作用

实现祖与后代组件间通信

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

2、实现

//父组件
let car = reactive({name:'奔驰',price:'40万'})
provide('car',car)
//子组件
const car = inject('car')
return {car}

十二、响应式数据的判断

  1. isRef: 检查一个值是否为一个 ref 对象
  2. isReactive: 检查一个对象是否是由 reactive 创建的响应式代理
  3. isReadonly: 检查一个对象是否是由 readonly 创建的只读代理
  4. isProxy: 检查一个对象是否是由 reactive 或者 readonly 方法创建的代理

十三、新的组件

(一)Fragment

  1. 在Vue2中: 组件必须有一个根标签
  2. 在Vue3中: 组件可以没有根标签, 内部会将多个标签包含在一个Fragment虚拟元素中
  3. 好处: 减少标签层级, 减小内存占用

(二)Teleport

什么是Teleport?—— Teleport 是一种能够将我们的组件html结构移动到指定位置的技术。

//此时被teleport包裹的元素会出现到to所指定的元素上,to可以指定元素名,类名
<button @click="isShow = true">点我弹个窗</button>
<teleport to="body">
	<div v-if="isShow" class="mask">
		<div class="dialog">
			<h3>我是一个弹窗</h3>
			<h4>一些内容</h4>
			<h4>一些内容</h4>
			<h4>一些内容</h4>
			<button @click="isShow = false">关闭弹窗</button>
		</div>
	</div>
</teleport>

十四、其他

(一)全局API的转移

将全局的API,即:Vue.xxx调整到应用实例(app)上

2.x 全局 API(Vue 3.x 实例 API (app)
Vue.config.xxxx app.config.xxxx
Vue.config.productionTip 移除
Vue.component app.component
Vue.directive app.directive
Vue.mixin app.mixin
Vue.use app.use
Vue.prototype app.config.globalProperties

(二)过度类名的更改

Vue2.x写法
css
.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;
}

(三)移除过滤器(filter)

过滤器虽然这看起来很方便,但它需要一个自定义语法,打破大括号内表达式是 “只是 JavaScript” 的假设,这不仅有学习成本,而且有实现成本!建议用方法调用或计算属性去替换过滤器。

你可能感兴趣的:(javascript,vue.js,前端)