v2-v3的学习成本不高,只要有v2基础,基本可以上手vue3
setup中不能访问v2的配置比如data,methods等
使用ref可以创建一个对象,可以是基本类型,也可以是对象
例如:
<template>
<div class="home">
{{a}}
div>
template>
<script>
import { ref} from 'vue'
export default {
name: 'Home',
setup(){
// 创建
const a = ref('')
// 使用方法 xxx.value
a.value = 'NanChen'
return{
a,
}
},
}
script>
这是一个对象类型的响应数据,例:
<template>
<div class="home">
{{a.sex}}
{{a.name}}
div>
template>
<script>
import { reactive } from "vue";
export default {
name: "Home",
setup() {
const a = reactive({
sex: "",
name: "",
});
a.sex = "男";
a.name = "NanChen";
return {
a,
};
},
};
script>
例:
<template>
<div>
<div>
姓:{{per.firstName}}
div>
<div>
名:{{per.lastName}}
div>
<div>
加起来:{{per.fullName}}
div>
div>
template>
<script>
import { reactive, computed } from "vue";
export default {
setup() {
let per = reactive({
firstName: "Nan",
lastName: "Chen",
});
per.fullName = computed(() => {
return per.firstName + "++" + per.lastName;
});
return {
per,
};
},
};
script>
<style>
style>
<template>
<div>
监听<button @click="num++">+1查看监听器变化button>
<div>{{num}}div>
div>
template>
<script>
import { ref, watch } from "vue";
export default {
setup() {
let num = ref(0);
watch(num,(newValue,oldValue)=>{
console.log('newValue: '+newValue,' oldValue: '+oldValue);
})
return{
num
}
},
};
script>
<template>
<div>
<div>
<button @click="num++">+1查看监听器变化button>
<div>num:{{num}}div>
div>
<div>
<button @click="num2+='改动了'">改变button>
<div>num2:{{num2}}div>
div>
div>
template>
<script>
import { ref, watch } from "vue";
export default {
setup() {
let num = ref(0);
let num2 = ref("监听多个ref响应式的使用");
watch(
[num, num2],
(newValue, oldValue) => {
console.log("num and num2 ", newValue, oldValue);
},
/* immediate:第一次就监听 */
{ immediate: true }
);
return {
num,
num2,
};
},
};
script>
<template>
<div>
<div>
<button @click="a.name+='XX'">更改姓名button>
<div>{{a.name}}div>
div>
<div>
<button @click="a.age++">更改年龄button>
<div>{{a.age}}div>
div>
div>
template>
<script>
import { reactive, watch } from "vue";
export default {
setup() {
let a = reactive({
name: "NanChen",
age: 20,
});
watch(a,(newValue, oldValue) => {
console.log(newValue, oldValue);
},{immediate:true,deep:false}//deep无效
);
return {
a,
};
},
};
script>
<template>
<div>
<div>
<button @click="a.name+='XX'">更改姓名button>
<div>{{a.name}}div>
div>
<div>
<button @click="a.age++">更改年龄button>
<div>{{a.age}}div>
div>
div>
template>
<script>
import { reactive, watch } from "vue";
export default {
setup() {
let a = reactive({
name: "NanChen",
age: 20,
});
watch(() => a.name,(newValue, oldValue) => {
console.log(newValue, oldValue);
}
);
return {
a,
};
},
};
script>
<template>
<div>
<div>
<button @click="a.name+='XX'">更改姓名button>
<div>{{a.name}}div>
div>
<div>
<button @click="a.age++">更改年龄button>
<div>{{a.age}}div>
div>
div>
template>
<script>
import { reactive, watch } from "vue";
export default {
setup() {
let a = reactive({
name: "NanChen",
age: 20,
});
watch([() => a.name, () => a.age],(newValue, oldValue) => {
console.log(newValue, oldValue);
}
);
return {
a,
};
},
};
script>
<template>
<div>
<div>
<button @click="a.name+='XX'">更改姓名button>
<div>{{a.name}}div>
div>
<div>
<button @click="a.age++">更改年龄button>
<div>{{a.age}}div>
div>
<div>
<button @click="a.obj.objList.num++">更改数字button>
<div>{{a.obj.objList.num}}div>
div>
div>
template>
<str>
import { reactive, watch } from "vue";
export default {
setup() {
let a = reactive({
name: "NanChen",
age: 20,
obj: {
objList: {
num: 100,
},
},
});
watch(() => a.obj,(newValue, oldValue) => {
console.log(newValue, oldValue);
},{ deep: true }); // 这里是坚挺的reactive对象中的某个属性,因此deep生效
// deep:其值是true或false;确认是否深入监听。(一般监听时是不能监听到对象属性值的变化的,数组的值变化可以听到。
return {
a,
};
},
};
script>
特性,也可以说成和watch的区别
- 不需要手动传入依赖
- 每次初始化时会执行一次回调函数来自动获取依赖
- 无法获取到原值,只能得到变化后的值
<template>
<div>
<div>
<button @click="a.name+=' hello'">更改姓名button>
<div>{{a.name}}div>
div>
<div>
<button @click="a.age++">更改年龄button>
<div>{{a.age}}div>
div>
div>
template>
<script>
import { reactive, watchEffect } from "vue";
export default {
setup() {
let a = reactive({
name: "NanChen",
age: 20,
});
watchEffect(() => {
console.log(a.name);
console.log(a.age);
});
setTimeout(() => {
a.name += " hi";
a.age++;
}, 1000);
return {
a,
};
},
};
script>
所有的声明周期要放在setup中
Vue3的生命周期如下:
1、beforeCreate -> 使用 setup()
2、created -> 使用 setup()
3、beforeMount -> onBeforeMount
4、mounted -> onMounted
5、beforeUpdate -> onBeforeUpdate
6、updated -> onUpdated
7、beforeDestroy -> onBeforeUnmount
8、destroyed -> onUnmounted
9、errorCaptured -> onErrorCaptured
setup() {
onMounted(() => {
console.log('mounted')
})
}
说白话文就是不用写前面的对象名称直接渲染里面的属性即可
<template>
<div>
<div>{{name}}div>
<div>{{age}}div>
<div>{{num}}div>
div>
template>
<script>
import { reactive, toRef } from "vue";
export default {
setup() {
let a = reactive({
name: "NanChen",
age: 20,
list: {
num: 0,
num1: 1,
num2: 2,
num3: 3,
num4: 4,
},
});
return {
name: toRef(a, "name"),
age: toRef(a, "age"),
num: toRef(a.list, "num"),
};
},
};
script>
一键给对象中的多个属性全部响应转换
<template>
<div>
<div>{{name}}div>
<div>{{age}}div>
<div>{{num}}div>
<div>{{num1}}div>
<div>{{num2}}div>
<div>{{num3}}div>
<div>{{num4}}div>
div>
template>
<script>
import { reactive, toRefs } from "vue";
export default {
setup() {
let a = reactive({
name: "NanChen",
age: 20,
list: {
num: 0,
num1: 1,
num2: 2,
num3: 3,
num4: 4,
},
});
return {
...toRefs(a),
...toRefs(a.list),
};
},
};
script>
只处理对象最外面一层的响应式数据(浅响应式)
<template>
<div>
<h1>姓:{{name}}h1>
<h2>岁数:{{age}}h2>
<h3>对象{{obj.objList.name}}h3>
<button @click="name += '+'">修改姓名button>
<button @click="age++">修改年龄button>
<button @click="obj.objList.name += '!'">修改水果button>
div>
template>
<script>
import { reactive, toRefs, shallowReactive } from "vue";
export default {
name: "App",
setup() {
// 定义了一段数据
let a = shallowReactive({
// 只将第一层数据做了响应式处理
name: "NanChen",
age: 20,
obj: {
objList: {
name: "Jia", // 深层次的数据将会是一个普通的对象
},
},
});
// 将数据返回出去
return {
...toRefs(a),
};
},
};
script>
只处理基础数据类型的响应式,不进行对象类型的响应式。
<template>
<div>
<h1>姓:{{a}}h1>
<button @click="a += '+'">修改姓名button>
<h2>{{b.num}}h2>
<button @click="b++">修改numbutton>
div>
template>
<script>
import { shallowRef } from "vue";
export default {
name: "App",
setup() {
// 定义了一段数据
let a = shallowRef("NanChen");
let b = shallowRef({
num: 1,
});
console.log(b.value.num);
// 将数据返回出去
return {
a,
b,
};
},
};
script>
这里可以看到,修改数据后将不会在触发页面的更新 因为监测不到了
const a = shallowRef({
name: 'NanChen', // 只读
obj: {
objList: 2 // 也是只读
}
})
const a = shallowReadonly({
name: 'NanChen', // 只读
obj: {
objList: 2 // 不是只读
}
})
例:
<template>
<h2>姓名:{{a.name}}h2>
<h2>年龄:{{a.age}}h2>
<button @click="showRawA">点我显示原始abutton>
template>
<script>
import { reactive, toRaw } from "vue";
export default {
name: "Demo",
setup() {
let a = reactive({
name: "NanChen",
age: 20,
});
function showRawA() {
console.log("a=", a);
let p = toRaw(a);
console.log("raw a = ", p);
}
return {
a,
showRawA,
};
},
};
script>
这里可以看到使用toRaw后,响应式对象变成了一个普通的对象
这里看一下使用markRaw和不使用markRaw的区别
看这个例子:
<template>
<h2>姓:{{a.name}}h2>
<div v-if="a.other" style="border: 1px solid #000;width: 200px;padding: 10px;margin-bottom: 10px;">
<h3>开发岗位:{{a.other.kaifa}}h3>
<h3>待遇:{{a.other.money}}Kh3>
<button @click="changeOne">更换工程师button>
<button @click="changeTwo">加薪资button>
div>
<button @click="addOther">添加信息button>
template>
<script>
import { reactive } from "vue";
export default {
name: "Demo",
setup() {
let a = reactive({
name: "NanChen",
age: 20,
});
function addOther() {
a.other = {
kaifa: "web开发",
money: 1,
};
}
function changeOne() {
a.other.kaifa = "java开发";
}
function changeTwo() {
a.other.money++;
}
return {
a,
addOther,
changeOne,
changeTwo,
};
},
};
script>
效果:
可以看到这里的数据是可以进行响应
<template>
<h2>姓名:{{a.name}}h2>
<div v-if="a.other" style="border: 1px solid #000;width: 200px;padding: 10px;margin-bottom: 10px;">
<h3>开发岗位:{{a.other.kaifa}}h3>
<h3>待遇:{{a.other.money}}Kh3>
<button @click="changeOne">更换工程师button>
<button @click="changeTwo">加薪资button>
div>
<button @click="addOther">添加信息button>
template>
<script>
import { reactive, markRaw } from "vue";
export default {
name: "Demo",
setup() {
let a = reactive({
name: "NanChen",
age: 20,
});
function addOther() {
a.other = markRaw({
kaifa: "web开发",
money: 1,
});
}
function changeOne() {
a.other.kaifa = "java开发";
}
function changeTwo() {
a.other.money++;
}
return {
a,
addOther,
changeOne,
changeTwo,
};
},
};
script>
效果:
因为markRaw将{kaifa: “web开发”,money: 1,}变成了一个非响应式对象。因此,当修改 a.other.kaifa 或 a.other.money时,界面不会更新
在组合式 API 中使用 provide/inject,两个只能在 setup 期间调用
provide 函数是有两个接受参数,是用来提供和发送数据
provide(name,value)
祖先组件:
import { provide,reactive } from "vue"
export default {
setup(){
let obj = reactive({
name:'NanChen',
age:20
}
provide('obj',obj)
}
}
inject则是用来接受数据
后代组件:
import { inject } from "vue"
export default {
setup(){
const obj = inject('car')
return{obj}
}
}
判断值是否为ref对象
let name = ref('NanChen')
console.log(isRef(name)); // true
判断值是否为isReactive对象
let num = isReactive({})
console.log(isRef(val)); // true
检查对象是否是由readonly创建的只读代理
const state = reactive({
name: 'NanChen'
})
console.log(isReactive(state)) // true
检查对象是否是由reactive或者readonly创建的proxy
const state = reactive({
name: 'NanChen'
})
console.log(isProxy(state)) // true