1.0生命周期
话不多说上图
Vue3.0中可以继续使用Vue2.x中的生命周期钩子,但有有两个被更名:
beforeDestroy改名为 beforeUnmount
destroyed改名为 unmounted
Vue3.0也提供了 Composition API 形式的生命周期钩子,与Vue2.x中钩子对应关系如下:
beforeCreate===>setup()
created=======>setup()
beforeMount ===>onBeforeMount
mounted=======>onMounted
beforeUpdate===>onBeforeUpdate
updated =======>onUpdated
beforeUnmount ==>onBeforeUnmount
unmounted =====>onUnmounted
话不多说先来一个vue3.0的页面模板
<template>
<!-- vue3.0模板 -->
<div v-if="isLook"></div>
</template>
<script lang="ts">
import {
defineComponent,
getCurrentInstance,
onMounted,
reactive,
ref,
toRefs,
watch,
} from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { ElMessage, ElMessageBox } from 'element-plus';
export default defineComponent({
name: 'index',
// props: {
// index: {
// type: String
// }
// },
components: {
},
setup(props, ctx) {
const route = useRoute();
const state = reactive({
dialogVisible: false,
isLook: true,
formData: {
params: '',
date: [],
},
});
// 批量审批
const batchMethods = {
approved() {
},
rebut() {
},
};
const api = {
//获取审批详情
getDetails(row) {
const data = {
id: parseInt(row.id),
code: row.code, //事件编号
};
state.detailId = row.id;
state.isLook = true;
//查看详情
MyProcess.getMyProcessDetails(data)
.then(res => {
if (!res.status) {
state.isLook = true;
} else {
state.result = res.data.processAuditList || [];
state.isLook = false;
}
})
.finally(() => {
state.isLook = false;
});
},
};
const router = useRouter();
onMounted(() => {
batchMethods.approved();
});
watch(
() => state.isLook,
(n, o) => {
n && batchMethods.approved();
}
);
//计算属性——简写
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]
}
})
//不可选
const selectable = (row, index) => {
};
return {
selectable,
// ploading,
...toRefs(state),
...batchMethods,
};
},
});
</script>
<style lang="scss" scoped>
:deep(.el-dropdown) {
font-size: 12px;
}
</style>
好的开始一步一步的给模板上的元素做分析
1.拉开序幕的setup
理解:setup函数是vue3.0的一个新的配置项,组件中所用到的数据和方法均需在setup中配置。
执行时机:在beforeMount 之前执行一次
参数:setup函数接收两个参数第一个参数为props,值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性。第二个参数为ctx,值为对象,代表页面的执行上下文,主要内容有
export default {
setup(props, context) {
// Attribute (非响应式对象,等同于 $attrs)
console.log(context.attrs)
// 插槽 (非响应式对象,等同于 $slots)
console.log(context.slots)
// 触发事件 (方法,等同于 $emit)
console.log(context.emit)
// 暴露公共 property (函数)
console.log(context.expose)
}
}
函数返回值:值一般为一个对象,对象中的属性、方法, 在模板中均可以直接使用
setup语法糖
<template>
<div></div>
<div v-for="item in state.dataList" :key="item.id">{{item.name}}子组件</div>
</template>
<script setup>
import { defineExpose, onMounted, reactive, ref, toRefs } from "vue";
let message = ref("简单类型");
let state = reactive({
dataList: [{ id: 1, name: 123 }],
});
onMounted(async () => {
if (code == 0) {
state.dataList = data;
}
});
let { dataList } = toRefs(state);
defineExpose({
//用state.dataList父组件接收的是初始化的数据,
// 不是从onMounted里面取的数据,但是子组件的datalist是从onMounted拿到的最新数据。
// 把dataList从state里面通过toRefs解构,父组件也可拿到最新的数据
dataList: dataList,
});
</script>
为何需要使用setup语法糖,因为他实在太香了
setup语法糖的优点
2.0定义变量
区别于vue2.0把变量写在data函数中的特点。vue3.0主张面向函数编程,也设置了两种定义变量的核心api:ref和reactive函数
2.1ref函数
语法:let xxx = ref(initVal)
参数:基本数据类型和引用数据类型
当参数是基本数据类型时响应式的底层原理依然是Object.defineProperty()的劫持,而参数是引用数据类型的则依靠 reactive函数
使用:在模板中读取数据时需要xxx.value
2.2reactive函数
语法:let xxx = reactive(initval)
参数:一般创建引用数据类型
使用:在模板中读取数据时不需要xxx.value,如果是个xxx是个对象的话,在setup抛出xxx时,可以使用...torefs(xxx)的方式将xxx的属性映射出来在模板中可以单独使用xxx的某个属性。
3.0计算属性和监听
和vue2.0使用理念类似,vue3.0的计算属性和监听属性在写法上更加偏函数式一点,也稍微加了些拓展
3.1计算属性
语法:
//计算属性——简写
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]
}
})
3.2监听属性
与Vue2.x中watch配置功能一致但是有两个特定问题:
1.监视reactive定义的响应式数据时:oldValue无法正确获取、强制开启了深度监视。
2.监视reactive定义的响应式数据中某个属性时:deep配置有效。
//情况一:监视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})
//特殊情况
watch(()=>person.job,(newValue,oldValue)=>{
console.log('person的job变化了',newValue,oldValue)
},{deep:true}) //此处由于监视的是reactive素定义的对象中的某个属性,所以deep配置有效
3.3watchEffect函数
watch的套路是:既要指明监视的属性,也要指明监视的回调。
watchEffect的套路是:不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性。
watchEffect有点像computed:
但computed注重的计算出来的值(回调函数的返回值),所以必须要写返回值。
而watchEffect更注重的是过程(回调函数的函数体),所以不用写返回值。
语法有:
//watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调。
watchEffect(()=>{
const x1 = sum.value
const x2 = person.age
console.log('watchEffect配置的回调执行了')
})
参考链接:https://blog.csdn.net/qq_22182989/article/details/125781704