# Vue 3全面指南:从入门到精通

Vue 3全面指南:从入门到精通

目录

  1. 基础概念与环境搭建
  2. 组合式API (Composition API)
  3. 响应式系统
  4. 组件开发
  5. 高级特性
  6. 性能优化
  7. 最佳实践

1. 基础概念与环境搭建

1.1 创建Vue 3项目

# 使用 Vite 创建项目
npm create vite@latest my-vue-app -- --template vue

# 使用 Vue CLI 创建项目
npm init vue@latest

1.2 项目结构

my-vue-app/
├── public/
├── src/
│   ├── assets/
│   ├── components/
│   ├── views/
│   ├── App.vue
│   └── main.js
├── package.json
└── vite.config.js

2. 组合式API (Composition API)

2.1 基础示例

<template>
  <div class="user-profile">
    <h1>{
   
   { userState.name }}的个人信息</h1>
    <div class="info">
      <p>年龄:{
   
   { userState.age }}</p>
      <p>邮箱:{
   
   { userState.email }}</p>
    </div>
    <button @click="updateAge">年龄+1</button>
  </div>
</template>

<script setup>
import { reactive, onMounted } from 'vue'

// 状态定义
const userState = reactive({
  name: '张三',
  age: 25,
  email: '[email protected]'
})

// 方法定义
const updateAge = () => {
  userState.age++
}

// 生命周期钩子
onMounted(() => {
  console.log('组件已挂载')
})
</script>

<style scoped>
.user-profile {
  padding: 20px;
  border: 1px solid #eee;
  border-radius: 8px;
}

.info {
  margin: 20px 0;
}
</style>

2.2 响应式系统

<template>
  <div class="counter">
    <h2>计数器示例</h2>
    <p>当前计数:{
   
   { count }}</p>
    <p>双倍值:{
   
   { doubleCount }}</p>
    <button @click="increment">增加</button>
    <button @click="reset">重置</button>
  </div>
</template>

<script setup>
import { ref, computed, watch } from 'vue'

// ref 响应式引用
const count = ref(0)

// computed 计算属性
const doubleCount = computed(() => count.value * 2)

// 方法
const increment = () => {
  count.value++
}

const reset = () => {
  count.value = 0
}

// watch 侦听器
watch(count, (newValue, oldValue) => {
  console.log(`计数从 ${oldValue} 变为 ${newValue}`)
})
</script>

2.3 生命周期钩子

<script setup>
import { onMounted, onUpdated, onUnmounted, onBeforeMount } from 'vue'

onBeforeMount(() => {
  console.log('组件挂载前')
})

onMounted(() => {
  console.log('组件已挂载')
})

onUpdated(() => {
  console.log('组件已更新')
})

onUnmounted(() => {
  console.log('组件已卸载')
})
</script>

3. 响应式系统

3.1 ref vs reactive

<script setup>
import { ref, reactive } from 'vue'

// ref 用于基本类型
const count = ref(0)
const message = ref('Hello')

// reactive 用于对象
const state = reactive({
  user: {
    name: '张三',
    age: 25
  },
  settings: {
    theme: 'dark'
  }
})

// 访问和修改
console.log(count.value) // 需要.value
console.log(state.user.name) // 直接访问

const updateState = () => {
  count.value++
  state.user.age++
}
</script>

3.2 计算属性和侦听器

<script setup>
import { ref, computed, watch, watchEffect } from 'vue'

const count = ref(0)
const message = ref('Hello')

// 计算属性
const doubleCount = computed(() => count.value * 2)
const reversedMessage = computed(() => message.value.split('').reverse().join(''))

// 侦听器
watch(count, (newValue, oldValue) => {
  console.log(`count changed from ${oldValue} to ${newValue}`)
})

// watchEffect
watchEffect(() => {
  console.log(`count is: ${count.value}`)
  console.log(`message is: ${message.value}`)
})
</script>


````markdown
## 4. 组件开发

### 4.1 Props定义
````vue
<script setup>
import { defineProps } from 'vue'

const props = defineProps({
  title: {
    type: String,
    required: true
  },
  count: {
    type: Number,
    default: 0
  },
  user: {
    type: Object,
    default: () => ({
      name: '默认用户',
      age: 20
    })
  }
})
</script>

4.2 事件发射

<template>
  <div>
    <button @click="handleClick">点击发射事件</button>
  </div>
</template>

<script setup>
import { defineEmits } from 'vue'

const emit = defineEmits(['update', 'delete'])

const handleClick = () => {
  emit('update', { id: 1, data: 'new data' })
}
</script>

4.3 插槽使用

<template>
  <div class="card">
    <header>
      <slot name="header">默认标题</slot>
    </header>
    <main>
      <slot>默认内容</slot>
    </main>
    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

5. 高级特性

5.1 Teleport组件

<template>
  <button @click="showModal = true">打开模态框</button>
  
  <teleport to="body">
    <div v-if="showModal" class="modal">
      <h3>模态框标题</h3>
      <p>这是一个传送门示例</p>
      <button @click="showModal = false">关闭</button>
    </div>
  </teleport>
</template>

<script setup>
import { ref } from 'vue'

const showModal = ref(false)
</script>

<style scoped>
.modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: white;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}
</style>

5.2 Suspense异步组件

<template>
  <Suspense>
    <template #default>
      <async-component />
    </template>
    <template #fallback>
      <div class="loading">加载中...</div>
    </template>
  </Suspense>
</template>

<script setup>
import { defineAsyncComponent } from 'vue'

const AsyncComponent = defineAsyncComponent(() =>
  import('./components/HeavyComponent.vue')
)
</script>

5.3 自定义指令

<script setup>
// v-focus 指令
const vFocus = {
  mounted: (el) => el.focus()
}

// v-click-outside 指令
const vClickOutside = {
  mounted: (el, binding) => {
    el._clickOutside = (event) => {
      if (!(el === event.target || el.contains(event.target))) {
        binding.value(event)
      }
    }
    document.addEventListener('click', el._clickOutside)
  },
  unmounted: (el) => {
    document.removeEventListener('click', el._clickOutside)
  }
}
</script>

6. 性能优化

6.1 动态组件优化

<template>
  <component 
    :is="currentComponent" 
    v-bind="componentProps"
  />
</template>

<script setup>
import { shallowRef, markRaw } from 'vue'
import ComponentA from './ComponentA.vue'
import ComponentB from './ComponentB.vue'

// 使用 shallowRef 和 markRaw 优化动态组件
const components = {
  a: markRaw(ComponentA),
  b: markRaw(ComponentB)
}

const currentComponent = shallowRef(components.a)
</script>

6.2 大列表优化

<template>
  <div class="virtual-list">
    <div 
      class="list-container"
      :style="{ height: totalHeight + 'px' }"
    >
      <div
        v-for="item in visibleItems"
        :key="item.id"
        :style="{
          position: 'absolute',
          top: item.top + 'px'
        }"
      >
        {
   
   { item.content }}
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue'

const itemHeight = 50
const visibleCount = Math.ceil(window.innerHeight / itemHeight)
const startIndex = ref(0)

const items = Array.from({ length: 10000 }, (_, i) => ({
  id: i,
  content: `Item ${i}`,
}))

const visibleItems = computed(() => {
  return items
    .slice(startIndex.value, startIndex.value + visibleCount)
    .map((item, index) => ({
      ...item,
      top: (startIndex.value + index) * itemHeight
    }))
})

const totalHeight = items.length * itemHeight
</script>

7. 最佳实践

7.1 组合式函数封装

// useApi.js
import { ref } from 'vue'

export function useApi(apiFunc) {
  const data = ref(null)
  const loading = ref(false)
  const error = ref(null)

  const execute = async (...args) => {
    loading.value = true
    error.value = null
    
    try {
      data.value = await apiFunc(...args)
    } catch (e) {
      error.value = e
    } finally {
      loading.value = false
    }
  }

  return {
    data,
    loading,
    error,
    execute
  }
}

// 使用示例
const { data, loading, error, execute } = useApi(fetchUserData)

7.2 状态管理

// store/user.js
import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
  state: () => ({
    user: null,
    token: null
  }),
  
  getters: {
    isLoggedIn: (state) => !!state.token
  },
  
  actions: {
    async login(credentials) {
      const { token, user } = await api.login(credentials)
      this.token = token
      this.user = user
    },
    
    logout() {
      this.token = null
      this.user = null
    }
  }
})

总结

Vue 3提供了强大的功能和优秀的性能:

  1. 响应式系统

    • 基于Proxy的响应式
    • 更好的性能
    • 更完善的类型支持
  2. 组合式API

    • 更好的代码组织
    • 更强的代码复用
    • 更清晰的逻辑分离
  3. 性能优化

    • 更小的打包体积
    • 更快的渲染速度
    • 更好的内存使用
  4. 开发体验

    • 更好的TypeScript支持
    • 更强大的开发工具
    • 更完善的生态系统

参考资料

  1. Vue 3官方文档
  2. Vue 3 GitHub仓库
  3. Vue 3迁移指南

本文详细介绍了Vue 3的核心特性和最佳实践,希望能帮助开发者更好地理解和使用Vue 3。如有问题,欢迎在评论区讨论。

猜你喜欢

转载自blog.csdn.net/weixin_57190021/article/details/146050099
今日推荐