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 带来了很多现代化的特性,让开发体验更加流畅,但也要根据项目实际情况选择合适的特性使用。

相关推荐
haofafa6 分钟前
JavaScript性能优化实战
开发语言·javascript·性能优化
我叫张小白。14 分钟前
TypeScript对象类型与接口:构建复杂数据结构
前端·javascript·typescript
O***p60419 分钟前
JavaScript增强现实开发
开发语言·javascript·ar
墨客希20 分钟前
如何快速掌握大型Vue项目
前端·javascript·vue.js
大福ya35 分钟前
AI开源项目改造NextChat(ChatGPT-Next-Web)实现前端SSR改造打造一个初始框架
前端·chatgpt·前端框架·开源·aigc·reactjs·ai编程
samroom37 分钟前
langchain+ollama+Next.js实现AI对话聊天框
javascript·人工智能·langchain
n***33351 小时前
SpringBoot返回文件让前端下载的几种方式
前端·spring boot·后端
纯粹的热爱1 小时前
🌐 阿里云 Linux 服务器 Let's Encrypt 免费 SSL 证书完整部署指南
前端
北辰alk1 小时前
Vue3 自定义指令深度解析:从基础到高级应用的完整指南
前端·vue.js
AAA阿giao1 小时前
使用 Vite + Vue 3 搭建项目并配置路由的全流程(含国内镜像加速)
vue.js·node.js·vite