Vue 3 使用心得

1. Composition API 优势

逻辑组织更清晰

javascript 复制代码
// Vue 2 Options API
export default {
  data() {
    return {
      userList: [],
      loading: false
    }
  },
  methods: {
    fetchUsers() { /* ... */ }
  },
  computed: {
    activeUsers() { /* ... */ }
  }
}

// Vue 3 Composition API
import { ref, computed, onMounted } from 'vue'

export default {
  setup() {
    const userList = ref([])
    const loading = ref(false)
    
    const activeUsers = computed(() => {
      return userList.value.filter(user => user.active)
    })
    
    const fetchUsers = async () => {
      // ...
    }
    
    onMounted(() => {
      fetchUsers()
    })
    
    return {
      userList,
      loading,
      activeUsers,
      fetchUsers
    }
  }
}

逻辑复用更方便

javascript 复制代码
import { ref, reactive } from 'vue'

export function useAuth() {
  const user = ref(null)
  const isAuthenticated = computed(() => !!user.value)
  
  const login = async (credentials) => {
    // 登录逻辑
  }
  
  const logout = () => {
    user.value = null
  }
  
  return {
    user,
    isAuthenticated,
    login,
    logout
  }
}

// 在组件中使用
export default {
  setup() {
    const { user, isAuthenticated, login, logout } = useAuth()
    
    return {
      user,
      isAuthenticated,
      login,
      logout
    }
  }
}

2. 性能优化

更好的 Tree-shaking

javascript 复制代码
// 只引入需要的 API import { ref, computed, watch } from 'vue'

更高效的响应式系统

php 复制代码
javascript
// Vue 3 Proxy-based 响应式
const state = reactive({
  user: {
    profile: {
      name: 'John'
    }
  }
})

// Vue 2 Object.defineProperty
// 需要递归遍历所有属性

3. TypeScript 支持

typescript 复制代码
typescript
import { defineComponent, ref, PropType } from 'vue'

interface User {
  id: number
  name: string
  email: string
}

export default defineComponent({
  props: {
    users: {
      type: Array as PropType<User[]>,
      required: true
    }
  },
  setup(props) {
    const selectedUser = ref<User | null>(null)
    
    const selectUser = (user: User) => {
      selectedUser.value = user
    }
    
    return {
      selectedUser,
      selectUser
    }
  }
})

4. Teleport 组件

xml 复制代码
vue
<template>
  <div class="modal">
    <teleport to="body">
      <div class="modal-overlay" v-if="visible">
        <div class="modal-content">
          <slot></slot>
        </div>
      </div>
    </teleport>
  </div>
</template>

5. Suspense 组件

xml 复制代码
vue
<template>
  <Suspense>
    <template #default>
      <AsyncComponent />
    </template>
    <template #fallback>
      <div>Loading...</div>
    </template>
  </Suspense>
</template>

6. 多个 v-model 支持

xml 复制代码
vue
<template>
  <MyComponent 
    v-model:title="pageTitle" 
    v-model:content="pageContent" 
  />
</template>

<!-- MyComponent.vue -->
<template>
  <input v-model="title" />
  <textarea v-model="content" />
</template>

<script>
export default {
  props: ['title', 'content'],
  emits: ['update:title', 'update:content']
}
</script>

7. Fragment 支持

xml 复制代码
vue
<template>
  <!-- 不再需要单一根元素 -->
  <header>...</header>
  <main>...</main>
  <footer>...</footer>
</template>

8. 实用技巧

使用 watchEffect 自动追踪依赖

csharp 复制代码
javascript
import { ref, watchEffect } from 'vue'

const userId = ref(1)
const user = ref(null)

watchEffect(async () => {
  if (userId.value) {
    user.value = await fetchUser(userId.value)
  }
})

使用 provide/inject 进行依赖注入

javascript 复制代码
javascript
// 父组件
import { provide, ref } from 'vue'

export default {
  setup() {
    const theme = ref('dark')
    provide('theme', theme)
  }
}

// 子组件
import { inject } from 'vue'

export default {
  setup() {
    const theme = inject('theme')
    return { theme }
  }
}

使用自定义指令

javascript 复制代码
javascript
const MyDirective = {
  mounted(el, binding) {
    el.focus()
  }
}

export default {
  directives: {
    focus: MyDirective
  }
}

9. 常见陷阱与解决方案

响应式解构问题

scss 复制代码
javascript
// ❌ 错误:失去响应性
const { count, double } = useCounter()
 
// ✅ 正确:保持响应性
const counter = useCounter()
const { count, double } = toRefs(counter)

// 或者使用 reactive
const state = reactive(useCounter())

异步组件加载

javascript 复制代码
javascript
import { defineAsyncComponent } from 'vue'

const AsyncComponent = defineAsyncComponent({
  loader: () => import('./MyComponent.vue'),
  loadingComponent: LoadingComponent,
  errorComponent: ErrorComponent,
  delay: 200,
  timeout: 3000
})

10. 最佳实践

  1. 合理使用 Composition API:不是所有情况都需要使用,简单组件用 Options API 也很好
  2. 组件拆分:保持组件小巧,单一职责
  3. 状态管理:复杂应用使用 Pinia 或 Vuex
  4. 性能优化 :合理使用 v-memov-once 等优化手段
  5. 类型安全:尽可能使用 TypeScript 提高代码质量

Vue 3 带来了很多现代化的特性,让开发体验更加流畅,但也要根据项目实际情况选择合适的特性使用。

相关推荐
鹏北海-RemHusband1 分钟前
微前端实现方式:HTML Entry 与 JS Entry 的区别
前端·javascript·html
行走的陀螺仪24 分钟前
JavaScript 装饰器完全指南(原理/分类/场景/实战/兼容)
开发语言·javascript·ecmascript·装饰器
瘦的可以下饭了27 分钟前
3 链表 二叉树
前端·javascript
我那工具都齐_明早我过来上班32 分钟前
WebODM生成3DTiles模型在Cesium地图上会垂直显示问题解决(y-up-to-z-up)
前端·gis
粉末的沉淀38 分钟前
jeecgboot:electron桌面应用打包
前端·javascript·electron
1024肥宅41 分钟前
浏览器相关 API:DOM 操作全解析
前端·浏览器·dom
烟西44 分钟前
手撕React18源码系列 - Event-Loop模型
前端·javascript·react.js
空镜1 小时前
通用组件使用文档
前端·javascript