Files
KintoneAppBuilder/frontend/VUE3.0编程规范.md

9.9 KiB
Raw Blame History

以下是一份 Vue 3 和 TypeScript 的编程规范:

1. 组件定义

  • 推荐使用 defineComponent 来定义组件,以获取 TypeScript 的类型支持。
import { defineComponent } from 'vue'

export default defineComponent({
  // 组件选项
})

2. 数据定义

  • 使用 reactive 定义响应式对象。
  • 使用 ref 定义响应式单值。
  • 使用 computed 定义计算属性。
import { reactive, ref, computed } from 'vue'

const state = reactive({
  count: 0,
  message: 'Hello Vue 3'
})

const count = ref(0)

const doubledCount = computed(() => state.count * 2)

3. 生命周期钩子

  • 使用 onMountedonUpdated 等生命周期钩子,而不是 beforeCreatecreatedbeforeMountmountedbeforeUpdateupdatedbeforeUnmountunmounted
import { onMounted } from 'vue'

onMounted(() => {
  console.log('Component is mounted.')
})

4. 组件通信

  • 使用 propsemit 实现父子组件通信。
  • 使用 provideinject 实现祖先和后代组件通信。
  • 不再推荐使用 event bus 进行任意组件间的通信,可以使用 Vuex 或者全局 provide/inject 替代。
// 父组件
<ChildComponent @my-event="handleEvent" />

// 子组件
this.$emit('my-event', eventData)

5. 异步处理

  • 使用 async/await 进行异步处理。
  • 使用 Suspenseasync setup() 处理异步依赖。
import { ref, onMounted } from 'vue'
import axios from 'axios'

onMounted(async () => {
  const response = await axios.get('https://api.example.com/data')
  data.value = response.data
})

6. Vue Router 和 Vuex

  • 使用 Vue Router 4 和 Vuex 4它们是为 Vue 3 重新设计的。
  • 使用 useRouteruseRoute 钩子函数在组件中使用 router。
  • 使用 useStore 钩子函数在组件中使用 Vuex store。
import { useStore } from 'vuex'
import { useRouter } from 'vue-router'

const store = useStore()
const router = useRouter()

7. 组件模板

  • 使用 v-model 代替 .sync 修饰符进行双向绑定。
  • 使用 v-for:key 渲染列表。
  • 使用 v-ifv-elsev-else-if 进行条件渲染。
  • 使用 v-on 或者 @ 监听事件。
  • 使用 v-bind 或者 : 绑定属性。
<template>
  <div v-if="condition">If block</div>
  <div v-else>Else block</div>

  <ul>
    <li v-for="(item, index) in list" :key="index">{{ item }}</li>
  </ul>

  <button @click="handleClick">Click me</button>
</template>
  1. 使用类型注解和接口

    在 TypeScript 中,尽可能使用类型注解和接口来提供更完善的类型信息和类型检查。这将有助于发现和预防错误。

    interface User {
      name: string;
      age: number;
    }
    
    const user: User = {
      name: 'John',
      age: 30
    }
    
  2. 模块化和组件化

    尽可能将功能和逻辑模块化和组件化,使得代码更易于理解和维护。特别是使用 Composition API 时,可以将公共的逻辑封装成 composable 函数。

    下面是一个使用 Suspenseaxios 的示例,这个示例将会从一个 JSON Placeholder API 获取数据:

    首先,我们创建一个 composable 函数,用于获取数据:

    import { ref } from 'vue'
    import axios from 'axios'
    
    export function useAsyncData(url: string) {
      const data = ref(null)
      const error = ref(null)
    
      const fetchData = async () => {
        try {
          const response = await axios.get(url)
          data.value = response.data
        } catch (e) {
          error.value = e
        }
      }
    
      return { data, error, fetchData }
    }
    

    然后,我们创建一个 Vue 组件来使用这个函数:

    <template>
      <Suspense>
        <template #default>
          <div v-if="error">{{ error.message }}</div>
          <div v-else>{{ data }}</div>
        </template>
        <template #fallback>
          <div>Loading...</div>
        </template>
      </Suspense>
    </template>
    
    <script lang="ts">
    import { defineComponent, onMounted } from 'vue'
    import { useAsyncData } from './composables/useAsyncData'
    
    export default defineComponent({
      setup() {
        const { data, error, fetchData } = useAsyncData('https://jsonplaceholder.typicode.com/posts/1')
    
        onMounted(fetchData)
    
        return { data, error }
      },
    })
    </script>
    
    <style scoped>
    /* 在这里添加 CSS 样式 */
    </style>
    

    在这个示例中,我们在 useAsyncData 函数中获取数据。当 onMounted 钩子函数被调用时(也就是当组件挂载完成后),我们开始获取数据。这个过程是异步的,因此我们在 Suspense 组件的 #fallback 插槽中显示一个 "Loading..." 的提示。一旦数据加载完成,Suspense 组件的 #default 插槽就会被渲染,并显示获取到的数据。

  3. 良好的代码风格

    遵循一致的代码风格和代码质量规则,例如使用 ESLint 和 Prettier 来检查和格式化代码。

  4. 单元测试和端到端测试

    对关键的组件和函数编写单元测试,对用户的主要操作路径编写端到端测试,确保功能的正确性。

  5. 注释和文档

    对复杂的逻辑和函数编写注释,提供必要的项目文档,帮助其他开发者理解和使用你的代码。

  6. 以下是 Vue 2 中被废弃或改变的部分API以及在 Vue 3 中的替代方案:

Vue 2.x Vue 3.0 说明
Vue.set / this.$set 响应式数据现在是默认的,无需使用这些方法 Vue 3 的响应式系统是从头开始构建的,所有的对象和数组都是响应式的
Vue.delete / this.$delete 无需使用这些方法 在 Vue 3 中,你只需要使用 delete 操作符即可
filters 无对应项 Vue 3 不再支持过滤器,建议使用计算属性或方法替代
Vue.observable reactive reactive 替代 Vue.observable,实现数据的响应式
Vue.prototype app.config.globalProperties 在 Vue 3 中,全局 API 已经改变,Vue.prototypeapp.config.globalProperties 替代
Vue.component, Vue.directive, Vue.mixin, Vue.use app.component, app.directive, app.mixin, app.use 全局注册的 API 改变,如 Vue.component 变为 app.component
beforeDestroydestroyed 生命周期钩子 beforeUnmountunmounted 生命周期钩子名字变化,beforeDestroydestroyed 分别改为 beforeUnmountunmounted
$on, $off, $once 无对应项 Event Bus方法被移除需要用户自行实现或者使用第三方库
v-model 在自定义组件上使用 需要明确的 modelValueupdate:modelValue Vue 3 对 v-model 的改动使其在自定义组件上更具灵活性
functional 选项 无对应项 Vue 3 不再支持函数式组件的写法,而是推荐使用 render 函数或 setup 函数
异步组件的 functional 写法 defineAsyncComponent 异步组件的创建方式更改,通过 defineAsyncComponent 方法创建
destroyedbeforeDestroy 钩子函数 unmountedbeforeUnmount 生命周期钩子的名称已改为更直观的名称,以更好地表示其在组件实例生命周期中的角色
Vue.extend defineComponent Vue 3 使用 defineComponent 方法定义组件,有更好的类型推断

注意Vue 3 对于 Options API 和 Composition API 提供了完全的支持,你可以在一个组件中混合使用这两种 API。不过为了代码的一致性和可读性建议在一个项目中选择一种 API 并坚持使用。

  • 以下是 Vue 3.0 中的 Composition API 函数的基本说明,以及与 Options API 的对比
Composition API 说明 对应的 Options API
setup setup 是一个新引入的组件选项,用于使用 Composition API。它是组件内部使用 Composition API 的入口。
ref ref 函数用于创建一个响应式的数据。它接收一个参数,返回一个响应式的 Ref 对象。 data
reactive reactive 函数用于创建一个响应式的对象。它接收一个普通对象,返回一个响应式的对象。 data
computed computed 函数用于创建一个计算属性。它接收一个 getter 函数或者一个具有 getter 和 setter 的对象,返回一个响应式的 Ref 对象。 computed
watch watch 函数用于响应式地跟踪和触发副作用。它接收一个响应式的源和一个执行副作用的回调函数。 watch
watchEffect watchEffect 函数用于立即执行传入的一个函数,并响应式地追踪其依赖,并在其依赖变更时重新运行该函数。
onMounted onMounted 函数在组件被挂载时调用。它接收一个在组件挂载后执行的回调函数。 mounted
onUnmounted onUnmounted 函数在组件被卸载时调用。它接收一个在组件卸载后执行的回调函数。 beforeDestroy/unmounted
onUpdated onUpdated 在组件更新后调用。它接收一个在组件更新后执行的回调函数。 updated
provide provide 函数用于在组件上定义一个可以被后代组件注入的值。它接收一个提供的键和值。 有,与 provide/inject 相似但是属性而不是函数
inject inject 函数用于在组件中注入一个由祖先组件提供的值。它接收一个注入的键。 有,但与 provide/inject 相似但是属性而不是函数

值得注意的是,虽然一些 Composition API 函数与 Options API 的某些选项有相似之处,但它们的工作方式和使用方式可能有所不同。在实际使用中,你需要根据具体的使用场景和需求选择合适的 API。