1.reactive具有深层响应式
在vue2中针对一个复杂数据的修改有时会存在vue监听不到的情况,(对象增加和删除的属性,通过下标修改数组的值),这时往往需要用到this.$set(数组/对象名,下标/属性名,新值)或者this.forceUpdate()让修改的数据被捕捉到。
或者watch监听一个对象时,如果对象属性还是个对象那么就需要deep: true才能监听到改变。
但是在vue3中,复杂数据类型用reactive()方法声明后会具有深层响应性,对对象和数组的(对象增加和删除的属性,通过下标修改数组的值)修改会被捕捉到。对对象深层次修改也会监听到。
2.nextTick(fn(){})
vue2中往往在组件实例中使用this.$nextTick(fn(){})等待下一次 DOM 更新刷新。vue3中使用nextTick(fn(){})
并且nextTick()的返回结果是promise
使用方法1:nextTick(fn(){回调函数})
使用方法2:结合await
3.子组件获取父组件的数据 props/defineProps()
vue2中通常使用props:['',''] 或 props: {a: {},b: {}}的方式
vue3非setup语法糖,与vue2类似,需要传参到setup函数中
export default defineComponent({
props: ['b', 'a'],
setup(props) {
return{props}
}
})
vue3setup语法糖
<script setup>
const props = defineProps(['a','b'])
</script>
4.父组件获取子组件的数据和方法 defineExpose
vue2中父组件获取子组件的数据常用的方法
<sonComponent ref="aa"></sonComponent>
···
this.$refs.aa.变量名/方法名
或
this.$children[n].*** 获取下标第几个的子组件
vue3中:
1.子组件使用的选项式API(vue2风格)或者没有使用setup语法糖,那么使用子组件的数据和方法
<son ref="aa"></son>
···
const aa = ref(null)
onMounted(()=>{ aa.value.变量名/方法名 })
2.子组件使用了setup语法糖,子组件需要defineExpose显式的暴露自己的变量和函数,父组件才可以使用子组件的暴露的内容。
父组件
<son ref="aa"></son>
···
const aa = ref(null)
onMounted(()=>{ aa.value.变量名/方法名 })
子组件
let a = ref('a')
function b(){}
defineExpose({ a,b }) defineExpose显式的暴露
5.模板引用 ref获取DOM元素或子组件
vue2中通常使用this.$refs.***获取DOM元素本身或者vue组件实例
vue3中
单个DOM:
html: <p ref="p">hello</p>
js:const p = ref(null)即可
多个DOM:
html:<p v-for="item in 3" ref="p">hello</p>
js:const pArr = ref([])即可
注意使用dom的时机
6.子组件事件触发父组件方法 emits/defineEmits
vue2中通常使用
this.$emit('自定义事件名',参数)
vue3中:
没有使用setup语法糖,需要使用emits并且传入setup第二个参数中
export default{
emits: ['自定义事件名a','自定义事件名b'],
setup(props, ctx){
ctx.emit('自定义事件名a', 参数)
}
}
使用了setup语法糖,需要使用defineEmits方法:
const emit = defineEmits(['自定义事件名a','自定义事件名b'])
emit(自定义事件名a, 参数)
7.watch监听器
vue2中对对象的深层监听需要手动开启,在vue3中reactive具有深层响应式,所以watch监听对象时默认开始深层监听。
watch(对象名,(new,old)=>{***})
深度侦听需要遍历被侦听对象中的所有嵌套的属性,当用于大型数据结构时,开销很大。因此请只在必要时才使用它,并且要留意性能。只需要监听复杂对象的某个属性时,使用
watch(()=>对象名.属性名,(new,old)=>{***})
vue3中新增了watchEffectAPI,它与watch不同在于,它没有明确指定依赖哪个数据,函数中用到的数据都是它的依赖数据,当依赖的数据发生改变时就会执行函数。
watchEffect(() => {***})
8.注册全局组件
vue2:
import Vue from "vue";
import zujian from '**'
Vue.component('组件名', zujian)
vue3:
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
import zujian from '**'
app.component('组件名', zujian) app.component().component().component()方法可以被链式调用
9.具名插槽
vue2的使用办法:
子组件:
<slot name="aa"></slot>
父组件两种办法:
<div slot="aa">123456789</div>
<template v-slot:aa>123456789</template> v-slot: 可简写为 #
vue3的使用办法:
子组件:
<slot name="aa"></slot>
父组件:
<template v-slot:aa>123456789</template> v-slot: 可简写为 #
10.异步组件 defineAsyncComponent
在大型项目中,我们可能需要拆分应用为更小的块,并仅在需要时再从服务器加载相关组件,会发送请求。 vue2中:
components: {
componentA: ()=> import('***')
}
vue3中:
const componentA = defineAsyncComponent(()=> import('***'))
更多配置
const AsyncComp = defineAsyncComponent({
loader: () => import('./Foo.vue'),
loadingComponent: LoadingComponent,
delay: 200,
errorComponent: ErrorComponent,
timeout: 3000
})
11.逻辑复用 组合式函数
vue2中推荐使用mixins
vue3中推荐使用组合式函数,组合式函数与普通导出的函数的区别是可以使用vue里提供给的api
12.状态管理
vue3推荐使用菠萝,也可以使用vuex,
vue2使用this.$store.***具有响应式
vue3使用useStore()函数,想要具有响应式要在计算变量中声明,且useStore()在刚进去就执行,否则会出现莫名其妙的错误,求告知。
而且直接使用let store = useStore() 的store.state.**不具有响应式,当vuex改变时store不会改变。使用计算属性computed(() => store.state.**)使其具有响应式。
13.路由缓存
今天使用老方法实现路由缓存,发现失败了,进而发现vue3的路由缓存和vue2的实现方法不一样。路由缓存是指将在该路径下的组件在切换时不进行销毁,而是存入缓存中,当路径改变再次切换回来时会保持离开时的状态。
vue2的实现方法:
<keep-alive>
<router-view />
</keep--alive>
vue3的实现方法:
<router-view v-solt="{ Component }">
<keep-alive>
<component :is="Component" />
</keep-alive>
</router-view>
<keep-alive>可以通过include和exclude决定哪些组件可以存入缓存,哪些组件不能存入缓存,匹配的是组件里的name。
vue3组件的name : 当使用了setup语法糖时,单文件组件会自动根据文件名生成对应的 name 选项 例如 Tree.vue 那他的name 就是 Tree 自动生成。当没有使用setup语法糖时可以自己name:**定义。
查漏补缺
v-show不支持在template标签上使用
v-for="item in arr" 可以写作 v-for="item of arr"
在事件处理中访问事件参数
1.<div @click="方法名(参数,$event)"></div>
2.<div @click="(event)=>方法名(参数,event)"></div>
v-model上的修饰符
1.lazy 更新数据的时机由input事件变为change事件
2.number 该值无法被 parseFloat() 处理,那么将返回原始值。
3.trim 同字符串.trim()方法,去除字符串两端空格
组件名推荐使用帕斯卡命名法
即<MyComponent>
传递props推荐使用kebab-case形式
即aa-bb-cc烤肉串形状