Skip to content

Vue.js框架

基础概念

Vue.js是一套用于构建用户界面的渐进式框架,易于上手,可以与其他库或现有项目整合。

核心特性

  • 响应式数据绑定: 数据变化自动更新视图
  • 组件化: 可复用的UI组件
  • 虚拟DOM: 高效的DOM更新机制
  • 渐进式: 可以逐步采用,从简单应用到复杂应用

基础语法

模板语法

vue
<template>
  <div id="app">
    <!-- 文本插值 -->
    <h1>{{ message }}</h1>
    
    <!-- 属性绑定 -->
    <img :src="imageSrc" :alt="imageAlt">
    
    <!-- 条件渲染 -->
    <div v-if="isVisible">显示内容</div>
    <div v-else>隐藏内容</div>
    
    <!-- 列表渲染 -->
    <ul>
      <li v-for="item in items" :key="item.id">
        {{ item.name }}
      </li>
    </ul>
    
    <!-- 事件处理 -->
    <button @click="handleClick">点击我</button>
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      message: 'Hello Vue!',
      imageSrc: '/logo.png',
      imageAlt: 'Vue Logo',
      isVisible: true,
      items: [
        { id: 1, name: 'Item 1' },
        { id: 2, name: 'Item 2' }
      ]
    }
  },
  methods: {
    handleClick() {
      console.log('Button clicked!')
    }
  }
}
</script>

<style scoped>
#app {
  text-align: center;
  margin-top: 60px;
}
</style>

组件系统

vue
<!-- 子组件 -->
<template>
  <div class="child-component">
    <h2>{{ title }}</h2>
    <p>{{ content }}</p>
    <button @click="$emit('update', newValue)">
      更新父组件
    </button>
  </div>
</template>

<script>
export default {
  name: 'ChildComponent',
  props: {
    title: {
      type: String,
      required: true
    },
    content: {
      type: String,
      default: '默认内容'
    }
  },
  data() {
    return {
      newValue: '新值'
    }
  }
}
</script>

<!-- 父组件 -->
<template>
  <div>
    <child-component
      :title="parentTitle"
      :content="parentContent"
      @update="handleUpdate"
    />
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue'

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      parentTitle: '父组件标题',
      parentContent: '父组件内容'
    }
  },
  methods: {
    handleUpdate(value) {
      this.parentContent = value
    }
  }
}
</script>

生命周期

javascript
export default {
  name: 'LifecycleDemo',
  
  // 创建阶段
  beforeCreate() {
    console.log('beforeCreate: 实例初始化之前')
  },
  
  created() {
    console.log('created: 实例创建完成')
  },
  
  // 挂载阶段
  beforeMount() {
    console.log('beforeMount: 挂载开始之前')
  },
  
  mounted() {
    console.log('mounted: 挂载完成')
  },
  
  // 更新阶段
  beforeUpdate() {
    console.log('beforeUpdate: 数据更新时')
  },
  
  updated() {
    console.log('updated: 数据更新完成')
  },
  
  // 销毁阶段
  beforeDestroy() {
    console.log('beforeDestroy: 实例销毁之前')
  },
  
  destroyed() {
    console.log('destroyed: 实例销毁完成')
  }
}

计算属性和侦听器

计算属性

javascript
export default {
  data() {
    return {
      firstName: 'John',
      lastName: 'Doe',
      items: [1, 2, 3, 4, 5]
    }
  },
  
  computed: {
    // 基本计算属性
    fullName() {
      return this.firstName + ' ' + this.lastName
    },
    
    // 带缓存的复杂计算
    filteredItems() {
      return this.items.filter(item => item > 2)
    },
    
    // 计算属性的getter和setter
    fullNameWithSetter: {
      get() {
        return this.firstName + ' ' + this.lastName
      },
      set(value) {
        const names = value.split(' ')
        this.firstName = names[0]
        this.lastName = names[1]
      }
    }
  }
}

侦听器

javascript
export default {
  data() {
    return {
      message: 'Hello',
      user: {
        name: 'John',
        age: 25
      }
    }
  },
  
  watch: {
    // 简单侦听
    message(newVal, oldVal) {
      console.log('message changed:', oldVal, '->', newVal)
    },
    
    // 深度侦听对象
    user: {
      handler(newVal, oldVal) {
        console.log('user changed:', newVal)
      },
      deep: true
    },
    
    // 立即执行
    immediate: true,
    
    // 侦听特定属性
    'user.name'(newVal, oldVal) {
      console.log('user.name changed:', oldVal, '->', newVal)
    }
  }
}

Vue 3 Composition API

基础用法

vue
<template>
  <div>
    <h1>{{ title }}</h1>
    <p>Count: {{ count }}</p>
    <button @click="increment">增加</button>
    <button @click="decrement">减少</button>
  </div>
</template>

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

export default {
  setup() {
    // 响应式数据
    const title = ref('Vue 3 Composition API')
    const count = ref(0)
    
    const state = reactive({
      firstName: 'John',
      lastName: 'Doe'
    })
    
    // 计算属性
    const fullName = computed(() => {
      return state.firstName + ' ' + state.lastName
    })
    
    // 方法
    const increment = () => {
      count.value++
    }
    
    const decrement = () => {
      count.value--
    }
    
    // 生命周期
    onMounted(() => {
      console.log('Component mounted')
    })
    
    return {
      title,
      count,
      fullName,
      increment,
      decrement
    }
  }
}
</script>

组合函数

javascript
// useCounter.js
import { ref, computed } from 'vue'

export function useCounter(initialValue = 0) {
  const count = ref(initialValue)
  
  const doubleCount = computed(() => count.value * 2)
  
  const increment = () => count.value++
  const decrement = () => count.value--
  const reset = () => count.value = initialValue
  
  return {
    count,
    doubleCount,
    increment,
    decrement,
    reset
  }
}

// 在组件中使用
import { useCounter } from './useCounter'

export default {
  setup() {
    const { count, doubleCount, increment, decrement, reset } = useCounter(10)
    
    return {
      count,
      doubleCount,
      increment,
      decrement,
      reset
    }
  }
}

路由管理

Vue Router基础

javascript
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: About
  },
  {
    path: '/user/:id',
    name: 'User',
    component: () => import('../views/User.vue'),
    props: true
  }
]

const router = createRouter({
  history: createWebHistory(),
  routes
})

export default router

路由导航

vue
<template>
  <div>
    <!-- 声明式导航 -->
    <router-link to="/">首页</router-link>
    <router-link to="/about">关于</router-link>
    <router-link :to="{ name: 'User', params: { id: 123 }}">
      用户页面
    </router-link>
    
    <!-- 编程式导航 -->
    <button @click="goToHome">去首页</button>
    <button @click="goToUser(456)">去用户页面</button>
    
    <!-- 路由出口 -->
    <router-view />
  </div>
</template>

<script>
export default {
  methods: {
    goToHome() {
      this.$router.push('/')
    },
    
    goToUser(id) {
      this.$router.push({
        name: 'User',
        params: { id }
      })
    }
  }
}
</script>

状态管理

Vuex基础

javascript
// store/index.js
import { createStore } from 'vuex'

export default createStore({
  state: {
    count: 0,
    user: null
  },
  
  mutations: {
    increment(state) {
      state.count++
    },
    setUser(state, user) {
      state.user = user
    }
  },
  
  actions: {
    async fetchUser({ commit }, userId) {
      const user = await api.getUser(userId)
      commit('setUser', user)
    }
  },
  
  getters: {
    doubleCount: state => state.count * 2,
    isLoggedIn: state => !!state.user
  }
})

在组件中使用

vue
<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double Count: {{ doubleCount }}</p>
    <button @click="increment">增加</button>
    <button @click="fetchUser(123)">获取用户</button>
  </div>
</template>

<script>
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'

export default {
  computed: {
    ...mapState(['count']),
    ...mapGetters(['doubleCount'])
  },
  
  methods: {
    ...mapMutations(['increment']),
    ...mapActions(['fetchUser'])
  }
}
</script>

最佳实践

性能优化

  1. 懒加载: 使用动态导入减少初始包大小
  2. 虚拟滚动: 处理大量数据时使用虚拟滚动
  3. keep-alive: 缓存组件状态
  4. v-show vs v-if: 频繁切换使用v-show

代码组织

  1. 组件命名: 使用PascalCase命名组件
  2. 文件结构: 按功能组织文件
  3. 类型检查: 使用TypeScript提高代码质量
  4. 测试: 编写单元测试和集成测试