这里写自定义目录标题
vue2和vue3的一些区别
首先是生命周期:
vue2生命周期 | vue3生命周期 | 说明 |
---|---|---|
beforeCreate | setup | 组件创建之前 |
created | setup | 组件创建之前 |
beforeMount | onBeforeMount | 组件挂载之前 |
mounted | onMounted | 组件挂载完成 |
beforeUpdate | onBeforeUpdate | 数据更新,虚拟 DOM 打补丁之前 |
updated | onUpdated | 数据更新,虚拟 DOM 渲染完成 |
beforeDestroy | onBeforeUnmount | 组件销毁之前 |
destroyed | onUnmounted | 组件销毁后 |
其实setup 是在beforeCreate之前执行的
<template>
<div class="home">
</div>
</template>
<script>
// ref 是 vue 3.0 的一个重大变化,其作用为创建响应式的值
import { ref } from 'vue'
// 导出依然是个对象,不过对象中只有一个 setup 函数
export default {
setup () {//所有的数据都是写在setup中的
// 定义一个 count 的响应式数据,并赋值为 0
const count = ref(0)
onBeforeMount(()=>{//生命周期的写法
})
// 导出一些内容给上面的模板区域使用
return {
count,
}
}
}
</script>
})
vue3的API的变化
ref与reactive
import { reactive, ref, watch ,watchEffect} from "vue"
ref:可以声明简单的数据类型
reactive: 可以声明复杂的数据类型
当然ref也可以声明复杂的数据类型,但是在内部会被转换成reactive
const num = ref(1)
const state = reactive({
count: 0,
double: computed(() => { return state.count * 2 })
})
//如果是在setup中用ref的话是:num.value//1
//页面中可以自动解读num:
/**
*<div>默认的count:{{num}}</div>
*/
//而reactive是state.count//0
watch与watchEffect
watch:这个用法和vue2没什么区别
watchEffect:这个是vue3新增的如果要监听数据或路由,这个基本上都能满足我们的需求
// watchEffect:
/**
* 1、不需要手动传入依赖
* 2、不是lazy初始化执行分子依赖
* 3、无法获取原始值
* 4、一些异步操作放里面更合适
* 5、watch第三个参数处理副作用的第一个参数
*/
//页面初始化时或默认加载一次
const stop = watchEffect((onInvalidate)=>{
onInvalidate(()=>{
//清除副作用
stop.cancel()
})
},{
flush:'sync',// 'pre' | 'post' | 'sync' // 默认:'pre'//调用时机,不熟的话不建议使用
})
//当然如果我们想停止监听的话可以
stop()
注意点:
watchEffect 会在 Vue3 开发中大量使用,这里说几个注意点:
1、如果有多个负效应,不要粘合在一起,建议写多个 watchEffect。
2、watchEffect 也可以放在其他生命周期函数内
比如你的副作用函数在首次执行时就要调用 DOM,你可以把他放在 onMounted 钩子里:
onMounted(() => {
watchEffect(() => {
// access the DOM or template refs
});
}
watchEffect 基本上是现象级拷贝了 React 的 useEffect;这里倒不是 diss Vue3,只是说 watchEffect 和 useEffect 的设计都源自于一个比较成熟的编程范式——FP。大家在看 Vue3 文档时,也不要只盯着某些 api 的用法,Vue 只是工具,解决问题才是终极目标;我们还是要把重点放在领悟框架的设计思想上;悟到了,才是真正掌握了解决问题的手段。
Computed和Watch
<template>
<div>
<h2>计算属性与监听属性</h2>
<fieldset>
<legend>姓名操作</legend>姓氏:
<input type="text" placeholder="请输入姓氏" v-model="user.firstName" />
<br />名字:
<input type="text" placeholder="请输入名字" v-model="user.lastName" />
</fieldset>
<fieldset>
<legend>计算属性与监听属性</legend>名字:
<input type="text" placeholder="显示名字" v-model="fullName" />
<br />名字:
<input type="text" placeholder="显示名字" v-model="fullName2" />
<br />名字:
<input type="text" placeholder="显示名字" v-model="fullName3" />
</fieldset>
</div>
</template>
<script lang="ts">
import { ref, reactive, defineComponent, watch, watchEffect, computed } from 'vue'
export default defineComponent({
setup(props, { attrs, slots, emit }) {
//定义一个响应式对象
let user = reactive({
firstName: '东方',
lastName: '月初'
})
//vue3中的计算属性
//通过计算属性的方式,实现第一个姓氏的显示
//计算属性的函数中如果之传入一个回调函数,表示get
//返回的是一个ref类型的对象
let fullName = computed(() => {//第一个姓名
return user.firstName + '_' + user.lastName
})
let fullName2 = computed({//第一个姓名
get() {
return user.firstName + '_' + user.lastName
},
set(val: string) {
// console.log(val);
let names = val.split('_')
user.firstName = names[0]
user.lastName = names[1]
}
})
//第三姓名
let fullName3 = ref('')
//监听
//watch可以监听多个数据
//当我们是有watch监听非响应式的数据的时候,箭头函数不会执行
watch([user.firstName, user.lastName], () => {
})
//这样就可以了
watch([() => user.firstName, () => user.lastName], () => {
})
// watch(user,({firstName,lastName})=>{
// fullName3.value = firstName + '_' + lastName
// },{immediate:true,deep:true})
watchEffect(() => {//本身就会立即监听一次
})
return {
user,
fullName,
fullName2,
fullName3
}
}
})
</script>
CustomRef的使用
<template>
<div>
<h2>CustomRef的使用</h2>
<input type="text" v-model="keyword" />
<p>{{ keyword }}</p>
</div>
</template>
<script>
import { ref, reactive, defineComponent, customRef } from 'vue'
//自定义防抖函数
function useDebounced(value, delay = 200) {
//准备一个存储定时器的id的变量
let timeOutId: number
return customRef((track, trigger) => {
return {
//返回数据
get() {
track()
return value
},
//设置数据
set(newValue) {
//每次进来之前先清除定时器
clearTimeout(timeOutId)
timeOutId = setTimeout(() => {
value = newValue
trigger()
}, delay)
}
}
})
}
export default defineComponent({
setup() {
//使用customRef实现了防抖
let keyword = useDebounced('abc', 500)
// let keyword = ref('123')
return {
keyword,
}
}
})
</script>