【Vue.js】官方路由 - VueRouter

什么是 VueRouter ?

Vue Router 是 Vue.js 的官方路由 (SPA / MPA(SSR))。 Vue Router 与 Vue.js 核心深度集成,让用 Vue.js 构建单页应用变得轻而易举。 Vue Router 的功能包括:

  • 嵌套路由映射
  • 动态路由选择
  • 模块化、基于组件的路由配置
  • 路由参数、查询、通配符
  • 展示由 Vue.js 的过渡系统提供的过渡效果
  • 细致的导航控制
  • 自动激活 CSS 类的链接
  • HTML5 history 模式或 hash 模式
  • 可定制的滚动行为
  • URL 的正确编码

使用:

CDN 链接引入:

Unpkg 提供了基于 npm 的 CDN 链接,在 html 中引入以下代码即可:

perl 复制代码
# vue
https://unpkg.com/vue@3

# vue-router
https://unpkg.com/vue-router@4
html 复制代码
<script type="text/javascript" src="https://unpkg.com/vue-router@4" defer></script>

依赖安装:

shell 复制代码
# 使用 npm 安装
npm install -S vue-router@4

# 使用 yarn 安装
yarn add vue-router@4

# 使用 pnpm 安装
pnpm install -S vue-router@4

基本使用:

CDN 链接直接使用:

使用步骤:

  1. 引入 vuevue-router的 CDN 链接
  2. 使用 <router-view>组件渲染对应的路由视图
  3. 使用 <router-link>作为可以点击的跳转页面标签(类似于 HTML 里面的 <a>标签)

代码示例:

html 复制代码
<script src="https://unpkg.com/vue@3"></script>
<script src="https://unpkg.com/vue-router@4"></script>

<div id="app">
  <h1>Hello App!</h1>
  <p>
    <!--使用 router-link 组件进行导航 -->
    <!--通过传递 `to` 来指定链接 -->
    <!--`<router-link>` 将呈现一个带有正确 `href` 属性的 `<a>` 标签-->
    <router-link to="/">Go to Home</router-link>
    <router-link to="/about">Go to About</router-link>
  </p>
  <!-- 路由出口 -->
  <!-- 路由匹配到的组件将渲染在这里 -->
  <router-view></router-view>
</div>

<script>
  const { createApp } = Vue;

  const Home = { template: '<div>Home</div>' };
  const About = { template: '<div>About</div>' };

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

  const router = VueRouter.createRouter({
    history: VueRouter.createWebHashHistory(), // 先使用 createWebHashHistory 创建 hash 路由
    routes,
  });

  createApp({}).use(router).mount('#app');
</script>

NPM 安装依赖后使用:

使用步骤:

  1. 声明两个页面: views/Home.vueviews/About.vue
  2. 根据已有的组件需要创建路由对象 router
  3. 在 app 实例中使用 router
  4. App.vue中使用路由

目录结构:

html 复制代码
router-demo
|- ...
|- src
  	|- App.vue
  	|- main.js
  	|- pages
    	|- Home.vue
    	|- About.vue
    |- router
      |- index.js

代码示例:

html 复制代码
<template>
  <h1>Home</h1>
</template>

<script setup></script>
html 复制代码
<template>
  <h1>About</h1>
</template>

<script setup></script>
javascript 复制代码
import { createRouter } from 'vue-router';

import Home from '../pages/Home.vue';

const routes = [
  {
    path: '/',
    component: Home
  },
  {
    path: '/about',
    component: () => import(/* webpackChunkName: Aboout */ '../pages/About.vue');
  }
];

const router = createRouter({
  history: VueRouter.createWebHashHistory(),
  routes,
});

export default router;
javascript 复制代码
import { createApp } from 'vue';
import App from './App.vue';

import router from './router';

const app = createApp(App);

app.use(router);

app.mount('#app');
html 复制代码
<template>
  <<h1>Hello App!</h1>
  <p class="switcher">
    <router-link to="/">Go to Home</router-link>
    <router-link to="/about">Go to About</router-link>
  </p>
  <router-view></router-view>
</template>

<script setup></script>

说明

  1. <router-view>vue-router 提供的一个内置组件,它的职能是把当前对应的路由视图渲染到设置的区域位置上
  2. <router-view> 中的页面如果需要被缓存,请配合 <keep-alive> 组件一起使用
  3. <router-link>是一个跳转页面的标签,提供设置 to="xxx"跳转到 xxx 页面。使用 <router-link> 组件不会引起页面的全局刷新造成闪屏 (基于 history API 进行封装)
  4. Vue@3 需要配合 VueRouter@4 使用,因为 Vue3 的插件几乎都是以 provide + inject 的方式进行注入使用的 (如果是 Vue@2 就需要配合 VueRouter@3 使用)

路由的参数传递:

路由的参数传递有两种方式:

  1. 通过路径参数传递
  2. 通过 query 传递

通过路径字符串中的动态参数传递

步骤:

  1. 定义路由,在路径中使用:动态参数名表明需要使用的动态参数
  2. 在动态组件中通过 params 获取

代码示例:

javascript 复制代码
import User from '../views/User.vue';

// 这些都会传递给 `createRouter`
const routes = [
  // 动态字段以冒号开始
  { path: '/users/:id', component: User },
  // 在路径 /users/tom、/users/jerry 都能匹配到,参数就是后面被替换的字符串
];
html 复制代码
<template>
  <div>
    ID: {{ id }}
  </div>
</template>

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

  const route = useRoute();

  const id = computed(() => {
    const { id } = route.params;
    return id;
  });
  
</script>
匹配模式 匹配路径 route.params
/users/:username /users/eduardo { username: 'eduardo' }
/users/:username/posts/:postId /users/eduardo/posts/123 { username: 'eduardo', postId: '123' }

通过 query 传递

步骤:

  1. 定义路由
  2. 跳转时设置 query
  3. 从 route 中获取当前的 query

代码示例:

  1. 定义路由:
javascript 复制代码
import Detail from '../views/Detail.vue';

const routes = [
  // ...

  {
    path: '/detail',
    name: 'Detail',
    component: Detail
  }
];
  1. 跳转时设置 query:
    1. 使用标签式跳转
html 复制代码
<router-link to="/detail?id=1&name=zhangsan">去张三详情页</router-link>
  1. 使用函数式跳转
javascript 复制代码
import { useRouter } from 'vue-router';

const router = useRouter();

const handleBtnClick = () => {
  router.push('/detail', {
    query: {
      id: 1,
      name: 'zhangsan'
    }
  });
}
  1. 从 route 中获取当前的 query:
javascript 复制代码
import { computed, onMounted } from 'vue';
import { useRoute } from 'vue-router';

const route = useRoute();

const query = computed(() => route.query);

onMounted(() => {
  console.log(query);
});

匹配 404 路由:

常规参数只匹配 url 片段之间的字符,用 / 分隔。 如果我们想匹配任意路径,我们可以使用自定义的 路径参数 正则表达式,在 路径参数 后面的括号中加入 正则表达式 :

javascript 复制代码
const routes = [
  // 将匹配所有内容并将其放在 `route.params.pathMatch` 下
  { path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound },
  // 将匹配以 `/user-` 开头的所有内容,并将其放在 `route.params.afterUser` 下
  { path: '/user-:afterUser(.*)', component: UserGeneric },
  // 通配路由,找不到就返回 404 页面
  { path: '/(.*)' }
]

嵌套路由:

描述:

一些应用程序的 UI 由多层嵌套的组件组成。在这种情况下,URL 的片段通常对应于特定的嵌套组件结构,例如:

javascript 复制代码
/user/johnny/profile                     /user/johnny/posts
+------------------+                  +-----------------+
| User             |                  | User            |
| +--------------+ |                  | +-------------+ |
| | Profile      | |  +------------>  | | Posts       | |
| |              | |                  | |             | |
| +--------------+ |                  | +-------------+ |
+------------------+                  +-----------------+

在上述例子中:

  • Vue Router 里面有一个一级路由需要渲染:User
  • User里面有两个二级路由:ProfilePosts

对于这种需要嵌套显示的路由视图,我们需要怎么渲染呢?

步骤:

  1. 定义 User 中需要渲染的子路由数组 userRoutes
  2. childRoutes 放到 User 的children 里面
  3. router 安装到 app 中
  4. User页面对应位置渲染路由

代码实现:

markdown 复制代码
|- router
  |- index.js
  |- routes
    |- userRoutes.js
|- views
	|- User
  	|- index.vue
  	|- pages
    	|- Profile.vue
    	|- Posts.vue
  	
  1. 定义 User 中需要渲染的子路由数组 userRoutes
javascript 复制代码
const userRoutes = [
  {
    path: 'profile',
    name: 'Profile',
    component: () => import('@/views/User/pages/Profile.vue')
  },
  {
    path: 'posts',
    name: 'Posts',
    component: () => import('@/views/User/pages/Posts.vue')
  }
];

export default userRoutes;
  1. childRoutes 放到 User 的children 里面:
javascript 复制代码
const { createRouter, createWebHashHistory } = VueRouter;

import userRoutes from './userRoutes';

const routes = [
  {
    path: '/user',
    // name: 'User', // 如果有子路由,就不需要定义父级路由的 name
    component: () => import('@/views/User/index.vue'),
    children: [
      ...userRoutes
    ]
  }
];

const router = createRouter({
  routes,
  mode: createWebHashHistory()
});

export default router;
  1. router 安装到 app 中:
javascript 复制代码
import App from './App.vue';
import router from './router';

const { createApp } = Vue;

const app = createApp(App);

app.use(router);

app.mount('#app');
  1. User页面对应位置渲染路由:
html 复制代码
<template>
  <!-- User.vue -->
  <!-- ... -->

  <router-view />
</template>

编程式导航:

概述:

在 Vue 的实例中,可以使用 useRouter获取到路由的实例 router ,然后调用 router上面的方法 push 或者 replace 进行跳转

对比:

声明式 编程式
<router-link :to="..."> router.push(...)
router.replace(...)
router.back(...)
router.go(...)

代码示例:

javascript 复制代码
const { useRouter } = VueRouter;

const router = useRouter();

const handleSwitch = () => {
  // 直接往历史栈中推入一个记录,具体参考:https://router.vuejs.org/zh/guide/essentials/navigation.html#%E5%AF%BC%E8%88%AA%E5%88%B0%E4%B8%8D%E5%90%8C%E7%9A%84%E4%BD%8D%E7%BD%AE
  router.push('/...', {});

  // 替换当前的历史记录,具体参考:https://router.vuejs.org/zh/guide/essentials/navigation.html#%E6%9B%BF%E6%8D%A2%E5%BD%93%E5%89%8D%E4%BD%8D%E7%BD%AE
  router.replace('/...', {});

  // 返回上一条历史记录
  router.back();

  // 横跨历史,具体参考:https://router.vuejs.org/zh/guide/essentials/navigation.html#%E6%A8%AA%E8%B7%A8%E5%8E%86%E5%8F%B2
  router.go(-1);
}

重定向和别名

重定向 redirect

重定向也是通过 routes 配置来完成,下面例子是从 /home 重定向到 /

javascript 复制代码
const routes = [{ path: '/home', redirect: '/' }]

重定向的目标也可以是一个命名的路由:

javascript 复制代码
const routes = [{ path: '/home', redirect: { name: 'homepage' } }]

甚至是一个方法,动态返回重定向目标:

javascript 复制代码
const routes = [
  {
    // /search/screens -> /search?q=screens
    path: '/search/:searchText',
    redirect: to => {
      // 方法接收目标路由作为参数
      // return 重定向的字符串路径/路径对象
      return { path: '/search', query: { q: to.params.searchText } }
    },
  },
  {
    path: '/search',
    // ...
  },
]

注意:

  • 导航守卫对于重定向配置的路由对象不生效
  • 在写 redirect 的时候,可以省略 component 配置,因为它从来没有被直接访问过

别名 alias

重定向是指当用户访问 /home 时,URL 会被 / 替换,然后匹配成 /。那么什么是别名呢? 将 / 别名为 /home,意味着当用户访问 /home 时,URL 仍然是 /home,但会被匹配为用户正在访问 /。 上面对应的路由配置为:

javascript 复制代码
const routes = [{ path: '/', component: Homepage, alias: '/home' }]

通过别名,开发者可以:

  1. 自由地将 UI 结构映射到一个任意的 URL,而不受配置的嵌套结构的限制使别名以 / 开头
  2. 以使嵌套路径中的路径成为绝对路径。

多个别名:

javascript 复制代码
const routes = [
  {
    path: '/users',
    component: UsersLayout,
    children: [
      // 为这 3 个 URL 呈现 UserList
      // - /users
      // - /users/list
      // - /people
      { path: '', component: UserList, alias: ['/people', 'list'] },
    ],
  },
]

如果你的路由有参数,请确保在任何绝对别名中包含它们:

javascript 复制代码
const routes = [
  {
    path: '/users/:id',
    component: UsersByIdLayout,
    children: [
      // 为这 3 个 URL 呈现 UserDetails
      // - /users/24
      // - /users/24/profile
      // - /24
      { path: 'profile', component: UserDetails, alias: ['/:id', ''] },
    ],
  },
]

路由守卫:

Vue Router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。

全局前置守卫:

概述:

当一个导航触发时,全局前置守卫按照创建顺序调用。守 卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于等待中。 每个守卫方法接收两个参数:

可以返回的值如下:

  • false: 取消当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
javascript 复制代码
const router = createRouter({ ... });

router.beforeEach((to, from) => {
  // ...
  // 返回 false 以取消导航
  return false;
});
  • 一个路由地址: 通过一个路由地址跳转到一个不同的地址,就像你调用 router.push() 一样,你可以设置诸如 replace: truename: 'home' 之类的配置。当前的导航被中断,然后进行一个新的导航,就和 from 一样。
javascript 复制代码
router.beforeEach(async (to, from) => {
   if (
     // 检查用户是否已登录
     !isAuthenticated &&
     // ❗️ 避免无限重定向
     to.name !== 'Login'
   ) {
     // 将用户重定向到登录页面
     return { name: 'Login' };
   }
 });
javascript 复制代码
router.beforeEach(async (to, from) => {
  // canUserAccess() 返回 `true` 或 `false`
  const canAccess = await canUserAccess(to)
  if (!canAccess) return '/login';
});

第三个参数 - next()

在之前的 Vue Router 版本中,也是可以使用第三个参数 next 方法。 但是 next 方法是一个常见的错误来源,可以通过 RFC 来消除错误。 next 方法 仍然是被支持的,这意味着你可以向任何导航守卫传递第三个参数。 在使用 next方法时, 确保 next 在任何给定的导航守卫中都被严格调用一次。它可以出现多于一次,但是只能在所有的逻辑路径都不重叠的情况下。

全局后置守卫:

你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:

javascript 复制代码
router.afterEach((to, from) => {
  sendToAnalytics(to.fullPath);
});

它们对于分析、更改页面标题、声明页面等辅助功能以及许多其他事情都很有用。 它们也反映了 navigation failures 作为第三个参数:

javascript 复制代码
router.afterEach((to, from, failure) => {
  if (!failure) sendToAnalytics(to.fullPath);
});

单个守卫:

路由独享:

你可以直接在路由配置上定义 beforeEnter 守卫:

javascript 复制代码
const routes = [
  {
    path: '/users/:id',
    component: UserDetails,
    beforeEnter: (to, from) => {
      // reject the navigation
      return false
    },
  },
];

beforeEnter 守卫 只在进入路由时触发,不会在 paramsqueryhash 改变时触发。例如,从 /users/2 进入到 /users/3 或者从 /users/2#info 进入到 /users/2#projects。它们只有在 从一个不同的 路由导航时,才会被触发。 你也可以将一个函数数组传递给 beforeEnter,这在为不同的路由重用守卫时很有用:

javascript 复制代码
function removeQueryParams(to) {
  if (Object.keys(to.query).length)
    return { path: to.path, query: {}, hash: to.hash }
}

function removeHash(to) {
  if (to.hash) return { path: to.path, query: to.query, hash: '' }
}

const routes = [
  {
    path: '/users/:id',
    component: UserDetails,
    beforeEnter: [removeQueryParams, removeHash],
  },
  {
    path: '/about',
    component: UserDetails,
    beforeEnter: [removeQueryParams],
  },
]

请注意,你也可以通过使用路径 meta 字段全局导航守卫来实现类似的行为。

组件独享:

你可以为路由组件添加以下配置:

  • onBeforeRouteUpdate
  • onBeforeRouteLeave
javascript 复制代码
const { onBeforeRouteUpdate, onBeforeRouteLeave } = VueRouter;

onBeforeRouteUpdate(() => {});

onBeforeRouteLeave(() => {});

路由元信息:

概述:

有时,你可能希望将任意信息附加到路由上,(如过渡名称、谁可以访问路由等。)这些事情可以通过接收属性对象的meta属性来实现,并且它可以在路由地址和导航守卫上都被访问到。定义路由的时候你可以这样配置 meta 字段:

javascript 复制代码
const routes = [
  {
    path: '/posts',
    component: PostsLayout,
    children: [
      {
        path: 'new',
        component: PostsNew,
        // 只有经过身份验证的用户才能创建帖子
        meta: { requiresAuth: true }
      },
      {
        path: ':id',
        component: PostsDetail
          // 任何人都可以阅读文章
          meta: { requiresAuth: false }
      }
    ]
  }
];

配合路由守卫使用:

一个路由匹配到的所有路由记录会暴露为 route 对象(还有在导航守卫中的路由对象)的 route.matched 数组。我们需要遍历这个数组来检查路由记录中的 meta 字段。 但是 Vue Router 还为你提供了一个 route.meta 方法,它是一个非递归合并所有 meta 字段的(从父字段到子字段)的方法:

javascript 复制代码
router.beforeEach((to, from) => {
  // 而不是去检查每条路由记录
  // to.matched.some(record => record.meta.requiresAuth)
  if (to.meta.requiresAuth && !auth.isLoggedIn()) {
    // 此路由需要授权,请检查是否已登录
    // 如果没有,则重定向到登录页面
    return {
      path: '/login',
      // 保存我们所在的位置,以便以后再来
      query: { redirect: to.fullPath },
    }
  }
})

路由懒加载

概述:

当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。 如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就会更加高效。

使用:

Vue Router 支持开箱即用的动态导入,这意味着你可以用动态导入代替静态导入:

javascript 复制代码
// 将
// import UserDetails from './views/UserDetails.vue'
// 替换成
const UserDetails = () => import('./views/UserDetails.vue')

const router = createRouter({
  // ...
  routes: [{ path: '/users/:id', component: UserDetails }],
})

component (和 components) 配置接收一个返回 Promise 组件的函数,Vue Router 只会在第一次进入页面时才会获取这个函数,然后使用缓存数据。这意味着你也可以使用更复杂的函数,只要它们返回一个 Promise

javascript 复制代码
const UserDetails = () =>
  Promise.resolve({
    /* 组件定义 */
  })

一般来说,对所有的路由都使用动态导入是个好主意。

注意

  • 不要在路由中使用异步组件。异步组件仍然可以在路由组件中使用,但路由组件本身就是动态导入的。
  • 如果你使用的是 webpack 之类的打包器,它将自动从代码分割中受益。
  • 如果你使用的是 Babel,你将需要添加 syntax-dynamic-import 插件,才能使 Babel 正确地解析语法。

把组件按组分块:

使用 webpack

有时候我们想把某个路由下的所有组件都打包在同个异步块 (chunk) 中。只需要使用命名 chunk,一个特殊的注释语法来提供 chunk name (需要 Webpack > 2.4):

javascript 复制代码
const UserDetails = () =>
  import(/* webpackChunkName: "group-user" */ './UserDetails.vue');
const UserDashboard = () =>
  import(/* webpackChunkName: "group-user" */ './UserDashboard.vue');
const UserProfileEdit = () =>
  import(/* webpackChunkName: "group-user" */ './UserProfileEdit.vue');

webpack 会将任何一个异步模块与相同的块名称组合到相同的异步块中。

使用 Vite

在Vite中,你可以在 rollupOptions 下定义分块:

javascript 复制代码
// vite.config.js
export default defineConfig({
  build: {
    rollupOptions: {
      // https://rollupjs.org/guide/en/#outputmanualchunks
      output: {
        manualChunks: {
          'group-user': [
            './src/UserDetails',
            './src/UserDashboard',
            './src/UserProfileEdit',
          ],
        },
      },
    },
  },
});

动态路由:

概述:

对路由的添加通常是通过 routes选项来完成的,但是在某些情况下,你可能想在应用程序已经运行的时候添加或删除路由。具有可扩展接口(如 Vue CLI UI )这样的应用程序可以使用它来扩展应用程序。

使用:

动态路由主要通过两个函数实现。router.addRoute()router.removeRoute()。它们只注册一个新的路由,也就是说,如果新增加的路由与当前位置相匹配,就需要你用 router.push() 或 router.replace() 来手动导航,才能显示该新路由。

替换路由:

看一下官网上面的例子: 想象一下,只有一个路由的以下路由:

javascript 复制代码
const router = createRouter({
  history: createWebHistory(),
  routes: [{ path: '/:articleName', component: Article }],
})

进入任何页面,/about/store,或者 /xxx 最终都会呈现 <Article> 组件。 如果我们在 /about上添加一个新的路由:

javascript 复制代码
router.addRoute({ path: '/about', component: About });

页面仍然会显示 Article 组件,我们需要**手动调用 router.replace() **来覆盖原来的位置(而不是添加一个新的路由,最后在我们的历史中两次出现在同一个位置):

javascript 复制代码
router.addRoute({ path: '/about', component: About });
// 我们也可以使用 this.$route 或 route = useRoute() (在 setup 中)
router.replace(router.currentRoute.value.fullPath);

如果你需要等待新的路由显示,可以使用 await router.replace()

在导航守卫中添加路由:

如果你决定在导航守卫内部添加或删除路由,你不应该调用 router.replace(),而是通过返回新的位置来触发重定向:

javascript 复制代码
router.beforeEach(to => {
  if (!hasNecessaryRoute(to)) {
    router.addRoute(generateRoute(to));
    // 触发重定向
    return to.fullPath;
  }
});

上面的例子有两个假设:第一,新添加的路由记录将与 to 位置相匹配,实际上导致与我们试图访问的位置不同。第二,hasNecessaryRoute() 在添加新的路由后返回 false,以避免无限重定向。 因为是在重定向中,所以我们是在替换将要跳转的导航,实际上行为就像之前的例子一样。而在实际场景中,添加路由的行为更有可能发生在导航守卫之外,例如,当一个视图组件挂载时,它会注册新的路由。

添加嵌套路由

  • 方式一:
javascript 复制代码
router.addRoute({
  name: 'admin',
  path: '/admin',
  component: Admin,
  children: [{ path: 'settings', component: AdminSettings }],
});
  • 方式二:
javascript 复制代码
router.addRoute({ name: 'admin', path: '/admin', component: Admin });
router.addRoute('admin', { path: 'settings', component: AdminSettings });

删除路由

有几个不同的方法来删除现有的路由:

  • 通过添加一个名称冲突的路由。如果添加与现有途径名称相同的途径,会先删除路由,再添加路由:js
javascript 复制代码
router.addRoute({ path: '/about', name: 'about', component: About });
// 这将会删除之前已经添加的路由,因为他们具有相同的名字且名字必须是唯一的
router.addRoute({ path: '/other', name: 'about', component: Other });
  • 通过调用 router.addRoute() 返回的回调:
javascript 复制代码
const removeRoute = router.addRoute(routeRecord);
removeRoute(); // 删除路由如果存在的话

当路由没有名称时,这很有用。

  • 通过使用 router.removeRoute() 按名称删除路由:
javascript 复制代码
router.addRoute({ path: '/about', name: 'about', component: About });
// 删除路由
router.removeRoute('about');

需要注意的是,如果你想使用这个功能,但又想避免名字的冲突,可以在路由中使用 Symbol 作为名字。 当路由被删除时,所有的别名和子路由也会被同时删除

命名:

路由命名:

参考链接

<router-view>命名:

参考链接

相关推荐
LIUENG36 分钟前
Vue3 响应式原理
前端·vue.js
wycode1 小时前
Vue2实践(3)之用component做一个动态表单(二)
前端·javascript·vue.js
wycode2 小时前
Vue2实践(2)之用component做一个动态表单(一)
前端·javascript·vue.js
第七种黄昏2 小时前
Vue3 中的 ref、模板引用和 defineExpose 详解
前端·javascript·vue.js
pepedd8644 小时前
还在开发vue2老项目吗?本文带你梳理vue版本区别
前端·vue.js·trae
前端缘梦4 小时前
深入理解 Vue 中的虚拟 DOM:原理与实战价值
前端·vue.js·面试
HWL56794 小时前
pnpm(Performant npm)的安装
前端·vue.js·npm·node.js
柯南95275 小时前
Vue 3 reactive.ts 源码理解
vue.js
柯南95275 小时前
Vue 3 Ref 源码解析
vue.js
小高0075 小时前
面试官:npm run build 到底干了什么?从 package.json 到 dist 的 7 步拆解
前端·javascript·vue.js