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

相关推荐
-凌凌漆-1 分钟前
【vue】选项式api与组合式api
前端·javascript·vue.js
2601_949809593 分钟前
flutter_for_openharmony家庭相册app实战+通知设置实现
android·javascript·flutter
可触的未来,发芽的智生26 分钟前
发现:认知的普适节律 发现思维的8次迭代量子
javascript·python·神经网络·程序人生·自然语言处理
BYSJMG1 小时前
计算机毕业设计选题推荐:基于大数据的肥胖风险分析与可视化系统详解
大数据·vue.js·数据挖掘·数据分析·课程设计
0思必得01 小时前
[Web自动化] Selenium处理文件上传和下载
前端·爬虫·python·selenium·自动化·web自动化
phltxy2 小时前
Vue3入门指南:从环境搭建到数据响应式,开启高效前端开发之旅
前端·javascript·vue.js
小飞大王6663 小时前
CSS基础知识
前端·css
Charlie_lll3 小时前
学习Three.js–风车星系
前端·three.js
代码游侠3 小时前
学习笔记——Linux内核与嵌入式开发1
linux·运维·前端·arm开发·单片机·嵌入式硬件·学习
玩电脑的辣条哥3 小时前
幽灵回复AI已回复但前端不显示的排查与修复
前端·人工智能