【涅槃】Vue3学习笔记(三)

709 阅读7分钟

vue3中生命周期的认识

在 Vue 3 中,生命周期钩子是组件在不同阶段执行的回调函数,用于在组件的创建、挂载、更新和销毁过程中插入自定义逻辑。与 Vue 2 相比,Vue 3 的生命周期钩子在功能上保持一致,但在命名和使用方式上有一些变化,尤其是在 Composition API 中。

Vue 3 生命周期的阶段

创建阶段(Creation):

  • 组件实例被创建,数据初始化。
  • 对应的生命周期钩子:beforeCreatecreated

挂载阶段(Mounting):

  • 组件被插入到 DOM 中。
  • 对应的生命周期钩子:beforeMountmounted

更新阶段(Updating):

  • 组件的响应式数据发生变化,导致 DOM 更新。
  • 对应的生命周期钩子:beforeUpdateupdated

销毁阶段(Unmounting):

  • 组件被移除并销毁。
  • 对应的生命周期钩子:beforeUnmountunmounted

错误处理阶段(Error Handling):

  • 组件内部发生错误时触发。
  • 对应的生命周期钩子:errorCapturedrenderTrackedrenderTriggered

选项式 API 中的生命周期钩子

在选项式 API 中,生命周期钩子直接作为组件选项定义。Vue 3 的生命周期钩子名称与 Vue 2 基本一致,只是在 Composition API 中有对应的替代方式。

<template>
  <div>
    <p>{{ count }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 0
    };
  },
  methods: {
    increment() {
      this.count++;
    }
  },
  beforeCreate() {
    console.log("beforeCreate: 组件实例创建之前");
  },
  created() {
    console.log("created: 组件实例创建完成");
  },
  beforeMount() {
    console.log("beforeMount: 组件挂载之前");
  },
  mounted() {
    console.log("mounted: 组件挂载完成");
  },
  beforeUpdate() {
    console.log("beforeUpdate: 数据更新之前");
  },
  updated() {
    console.log("updated: 数据更新完成");
  },
  beforeUnmount() {
    console.log("beforeUnmount: 组件销毁之前");
  },
  unmounted() {
    console.log("unmounted: 组件销毁完成");
  }
};
</script>

Composition API 中的生命周期钩子

在 Composition API 中,生命周期钩子通过setup()函数中的函数导入和调用。Vue 3 提供了一系列以on开头的生命周期函数,用于替代选项式 API 中的生命周期钩子。

生命周期函数

  • onBeforeMount
  • onMounted
  • onBeforeUpdate
  • onUpdated
  • onBeforeUnmount
  • onUnmounted
  • onErrorCaptured
  • onRenderTracked
  • onRenderTriggered

示例

<template>
  <div>
    <p>{{ count }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script>
import { ref, onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted } from 'vue';

export default {
  setup() {
    const count = ref(0);

    function increment() {
      count.value++;
    }

    onBeforeMount(() => {
      console.log("onBeforeMount: 组件挂载之前");
    });

    onMounted(() => {
      console.log("onMounted: 组件挂载完成");
    });

    onBeforeUpdate(() => {
      console.log("onBeforeUpdate: 数据更新之前");
    });

    onUpdated(() => {
      console.log("onUpdated: 数据更新完成");
    });

    onBeforeUnmount(() => {
      console.log("onBeforeUnmount: 组件销毁之前");
    });

    onUnmounted(() => {
      console.log("onUnmounted: 组件销毁完成");
    });

    return {
      count,
      increment
    };
  }
};
</script>

生命周期钩子的使用场景

beforeCreate / onBeforeCreate:

  • 在组件实例化之前调用,此时datamethods尚未初始化。
  • 通常用于初始化一些非响应式数据。

created / onCreated:

  • 在组件实例化完成后调用,此时datamethods已初始化,但 DOM 尚未生成。
  • 适合进行异步数据请求或初始化逻辑。

beforeMount / onBeforeMount:

  • 在组件挂载到 DOM 之前调用,此时可以访问el属性,但 DOM 尚未更新。
  • 适合在挂载前对 DOM 进行操作。

mounted / onMounted:

  • 在组件挂载到 DOM 后调用,此时可以访问完整的 DOM。
  • 适合进行 DOM 操作或绑定事件监听器。

beforeUpdate / onBeforeUpdate:

  • 在组件数据更新之前调用,此时可以访问旧的 DOM。
  • 适合在更新前进行一些校验或清理操作。

updated / onUpdated:

  • 在组件数据更新完成后调用,此时 DOM 已更新。
  • 适合在更新后进行 DOM 操作或重新计算布局。

beforeUnmount / onBeforeUnmount:

  • 在组件销毁之前调用,此时可以访问完整的组件实例。
  • 适合进行清理操作,如移除事件监听器或取消定时器。

unmounted / onUnmounted:

  • 在组件销毁后调用,此时组件实例已被销毁。
  • 适合进行最终的清理操作。 errorCaptured / onErrorCaptured:
  • 在组件内部发生错误时调用,可以捕获错误并进行处理。

renderTracked / onRenderTracked 和 renderTriggered / onRenderTriggered:

  • 用于调试和性能分析,分别在渲染器追踪和触发渲染时调用。

总结

Vue 3 的生命周期钩子是组件开发中非常重要的工具,用于在组件的不同阶段插入自定义逻辑。选项式 API 中的生命周期钩子与 Vue 2 保持一致,而 Composition API 提供了更灵活的生命周期函数,通过 on 开头的函数导入和调用。无论使用哪种 API,生命周期钩子的使用场景和目的都是一致的。理解生命周期钩子的执行顺序和适用场景,可以帮助你更好地管理组件的生命周期逻辑,从而开发出高效、可维护的 Vue 应用。

路由VueRouter的认识和使用

在 Vue 3 中,路由是构建单页应用程序(SPA)的核心概念之一,允许开发者根据 URL 的变化动态地渲染不同的组件。Vue Router 是 Vue.js 的官方路由管理工具,提供了强大的功能来管理路由和视图的切换。

Vue Router 的基本概念

路由的作用

路由是一种将 URL 映射到组件的机制。在传统的多页应用(MPA)中,每次页面跳转都会重新加载整个页面。而在单页应用(SPA)中,页面不会刷新,而是通过路由系统动态加载对应的组件,从而实现高效的页面切换。

核心概念

  • 路由器(Router):

    • 路由系统的管理者,负责监听 URL 的变化,并根据路由规则匹配对应的组件。
    • 提供导航方法(如router.push()router.replace())来控制页面跳转。
  • 路由(Route):

    • 路由是路径( path )与组件( component )的对应关系。
    • 一个典型的路由定义包括:
      • path:URL 中的路径部分。
      • component:路径匹配时要渲染的组件。
  • <RouterView> :

    • 用于渲染当前匹配的组件。
    • 在模板中使用<router-view>标签,Vue Router 会根据当前的 URL 渲染对应的组件。

Vue Router 的安装与配置

安装 Vue Router

在 Vue 3 项目中,可以通过 npm 安装 Vue Router:

npm install vue-router@4

配置路由 在项目中创建一个router文件夹,并创建index.js文件来配置路由。

// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../components/Home.vue';
import About from '../components/About.vue';

const routes = [
  {
    path: '/',
    component: Home
  },
  {
    path: '/about',
    component: About
  }
];

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

export default router;

在主文件中引入路由

main.js中引入并使用路由:

import { createApp } from 'vue';
import App from './App.vue';
import router from './router';

createApp(App)
  .use(router)
  .mount('#app');

在组件中使用<router-view>

在根组件中使用<router-view>来渲染当前匹配的组件:

<template>
  <div>
    <h1>App 根组件</h1>
    <router-view></router-view>
  </div>
</template>

Vue Router 的高级用法

动态路由匹配

通过在路径中添加动态参数,可以匹配不同的路径:

const routes = [
  {
    path: '/user/:id',
    component: User
  }
];

在组件中可以通过useRoute获取参数:

<script setup>
import { useRoute } from 'vue-router';

const route = useRoute();
const userId = route.params.id;
</script>

嵌套路由

在路由配置中定义子路由:

const routes = [
  {
    path: '/user/:id',
    component: User,
    children: [
      {
        path: 'profile',
        component: UserProfile
      },
      {
        path: 'posts',
        component: UserPosts
      }
    ]
  }
];

在父组件模板中使用<router-view>渲染子路由:

<template>
  <div>
    <h2>用户页面</h2>
    <router-view></router-view>
  </div>
</template>

编程式导航

通过useRouter提供的 API 进行编程式导航:

<script setup>
import { useRouter } from 'vue-router';

const router = useRouter();

function goToHome() {
  router.push('/');
}

function replaceToAbout() {
  router.replace('/about');
}
</script>

路由守卫

路由守卫用于控制导航行为,例如权限校验或数据预加载。

  • 全局前置守卫:
router.beforeEach((to, from, next) => {
  if (to.path === '/protected' && !isLoggedIn()) {
    next('/login');
  } else {
    next();
  }
});

  • 路由独享守卫:
const routes = [
  {
    path: '/admin',
    component: Admin,
    beforeEnter: (to, from, next) => {
      if (isAdmin()) {
        next();
      } else {
        next('/login');
      }
    }
  }
];

  • 组件内守卫:
<script setup>
import { beforeRouteEnter, beforeRouteUpdate, beforeRouteLeave } from 'vue-router';

beforeRouteEnter((to, from, next) => {
  next();
});

beforeRouteUpdate((to, from, next) => {
  next();
});

beforeRouteLeave((to, from, next) => {
  next();
});
</script>

懒加载

通过动态导入实现路由组件的懒加载:

const routes = [
  {
    path: '/about',
    component: () => import('./components/About.vue')
  }
];

命名路由和命名视图

  • 命名路由:
const routes = [
  {
    path: '/user/:id',
    name: 'user',
    component: User
  }
];

在组件中导航到命名路由:

<script setup>
import { useRouter } from 'vue-router';

const router = useRouter();

function goToUser(id) {
  router.push({ name: 'user', params: { id } });
}
</script>

  • 命名视图:
const routes = [
  {
    path: '/views',
    components: {
      default: ViewMain,
      sidebar: ViewSidebar
    }
  }
];

在模板中使用命名视图:

<template>
  <router-view></router-view>
  <router-view name="sidebar"></router-view>
</template>

总结

Vue Router 是 Vue.js 的官方路由管理工具,用于构建单页应用(SPA)。它提供了以下功能:

  • 声明式路由配置,将 URL 映射到组件。
  • 支持嵌套路由、动态路由匹配、懒加载等高级功能。
  • 提供编程式导航和路由守卫,用于控制导航行为。
  • 与 Vue.js 的组件系统无缝集成,提供高效的视图渲染。

通过合理配置和使用 Vue Router,可以构建复杂且高效的单页应用,为用户提供流畅的交互体验。