vue2 的响应式数据是通过 Object.defineProperty 进行数据劫持,其存在一些缺点:
vue3 的响应式数据是通过 Proxy 进行数据劫持的,可以很好的规避 Object.defineProperty 带来的缺陷
首先了解 vue 的 虚拟dom
虚拟DOM就是通过 JS 去生成一个 AST 节点树
一个dom节点上的属性是非常多的,所以直接操作DOM是非常浪费性能的,解决方案就是可以通过JS的计算性能去换取操作DOM所消耗的性能,既然逃不开操作DOM,那我们可以尽可能少的去操作DOM;
规则一:前序对比
规则二:尾序对比
规则三:新增对比
规则四:卸载移除对比
规则五:乱序对比
vue3.x 中标记和提升所有的静态节点,diff 的时候只需要对比动态节点内容,尽可能复用标记的静态节点。
// App.tsx
import {ref} from 'vue'
let v = ref<string>('')
const renderDom = ()=>{
return (
<div>
<input v-model = {v.value} type="text" />
<div>{v.value}</div>
</div>
)
}
export default renderDom
<template>
<renderDom></renderDom>
</template>
<script setup lang="ts">
import renderDom from './App'
</script>
通常,当我们需要从父组件向子组件传递数据时,我们使用 props。想象一下这样的结构:有一些深度嵌套的组件,而深层的子组件只需要父组件的部分内容。在这种情况下,如果仍然将 prop 沿着组件链逐级传递下去,会很麻烦。
场景A:通过路由进行局部组件的刷新,对数据进行操作之后需要手动刷新页面;
场景B:父组件有很多数据需要分发给其子代组件的时候
源码解析:
Inject 接收的值是unknown的问题:
组件实例化的时候注入 provides 的值
钩子主要用来处理复用代码逻辑的封装,在vue2的时候就已经有 Mixins 去做这样的事情了, Mixins 就是将这些多个相同的逻辑抽离出来,各个组件只需要引入 mixins 就能实现一次写代码,多组件受益的效果
缺点是会涉及覆盖问题,同名data、methods、filters覆盖,以及变量来源不明确,不利于阅读,使代码难以维护;
为了解决mixins存在的问题,Vue3.x版本使用了自定义Hooks去做这样的事情。
// 定义转换base64的hooks
import { onMounted } from 'vue'
type Options = {
el:string
}
export default function(options:Options):Promise<{baseUrl:string}>{
return new Promise((reslove)=>{
onMounted(()=>{
let img:HTMLImageElement = document.querySelector(options.el) as HTMLImageElement
img.onload = () => {
resolve({
baseUrl: base64(img)
})
}
})
const base64 = (el:HTMLImageElement) => {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
canvas.width = el.width
canvas.height = el.height
ctx?.drawImage(el,0,0,canvas.width,canvas.height)
return canvas.toDataURL('image/png')
}
})
}
// 使用 hooks
<template>
<div>
<img id='img' src='./assets/test.png'>
</div>
</template>
<script lang="ts" setup>
import useBase64 from './hooks'
useBase64({el: '#img'}).then(res=>{
window.console.log(res.baseUrl)
})
</script>