看完vue3文档我学会了这些

1,182 阅读5分钟

PS

  1. 由于公司最近新项目使用了vue3+ts+antdv+vite的技术栈,这几天看了一下vue3系统的了解了一下vue3的新特性和写法,其中有自己的理解也有直接摘抄的文档中的定义,理解不到位的各位看官可以提出来。

  2. 下面其实是用markdown写的思维导图,使用markmap渲染出来的,另外这个文档更适合有一定vue2基础的人看,懂得都懂

  3. 一些概念感觉是vue2中的并未做过多解释,只是列出来让vue的概念完全,当然后续有补充的会持续更新

  4. 最后贴出实际markmap渲染出来的思维导图

截屏2021-11-17 下午9.39.34.png

新的响应式系统

  • Proxy
    • 对比 defineProperty 和 value setter
    • 兼容性(彻底放弃IE)
  • ref
    • 利用对象的get和set实现
    • 只拦截某一个属性的修改(value)
    • 简单数据结构
    • 复杂的对象则通过reactive函数对对象进行深度响应式
  • unref
    • 如果参数是一个 ref,则返回内部值,否则返回参数本身。
    • 等价于 val = isRef(val)? val.value: val
  • reactive
    • 利用Proxy实现
    • 复杂的数据结构,深度转换
    • 本质是proxy包装的data属性
    • 前身:Vue.observable()
    • 可以理解为一组单个ref
    • ref赋值给reactive会被解包
  • isProxy
  • isReactive
  • toRaw
    • 返回 reactive 或 readonly 代理的原始对象
    • 可用在对响应式数据处理但不需要代理访问/跟踪的开销,同时可避免触发更改
  • markRaw
    • 标记对象不再转换为proxy,返回对象本身
  • shallowReactive
    • 创建响应式代理,但不执行嵌套对象深层响应式转换
  • shallowReadonly
    • 创建proxy只自身property为只读,不执行嵌套对象的只读转换
  • toRefs
    • 用来解构响应式数据,将复杂数据拆解成多个ref数据
    • 被解构的数据则不是响应式的对象了
    • import { reactive, toRefs } from 'vue'
      const book = reactive({
        author: 'Vue Team',
        title: '2020',
      })
      let { author, title } = toRefs(book)
      title.value = 'Vue 3 Detailed Guide' // 我们需要使用 .value 作为标题,现在是 ref
      console.log(book.title) // 'Vue 3 Detailed Guide'
      
  • toRef
    • 对响应式数据对象的某个property新创建一个ref
    • 并保持与原对象的响应式连接(可以互相修改)
    • 如果源property不存在也会返回一个可用的ref
  • isRef
  • readonly
    • 将响应式数据copy一份儿,并不影响原响应式数据修改,但copy之后的数据不可修改
  • computed: 计算属性
    • import { ref, computed } from 'vue';
      // 简单用法
      const count = ref(0);
      const pluseOne = computed(() => count.value + 1);
      // get set
      const plusOn = computed({
        get: () => count.value + 1,
        set: (val) => {
          count.value = val - 1;
        }
      })
      // 第二个参数可以传入出发计算时的钩子函数 onTrack onTrigger
      // onTrack 是被计算响应式数据作为依赖被追踪时触发
      // onTrigger 是被计算响应式数据值被修改时触发
      
  • watchEffect
    • 立即执行副作用函数(回调)并自动追踪其以来的响应式数据
    • watchPostEffect(别名)flush: post DOM渲染后执行可以拿到DOM信息
    • watchSyncEffect(别名)flush: sync
  • watch
    • 可以侦听单个或者多个数据源(第一个参数)
    • 懒执行副作用函数,并必须有依赖的响应式数据 (第二个参数)
    • 深度:deep: true(第三个参数)
  • style使用
    • scoped
    • :deep()可以影响子组件
      • .a :deep(.b) {}
    • :slotted:插槽选择器,用于直接选择插槽内的元素
      • :slotted(div) {}
    • :global标记全局样式
      • :global(.red) {}
    • SFC中可以有多个style标签
    • v-bind绑定到样式属性

生命周期

  • Options API
    • beforeCreate
    • created
    • beforeMount
    • mounted
    • beforeUpdate
    • updated
    • beforeUnmount
    • unmounted
    • errorCaptured
    • renderTracked
    • renderTriggered
    • activated
    • deactivated
  • Composition API
    • 不需要beforeCreate和created
    • onBeforeMount
    • onMounted
    • onBeforeUpdate
    • onUpdated
    • onBeforeUnmount
    • onUnmounted
    • onErrorCaptured
    • onRenderTracked
    • onRenderTriggered
    • onActivated
    • onDeactivated

组合式API 和 setup

  • 计算属性和生命周期都可以脱离Vue组件单独使用,可以在单独的文件中导出方法来使用
  • setup
    • 作为一个载体可以更好的将组合API导出与视图关联起来
    • 在组件创建之前调用
      • beforeCreate 和 created
      • data property、computed property 或 methods解析之前
      • 无法使用this
    • 生命周期可以在vue中导出使用
      • onMounted(() => { something });
        
    • 需要显式的返回setup函数中定义的响应式数据和方法
    • 如果返回函数可以使用vue中导出的h函数来单独渲染
    • 参数
      • props:响应式数据,解构使用toRefs
      • context:可以直接解构 { attrs, slots, emit, expose }
  • <script setup>
    • 作为setup属性的语法糖,让开发更丝滑
    • 可以在顶层使用await调用异步函数
    • 可以和其他的<script>标签并存
    • 顶层的绑定会暴露给模板
    • 可直接使用defineProps和defineEmits
  • Provide/Inject(依赖注入)
    • 用于穿透多个组件传值
    • 需要注意响应式数据需要使用ref或者reactive包装后使用
    • 尽量在provide组件处修改依赖数据
    • 如果有在inject组件修改数据的需求可以在provide处传入修改函数
  • 一个例子:组合式API实现获取鼠标位置的功能
    • import {ref, onMounted,onUnmounted} from 'vue'
      export function useMouse(){
          const x = ref(0)
          const y = ref(0)
          function update(e) {
            x.value = e.pageX
            y.value = e.pageY
          }
          onMounted(() => {
            window.addEventListener('mousemove', update)
          })
        
          onUnmounted(() => {
            window.removeEventListener('mousemove', update)
          })
          return { x, y }
      } 
      
  • Vueuse

虚拟DOM

  • 轻量级的JavaScript对象

Mixin(混入)

自定义指令

  • 对DOM层有操作需求的可以自定义一个指令
    • focus
    • permission
    • ...

新的内置组件

  • Fragment:
    • Vue 3 组件不再要求有一个唯一的根节点,清除了很多无用的占位 div。
  • Teleport:
    • 允许组件渲染在别的元素内,主要开发弹窗组件的时候特别有用。
  • Suspense:
    • 异步组件,更方便开发有异步请求的组件。

封装自己的组件

  • 组件
    • defineProps
    • defineEmits
    • 插槽(slot)
  • Form组件(理解v-model)
    • v-model
    • props: modelValue
    • let emits = defineEmits(['update:modelValue])
    • 一个例子:<OrgSelect>
  • hooks(useXxx)

TypeScript

  • 入门可以参考我的一篇总结TypeScript入门写法总结
  • 编辑器VSCode
    • Volar插件
  • defineComponent
  • Props:
    • interface Book {
        title: string,
        year?: number
      }  
      fn: {
        type: Function as PropType<() => void>
      },
      book: {
        type: Object as ProType<Book>
      }
      
  • computed: computedProp(): string {}
  • ref: const year = ref<string | number>('2021)
  • reactive: const book = reactive<Book>()
  • 组件 const model = ref<InstanceType<typeof MyComponent>>()
  • 类型声明文件src/types/*.d.ts

Vite

  • vite.config.js

参考

  • vue3官方文档
  • 最后感兴趣的可以看看markmap这个工具是markdown转思维导图的,同时提供VSCode插件