vue3 正式版开发体验心得!

1,356 阅读3分钟

最近使用Vue3+elmentPlus 开发了项目,收获的体验心得。

1. 安装

yarn install vue@3 vuex@4 vue-router@4

2. Options API 和 Composition API

Options API 问题
  • 在特定的区域(data,methods,watch,computed...)编写负责相同功能的代码。 随着业务复杂度越来越高,代码量会不断的加大,后续维护非常的复杂,代码可复用性也不高。
Composition API

特点:使用 composition api 可以更加优雅的组织代码、函数,让相关功能的代码更加有序的组织在一起

  • Vue 核心团队将 Composition API 描述为“一组基于功能的附加 API,可以灵活地组合组件逻辑”
  • 使用 Composition API 编写的代码更易读,而且没有任何幕后的魔力,更容易阅读和学习

3. 核心:setup()

  • 执行时机:在 beforeCreate 钩子之前被调用
  • setup()中没有了 this,this 为 undefined
  • setup 的意义:让你对模块的逻辑进行细化提取,以便于让你的组件更为通用,更容易封装,从而减少代码量。

5. 生命周期函数和响应式数据使用

  • 1)原 data 中定义的属性,改为使用 ref() 和 reactive()
  • 2)原 computed 中定义的属性,改为使用 computed()
  • 3)原 methods 中定义的方法,改为使用 setup()中定义,并且由 setup()返回
  • 4)原 watch 中定义的被观察属性,改为使用 watchEffect()
<template>
  <div ref="content">test content</div>
</template>;

import { ref, reactive, onBeforeUpdate, onUpdated, onMounted, onUnmounted, computed, watch, watchEffect } from "vue";
export default {
  props:{
    status:{
      type: Number,
      default:0
    }
  },
  setup(props, context) {
    console.log(this) // undefined
    // Attribute (非响应式对象)
    console.log(context.attrs)

    // 插槽 (非响应式对象)
    console.log(context.slots)

    // 触发事件 (方法)
    console.log(context.emit)

    let name = ref("ifredom")
    const contentDom = ref("content") // 获取dom
    const arr1 = ref([])
    const arr2 = reactive({
      arr: []
    })
    const arr3 = reactive([])
    const ceo = reactive({
      name: "雷军",
      sex: "man",
      age: 44,
    });

    // computed  使用
    const workAge = computed(() => {
      console.log("工作十年后");
      return ceo.age + 10;
    });

    // 监听单一数据源,此处为 name
    watch(name, (newVal, oldVal) => {
      console.log("name改变了")
      console.log(name.value)
    })

    // 监听函数内所有数据源
    const stop = watchEffect(() => {
      console.log("name改变了")
      console.log(name.value)
    })

    // 调用,则选择停止监听
    // stop()

    // 生命周期函数
    onBeforeMount(() => {
      console.log("onBeforeMount---")
    })

    onMounted(() => {
      console.log('onMounted---')
    })

    onBeforeUpdate(() => {
      console.log('onBeforeUpdate---')
    })

    onUpdated(() => {
      console.log('onUpdated---')
    })

    onUnmounted(() => {
      console.log('onUnmounted---')
    })

    // 捕获子孙组件被调用错误 (err, vm, info)
    onErrorCaptured(() => {
      console.log('onErrorCaptured---')
    })

    // 捕获渲染栈异常
    onRenderTracked(() => {
      console.log('onRenderTracked---')
    })

    // 渲染识别
    onRenderTriggered(() => {
      console.log('onRenderTriggered---')
    })

    // 数组赋值 - object 对象赋值同理
    // 方法1
      arr1.value = [1, 2, 3]
    // 方法2
      arr2.arr = [1, 2, 3]
    // 方法3
      arr3.push(...[1, 2, 3])

    // methods 函数使用
    function fetchUserInfo(){
      console.log("查询用户信息")
    }


    return {
      // 返回 (当你在template中用到此方法时才需要返回,否则不用)
      name,
      contentDom,
      arr1,
      arr2,
      arr3,
      ceo,
      fetchUserInfo,
    }
  },
}

6. 全局属性 和 Vuex 使用

import { nextTick, inject, getCurrentInstance} from "vue"
import { useStore } from "vuex"
import { useRoute } from "vue-router"

export default {
  setup() {
    // nextTick 使用
    nextTick(()=>{
      console.log('Now DOM is updated')
    })

    const route = useRoute(); // route 使用
    const store = useStore()

    // vuex4中的定义方式与vuex3中一模一样
    // 获取 user 定义的 state 中的 roles 属性
    const roles = store.state.user.roles
    // 结合 computed 使用
    const sidebar = computed(() => store.state.app.sidebar)

    // 方法一:全局注入属性(provide)
    // 在 main.js 中 从 vue 导出 provide 再使用:app.provide('Platform', '移动端')
    // 组件中获取 Platform
    const platform = inject('Platform') // '移动端'

    // 方法二:挂载到全局实例属性上(globalProperties)
    //在 main.js 中: app.config.globalProperties.Platform = '移动端'
    const { ctx } = getCurrentInstance() // 获取当前实例
    // 与以前this获取原型上东西一样
    // ctx.$parent  父组件
    // ctx.$nextTick  组件更新完毕
    // ctx.$store  VueX
    // 组件中获取 Platform
    console.log(ctx.Platform)

    return {
      roles,
      sidebar,
      platform
    };
  },
};