一文快速复习vue3

93 阅读3分钟

1. Vue 3 简介与新特性

Vue 3 是一款用于构建用户界面的​​渐进式 JavaScript 框架​​。相比于 Vue 2,它在性能、开发体验和类型支持方面都有显著提升。

  • ​性能提升​​:打包大小减少 41%,初次渲染快 55%,更新渲染快 133%,内存减少 54%。

  • ​更好的 TypeScript 支持​​:Vue 3 本身由 TypeScript 编写,提供了更好的类型推导和开发体验。

  • ​新特性​​:引入了 Composition API、Fragment、Teleport、Suspense 等新特性。

  • ​Vue 2 停止维护​​:Vue 2 已于 2023 年 12 月 31 日停止维护,官方推荐升级到 Vue 3。

2. 响应式系统

Vue 3 使用 ​​Proxy API​​ 替代了 Vue 2 中的 Object.defineProperty 来实现响应式,解决了 Vue 2 中无法检测数组索引变化和对象属性添加/删除的问题,并提升了性能。

特性Vue 2Vue 3
实现方式Object.definePropertyProxy
数组检测需要重写数组方法直接支持
属性增删无法直接检测直接检测
性能相对较低更高

在 Vue 3 中,主要通过 ref和 reactive来创建响应式数据:

  • ​ref​​:用于定义​​基本类型数据​​(也可以定义对象或数组)。在 JavaScript 中操作需要通过 .value,但在模板中不需要。

    import { ref } from 'vue';
    const count = ref(0);
    console.log(count.value); // 0
    
  • ​reactive​​:用于定义​​对象或数组类型数据​​。直接操作属性即可。

    import { reactive } from 'vue';
    const state = reactive({ count: 0 });
    console.log(state.count); // 0
    

​计算属性​​ (computed) 和​​侦听器​​ (watchwatchEffect) 也是响应式系统的重要组成部分:

  • ​computed​​:基于依赖的响应式数据计算并返回一个缓存的值。

    import { ref, computed } from 'vue';
    const count = ref(0);
    const doubleCount = computed(() => count.value * 2);
    
  • ​watch​​:监听一个或多个响应式数据源的变化,并执行回调函数。

    import { ref, watch } from 'vue';
    const count = ref(0);
    watch(count, (newValue, oldValue) => {
      console.log(`count changed from ${oldValue} to ${newValue}`);
    });
    
  • ​watchEffect​​:立即运行一个函数,并响应式地追踪其依赖,并在依赖变更时重新执行。

    import { ref, watchEffect } from 'vue';
    const count = ref(0);
    watchEffect(() => {
      console.log(`count is: ${count.value}`);
    });
    

3. 组合式 API (Composition API)

Composition API 是 Vue 3 的​​核心新特性​​,它允许你通过函数形式组织组件逻辑,提高代码的复用性和可维护性,尤其适合复杂组件。

  • ​setup 函数​​:Composition API 的“舞台”,组件中使用的数据、方法等都在此配置。它在 beforeCreate之前执行,this为 undefined

    import { ref } from 'vue';
    
    export default {
      setup(props, context) {
        // props 是组件接收的属性
        // context 包含 attrs, slots, emit 等
        const count = ref(0);
        function increment() {
          count.value++;
        }
        // 返回的对象中的属性和方法可在模板中使用
        return {
          count,
          increment
        };
      }
    };
    
  • ​响应式 API​​:如之前提到的 refreactivecomputedwatchwatchEffect

  • ​生命周期钩子​​:Composition API 提供了对应的生命周期函数(如 onMountedonUpdated等),可以在 setup中使用。

  • ​代码复用​​:通过自定义 Hook 函数来复用逻辑。

    // useCounter.js
    import { ref } from 'vue';
    
    export function useCounter() {
      const count = ref(0);
      function increment() {
        count.value++;
      }
      return { count, increment };
    }
    
    // MyComponent.vue
    import { useCounter } from './useCounter';
    
    export default {
      setup() {
        const { count, increment } = useCounter();
        return { count, increment };
      }
    };
    

4. 生命周期

Vue 3 的生命周期钩子与 Vue 2 相比有一些变化和更名。

Options APIComposition API描述
beforeCreate-实例初始化后
created-实例创建完成
beforeMountonBeforeMount挂载之前
mountedonMounted挂载完成
beforeUpdateonBeforeUpdate数据更新前
updatedonUpdated数据更新后
beforeUnmountonBeforeUnmount卸载之前
unmountedonUnmounted卸载完成
errorCapturedonErrorCaptured捕获到子孙组件错误时

在 setup()函数中使用 Composition API 生命周期钩子:

import { onMounted, onUnmounted } from 'vue';

export default {
  setup() {
    onMounted(() => {
      console.log('Component is mounted!');
    });
    onUnmounted(() => {
      console.log('Component is unmounted!');
    });
  }
};

5. 模板语法与指令

Vue 的模板语法允许你声明式地将数据渲染到 DOM。

  • ​插值​​:使用双大括号 {{ }}

    <span>{{ message }}</span>
    
  • ​指令​​:带有 v-前缀的特殊属性。

指令描述
v-bind(:)动态绑定属性
v-on(@)绑定事件监听器
v-model在表单元素上创建双向数据绑定
v-ifv-show条件性地渲染元素。v-if是真正的条件渲染;v-show只是切换 displayCSS 属性。
v-for基于源数据多次渲染元素或模板块。​​务必指定唯一的 key​。
v-html更新元素的 innerHTML(注意防止 XSS 攻击)
v-text更新元素的 textContent

v-model的用法​​:

<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>

v-for的用法​​:

<ul>
  <li v-for="(item, index) in items" :key="item.id">
    {{ index }} - {{ item.message }}
  </li>
</ul>

6. 组件与通信

组件是 Vue 应用的基石。

  • ​单文件组件 (SFC)​​:即 .vue文件,包含 <template><script><style>三个部分。

    <template>
      <div>{{ msg }}</div>
    </template>
    
    <script>
    export default {
      props: ['msg'],
      setup() {
        // ...
      }
    }
    </script>
    
    <style scoped>
    /* 样式 */
    </style>
    
  • ​组件通信​​:

    • ​Props​​:父组件向子组件传递数据。

      <!-- 父组件 -->
      <ChildComponent :message="parentMsg" />
      
      <!-- 子组件 -->
      <script>
      export default {
        props: ['message']
      }
      </script>
      
    • ​自定义事件​​:子组件向父组件传递消息。

      <!-- 子组件 -->
      <button @click="$emit('enlarge-text')">Enlarge text</button>
      
      <!-- 父组件 -->
      <ChildComponent @enlarge-text="handleEnlargeText" />
      
    • ​Provide / Inject​​:跨层级组件通信。

      // 祖先组件
      import { provide } from 'vue';
      export default {
        setup() {
          provide('theme', 'dark');
        }
      };
      
      // 后代组件
      import { inject } from 'vue';
      export default {
        setup() {
          const theme = inject('theme', 'light'); // 'light' 为默认值
          return { theme };
        }
      };
      

7. 路由与状态管理

对于单页面应用 (SPA),路由和状态管理几乎是必不可少的。

  • ​路由 (Vue Router)​​:官方路由管理器。

    // router/index.js
    import { createRouter, createWebHistory } from 'vue-router';
    import Home from '../views/Home.vue';
    
    const routes = [
      { path: '/', name: 'Home', component: Home },
      { path: '/about', name: 'About', component: () => import('../views/About.vue') } // 路由懒加载
    ];
    
    const router = createRouter({
      history: createWebHistory(),
      routes
    });
    
    export default router;
    
    // main.js
    import { createApp } from 'vue';
    import App from './App.vue';
    import router from './router';
    
    const app = createApp(App);
    app.use(router);
    app.mount('#app');
    
  • ​状态管理 (Pinia)​​:Vue 3 官方推荐的状态管理库(替代 Vuex)。

    Pinia 的 Store 中包含三个概念:stategetteraction

    // stores/counter.js
    import { defineStore } from 'pinia';
    
    export const useCounterStore = defineStore('counter', {
      state: () => ({ count: 0 }),
      getters: {
        doubleCount: (state) => state.count * 2
      },
      actions: {
        increment() {
          this.count++;
        }
      }
    });
    
    // 组件中使用
    import { useCounterStore } from '@/stores/counter';
    
    export default {
      setup() {
        const counterStore = useCounterStore();
        return { counterStore };
      }
    };
    

8. 生态系统与工具

  • ​构建工具​​:

    • ​Vite​​:新一代前端构建工具,开发环境启动速度极快,推荐用于新项目。

      npm create vite@latest my-vue-app -- --template vue
      cd my-vue-app
      npm install
      npm run dev
      
    • ​Vue CLI​​:虽然仍可使用,但已处于维护模式。

  • ​UI 框架​​:可根据项目需求选择:

    • Element Plus
    • Ant Design Vue
    • Naive UI
    • TDesign
  • ​TypeScript 支持​​:Vue 3 对 TypeScript 提供了更好的支持。

    import { defineComponent } from 'vue';
    
    interface User {
      name: string;
      age: number;
    }
    
    export default defineComponent({
      props: {
        user: {
          type: Object as () => User,
          required: true
        }
      },
      setup(props) {
        // props.user 具有 User 类型
      }
    });
    

9. 性能优化与新特性

Vue 3 在性能方面做了许多改进:

  • ​Tree-shaking​​:未引入的 API 在最终打包产物中会被移除,减小体积。

  • ​静态提升​​:编译时对静态节点进行提升,减少重渲染时的开销。

  • ​Fragment​​:组件可以有多个根节点,无需额外包裹。

  • ​Teleport​​:可以将组件的内容渲染到 DOM 树的指定位置,常用于模态框、弹窗等。

    <teleport to="body">
      <div class="modal">
        This modal will be rendered at the bottom of the body.
      </div>
    </teleport>
    
  • ​Suspense​​:异步组件加载时显示占位内容(实验性特性)。

    <Suspense>
      <template #default>
        <AsyncComponent />
      </template>
      <template #fallback>
        <div>Loading...</div>
      </template>
    </Suspense>