一、 搭建第一个 Vite 项目
https://vitejs.cn/guide/
项目模板的话暂时没有,只能创建个最基础的项目。
二、初试
setup()
所有的逻辑代码都写在这个函数中。
定义函数
<template>
<button @click="onClock">{
{
arr }}</button>
</template>
export default{
name: '',
setup() {
const data = reactive({
arr: 1,
obj: 6
})
let onClock = () => {
data.arr++
// data.obj--
},
return {
...toRefs(data),
onClock
}
}
}
computed()
与vue2中computed配置功能一致
<template>
<p><input type="text" v-model="num"></p>
<p>{
{
nextNum}}</p>
</template>
import {
ref, computed } from 'vue'
const num = ref(1)
const nextNum = computed(() => {
return Number(num.value) + 1
})
watch()
监听的是属性,不是属性值,所以监听ref定义的数据,不用加 ‘.value’。
这里有点点小坑:
在监听reactive定义的一个响应式数据时会出现拿不到正确的oldVal;
<div>
<p>姓名:{
{
obj.name }}</p>
<p>年龄:{
{
obj.age }}</p>
<p>职位:{
{
obj.job.job1.name }}</p>
<p>薪资:{
{
obj.job.job1.salary }}K</p>
<button @click="obj.name += 'Q'">修改姓名</button>
<button @click="obj.age++">修改年龄</button>
<button @click="obj.job.job1.salary++">加薪</button>
</div>
</template>
import {
ref, watch, reactive, watchEffect } from "vue";
export default {
setup() {
// sum是基本数据类型,所以用ref
let sum = ref(0);
let msg = ref("hello");
let obj = reactive({
name: "张三",
age: 22,
job: {
job1: {
name: "web工程师",
salary: 20,
},
},
});
// 情况一:监听ref所定义的一个响应式数据
watch(sum, (newVal, oldVal) => {
console.log("sum的值改变了");
},{
immediate:true});
// 情况二:监听ref所定义的多个响应式数据
watch([sum, msg], (newVal, oldVal) => {
console.log(newVal, "值改变了");
},{
immediate:true});
// 情况三:监听reactive所定义的一个响应式数据的全部属性,
// 注意:1.此处无法正确的获取oldVal;
watch(obj, (newVal, oldVal) => {
console.log(newVal);
console.log(oldVal);
},{
deep:true});
// 情况四:监听reactive所定义的一个响应式数据的某个属性
watch(()=>obj.age, (newVal, oldVal) => {
console.log(newVal);
console.log(oldVal);
});
// 情况五:监听reactive所定义的一个响应式数据的某些属性
watch([()=>obj.age,()=>obj.name], (newVal, oldVal) => {
console.log(newVal);
console.log(oldVal);
});
// 特殊情况
watch(
() => obj.job,
(newVal, oldVal) => {
console.log(newVal);
console.log(oldVal);
},
{
deep: true }//由于此处监听的是reactive所定义的对象中的某个属性,所以deep配置有效
);
return {
sum, msg, obj };
}
}
watchEffect()
1、watchEffect 不需要指定监听的属性,他会自动的收集依赖, 只要我们回调中引用到了 响应式的属性, 那么当这些属性变更的时候,这个回调都会执行,而 watch 只能监听指定的属性而做出变更。
2、watch 可以获取到新值与旧值(更新前的值),而 watchEffect 是拿不到的。
3、watchEffect 如果存在的话,在组件初始化的时候就会执行一次用以收集依赖(与computed同理),而后收集到的依赖发生变化,这个回调才会再次执行,而 watch 不需要,因为他一开始就指定了依赖。
在学习的时候了解到个东西,就是这个可以用来处理多次请求一个借口的时候,会出现拿不到最后一次结果的情况。
watchEffect(()=>{
// 异步api调用,返回一个操作对象
const apiCall = sometingAsyncMethods(props.userID)
onInvalidate(() => {
// 取消异步api的调用。
apiCall.cancel()
})
})
onInvalidate(fn)传入的回调会在 watchEffect 重新运行或者 watchEffect 停止的时候执行,这就能确保我们能拿到最后一次请求的结果。
生命周期
<template>
<div>
<h2>求和结果:{
{
sum }}</h2>
<button @click="sum++">+1</button>
</div>
</template>
<script>
// 组合式API
import {
ref,
onBeforeMount,
onMounted,
onBeforeUpdate,
onUpdated,
onBeforeUnmount,
onUnmounted,
} from "vue";
export default {
// setup先执行再到beforeCreate
// 在setup里面没有beforeCreate和created这两个组合API
setup() {
let sum = ref(0);
console.log("setup");
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,
};
},
// 若setuo里面的组合式API的生命周期钩子时期比配置项的生命周期钩子快一点
// 通过配置项的形式使用生命周期钩子
//#region
beforeCreate() {
console.log("beforeCreate");
},
created() {
console.log("created");
},
beforeMount() {
console.log("beforeMount");
},
mounted() {
console.log("mounted");
},
beforeUpdate() {
console.log("beforeUpdate");
},
updated() {
console.log("updated");
},
beforeUnmount() {
console.log("beforeUnmount");
},
unmounted() {
console.log("unmounted");
},
//#endregion
};
</script>
<style>
</style>
hooks函数
类似于Vue2.x中的mixin
自定义hook的优势:复用代码,让setup中的逻辑更清楚易懂
ref reactive toRef
ref()传入一个值作为参数,一般传入基本数据类型,返回一个基于该值的响应式Ref对象,该对象中的值一旦被改变和访问,都会被跟踪到,可以触发模板的重新渲染,显示最新的值;
reactive是用来定义更加复杂的数据类型,但是定义后里面的变量取出来就不在是响应式Ref对象数据了;
所以需要用toRefs函数转化为响应式数据对象
<script lang="ts">
import {
computed, reactive,toRefs } from "vue";
interface DataProps {
name: string;
now: number;
birthYear: number;
age: number;
sayName: () => void;
}
export default {
name: "App",
setup() {
const data: DataProps = reactive({
name: "zhangsan",
birthYear: 2000,
now: 2020,
sayName: () => {
console.log(1111);
console.log(data.name);
data.name = "I am " + data.name;
console.log(data.name);
},
age: computed(() => {
return data.now - data.birthYear;
}),
});
const refData = toRefs(data)
refData.age
return {
...refData,
};
},
};
</script>
此处详细描述:https://blog.csdn.net/weixin_43342105/article/details/110233333