vue3 学习笔记

102 阅读5分钟
重置数据
class State {
  count=0
  user={
    name:''
  }
}
const state=reactive(new State())
//重置
 Object.assign(state, (new State()))
父子组件传值
// 父组件
<child :info='parentMsg'>
const parentMsg=ref('父组件传的值')

//子组件
<div>n拿到父组件的值{{info}}</div>
const props=defineProps({
	info:String,//子组件接受父组件传过来的值
})
const {info}=toRefs(props) //使用父组件传递过来的值
子组件向父组件传值
// 子组件传递事件
<button @click='clickChild'>点击子组件</button>
const emit=defineEmits(['clickChild'])
const clickChild=()=>{
	let params={
		content:'b'
	}
	emit('clickChild',params)
}

// 父组件接受
<div>w我是父组件
	<child @clickChild='clickEven'></child>
	<p>z子组件传递的值是{{result}}</p>
</div>
const result=ref('')
const clickEven=(val)=>{
	console.log(val);
	result.value=val.content
}

父组件获取子组件中的属性值
//子组件
<div>
	<h2>我是子组件</h2>
	<p>x性别{{sex}}</p>
</div>
let sex=ref('男')
let info=reactive({
	like:'王者荣耀',
	age:18
})
defineExpose({sex,info})

//父组件显示
<div>
	我是父组件
	<child ref='testcomRef'></child>
	<button @click='getSonHander'>h获取子组件的值</button>
</div>
const testcomRef=ref()
const getSonHander=()=>{
	console.log('子组件中的性别:',testcomRef.value.sex)
	console.log('获取子组件中的其他信息',testcomRef.value.info)
}
获取refs表单验证
<el-form ref='formRef'></el-form>
// 方法1
const formRef=ref(null)
console.log(form.value) //获取到的dom树
// 方法2 
import {getCurrentInstance} from 'vue'
const {proxy} =getCurrentInstance()
proxy.$refs.formRefs.validate((val)=>{})
// 方法3 ts
const formRef=ref<InstanceType<typeof ChildComponent>>()
//也可以这样 获取elementui的组件类型
const formRef=ref<InstanceType<typeof ElForm>>()
formRef.value>validate((val)=>{})
全局注册(属性、方法)
//main.js
const app=createApp(App)
app.config.globalProperties.name='名称'

//在其他组件中被调用
const {appContext} =getCurrentInstance()
const global=appContext.config.globalProperties
console.log(global.name)
初始化生命周期
<script setup>
import {onMounted} from 'vue'
const getData=()=>{}
onMounted(()=>{
	getData()
})
</script>
解除绑定(清除定时器,监听之类的)
<script setup>
import {onBeforeUnmount,onDeactivated} from 'vue'
onBeforeUnmount(()=>{
	clearTimeout(timer)
	window.removeAddEventListener('...')
})
onDeactivated(()=>{
	clearTimeout(timer)
	windoe.removeAddEventListener('...')
})
</script> 
ref 和reactive

这两个都是用来创建响应式对象的,ref通常用于创建基础类型,reactive通常用来创建响应式,

ref如果传入的事引用类型,内部源码也是调用的reactive来实现的

ref返回的属性是在template中使用,可以直接使用,在js中需要通过.value获取

<template>
	<div>{{count}}</div>
</template>
<script setup>
import {ref,reactive} from 'vue'
//方式1
const count=ref(1)
//方式2
const arr=ref([])
console.log(arr.value) //[]
//方式3 一个组件里面所有的属性全部定义在一个对象里面,
const data=reactive({
	name:'123',
	age:18
})
console.log(data.name)
</script> 
toRef 和toRefs

用来创建响应式的引用,主要是用来取出响应式对象里面的属性,或者解构响应式对象,解构出来的属性依然是响应式属性,如果不用这两直接解构会丢失响应式效果

<script setup>
import {reavtive,toRef,toRefs} from 'vue'
const data=reactive({
	name:'123',
	age:18
})
// 这样虽然直接能拿到name/age 但是会变成普通变量,没用响应式效果
const {name.age}=data
const name=toRef(data,'name')
const {name,age}=toRefs(data)
//不管是 toRef 还是 toRefs,这样修改是会把 data 里的 name 改掉的
name.value='456'
</script>
watch

是一个函数,能接收三个参数,参数一是监听的属性,参数二是接受新值和老值的回调函数,参数三是配置项

<script setup>
import { watch, ref, reactive } from 'vue'

const name = ref('沐华')
const data = reactive({
    age: 18,
    money: 100000000000000000000,
    children: []
})

// 监听 ref 属性
watch(name, (newName, oldName) => { ... })

// 监听其他属性、路由或者状态管理的都这样
watch(
    () => data.age, 
    (newAge, oldAge) => { ... }
)

// 监听多个属性,数组放多个值,返回的新值和老值也是数组形式
watch([data.age, data.money], ([newAge, newMoney], [oldAge, oldMoney]) => { ... })

// 第三个参数是一个对象,为可配置项,有5个可配置属性
watch(data.children, (newList, oldList) => { ... }, {
    // 这两个和 Vue2 一样,没啥说的
    immediate: true,
    deep: true,
    // 回调函数的执行时机,默认在组件更新之前调用。更新后调用改成post
    flush: 'pre', // 默认值是 pre,可改成 post 或 sync
    // 下面两个是调试用的
    onTrack (e) { debugger }
    onTrigger (e) { debugger }
})
</script>


watchEffect
  • watch 是对传入的一个或多个值进行监听,触发时会返回新值和老值,且默认第一次不会执行
  • watchEffect 是传入一个立即执行函数,所以默认第一次就会执行,且不需要传入监听内容,会自动收集函数内的数据源作为依赖,当依赖发生变化时会重新执行函数(有点像computed的味道),而且不会返回新值和老值
  • 清除副作用和副作用的刷新时机是一样的,区别是 watch 中会作为回调的第三个参数传入,watchEffect 中是回调函数的第一个参数
  • 正常情况下组件销毁/卸载后这两都会自动停止监听,但也有例外,比如异步的方式,在 setTimeout 里创建的监听就都需要手动停止监听,停止方式如下
const unwatch = watch('key', callback)
const unwatchEffect = watchEffect(() => {})
// 需要停止监听的时候,手动调用停止监听
unwatch()
unwatchEffect()

watchEffect 使用:

<script setup>
import { watchEffect } from 'vue'

// 正常使用
watchEffect(() => {
    // 会自动收集这个函数使用到的属性作为依赖,进行监听
    // 监听的是 userInfo.name 属性,不会监听 userInfo
    console.log(userInfo.name)
})

// 有两个参数,参数一是触发监听回调函数,参数二是可选配置项
watchEffect(() => {...}, {
    // 这里是可配置项,意思和 watch 是一样的,不过这只有3个可配置的
    flush: 'pre',
    onTrack (e) { debugger }
    onTrigger (e) { debugger }
})

// 回调函数接收一个参数,为清除副作用的函数,和 watch 的同理
watchEffect(onInvalidate => {
    console.log('沐华')
    onInvalidate(() => {
        console.log(2222)
    })
})
</script>

watchEffect 如果需要修改配置项 flush 为 post 或 sync 时,可以直接使用别名,如下

watchEffect(() => {...}, {
    flush: 'post',
})
// 和下面这个是一样的
watchPostEffect(() => {})
-----------------------------
watchEffect(() => {...}, {
    flush: 'sync',
}) 
// 和下面这个是一样的
watchSyncEffect(() => {})