v2-v3的学习成本不高,只要有v2基础,基本可以上手vue3
一、setup语法
setup中不能访问v2的配置比如data,methods等
二、ref响应数据
使用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>
三、reactive创建响应式数据
这是一个对象类型的响应数据,例:
<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>
四、computed 计算属性
例:
<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>
五、watch 监听器
例(一):监听单个ref的响应式数据
<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>
例(二):监听ref定义的多个响应式数据
<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>
例(三):监听reactive所定义的一个响应式数据
<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>
例(四):监听reactive定义的一个响应式数据中的某一个属性
<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>
例(五):监听reactive定义的一个响应式数据中的某些属性
<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>
例(六):监听reactive定义的嵌套对象
<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>
六、watchEffect 监听器
特性,也可以说成和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>
七、Vue3生命周期
所有的声明周期要放在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') }) }
八、toRef
说白话文就是不用写前面的对象名称直接渲染里面的属性即可
<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>
九、toRefs 响应式转换
一键给对象中的多个属性全部响应转换
<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>
十、shallowReactive (浅响应式)
只处理对象最外面一层的响应式数据(浅响应式)
<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>
十一、shallowRef 不进行对象响应式
只处理基础数据类型的响应式,不进行对象类型的响应式。
<template> <div> <h1>姓:{{a}}</h1> <button @click="a += '+'">修改姓名</button> <h2>{{b.num}}</h2> <button @click="b++">修改num</button> </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>
这里可以看到,修改数据后将不会在触发页面的更新 因为监测不到了
十二、readonly(深只读)
const a = shallowRef({ name: 'NanChen', // 只读 obj: { objList: 2 // 也是只读 } })
十三、shallowReadonly(浅只读)
const a = shallowReadonly({ name: 'NanChen', // 只读 obj: { objList: 2 // 不是只读 } })
十四、toRaw 将响应式对象转换成普通对象
例:
<template> <h2>姓名:{{a.name}}</h2> <h2>年龄:{{a.age}}</h2> <button @click="showRawA">点我显示原始a</button> </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和不使用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}}K</h3> <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>
效果:
可以看到这里的数据是可以进行响应
添加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}}K</h3> <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时,界面不会更新
十六、provide / inject
在组合式 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} } }
十七、isRef
判断值是否为ref对象
let name = ref('NanChen') console.log(isRef(name)); // true
十八、isReactive
判断值是否为isReactive对象
let num = isReactive({}) console.log(isRef(val)); // true
十九、inReadonly
检查对象是否是由readonly创建的只读代理
const state = reactive({ name: 'NanChen' }) console.log(isReactive(state)) // true
二十、isProxy
检查对象是否是由reactive或者readonly创建的proxy
const state = reactive({ name: 'NanChen' }) console.log(isProxy(state)) // true