设为首页收藏本站

安徽论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 11606|回复: 0

vue3+TypeScript+vue-router的使用方法

[复制链接]

85

主题

0

回帖

267

积分

中级会员

Rank: 3Rank: 3

积分
267
发表于 2022-3-26 11:00:53 | 显示全部楼层 |阅读模式
网站内容均来自网络,本站只提供信息平台,如有侵权请联系删除,谢谢!
目录


简单使用


创建项目


vue-cli创建
  1. $npm install -g @vue/cli
  2. $vue --version
  3. @vue/cli 4.5.15
  4. $vue create my-project
复制代码
然后的步骤:

  • Please pick a preset
    选择 Manually select features
  • Check the features needed for your project
    选择上
    1. TypeScript
    复制代码
    ,特别注意点空格是选择,点回车是下一步
  • Choose a version of Vue.js that you want to start the project with
    选择 3.x (Preview)
  • Use class-style component syntax
    直接回车
  • Use Babel alongside TypeScript
    直接回车
  • Pick a linter / formatter config
    直接回车
  • Use history mode for router?
    直接回车
  • Pick a linter / formatter config
    直接回车
  • Pick additional lint features
    直接回车
  • Where do you prefer placing config for Babel, ESLint, etc.?
    直接回车
  • Save this as a preset for future projects?
    直接回车
文件结构:
  1. my-project
  2. +--- babel.config.js
  3. +--- package-lock.json
  4. +--- package.json
  5. +--- public
  6. |   +--- favicon.ico
  7. |   +--- index.html
  8. +--- README.md
  9. +--- src
  10. |   +--- App.vue
  11. |   +--- assets
  12. |   |   +--- logo.png
  13. |   +--- components
  14. |   |   +--- HelloWorld.vue
  15. |   +--- main.ts
  16. |   +--- shims-vue.d.ts
  17. +--- tsconfig.json
  18. +--- node_modules
  19. |   +--- ...
复制代码
  1. 入口文件为[code]src/main.ts
复制代码
[/code]
vite创建

执行以下命令创建项目
  1. $npm init vite-app <project-name>
  2. $cd <project-name>
  3. $npm install
  4. $npm run dev
复制代码
文件结构:
  1. project-name
  2. +--- index.html
  3. +--- package-lock.json
  4. +--- package.json
  5. +--- public
  6. |   +--- favicon.ico
  7. +--- src
  8. |   +--- App.vue
  9. |   +--- assets
  10. |   |   +--- logo.png
  11. |   +--- components
  12. |   |   +--- HelloWorld.vue
  13. |   +--- index.css
  14. |   +--- main.js
  15. +--- node_modules
  16. |   +--- ...
复制代码
  1. 入口文件为[code]src/main.ts
复制代码
[/code]注意: 由于使用vite方法创建的项目没有vue的声明文件, 所以需要我们自定义, 否则会报错.
  1. src/shims-vue.d.ts
复制代码
  1. /* eslint-disable */
  2. declare module '*.vue' {
  3.   import type { DefineComponent } from 'vue'
  4.   const component: DefineComponent<{}, {}, any>
  5.   export default component
  6. }
复制代码
安装vue-router
  1. $npm install vue-router@4
复制代码
至此,
  1. package.json
复制代码
如下:
  1. {
  2.   "name": "my-project",
  3.   "version": "0.1.0",
  4.   "private": true,
  5.   "scripts": {
  6.     "serve": "vue-cli-service serve",
  7.     "build": "vue-cli-service build",
  8.     "lint": "vue-cli-service lint"
  9.   },
  10.   "dependencies": {
  11.     "core-js": "^3.6.5",
  12.     "vue": "^3.0.0",
  13.     "vue-router": "^4.0.12"
  14.   },
  15.   "devDependencies": {
  16.     "@typescript-eslint/eslint-plugin": "^4.18.0",
  17.     "@typescript-eslint/parser": "^4.18.0",
  18.     "@vue/cli-plugin-babel": "~4.5.0",
  19.     "@vue/cli-plugin-eslint": "~4.5.0",
  20.     "@vue/cli-plugin-typescript": "~4.5.0",
  21.     "@vue/cli-service": "~4.5.0",
  22.     "@vue/compiler-sfc": "^3.0.0",
  23.     "@vue/eslint-config-typescript": "^7.0.0",
  24.     "eslint": "^6.7.2",
  25.     "eslint-plugin-vue": "^7.0.0",
  26.     "typescript": "~4.1.5"
  27.   }
  28. }
复制代码
创建/修改组件

创建
  1. src/router/index.ts
复制代码
  1. import { createRouter, createWebHashHistory } from "vue-router"

  2. import Home from '../components/Home.vue'
  3. import About from '../components/About.vue'
  4. import User from '../components/User.vue'

  5. const routes = [
  6.         // router参数详细看下文
  7.         {
  8.                 path: "/home",
  9.                 name: "home",
  10.                 component: Home
  11.         },
  12.         {
  13.                 path: "/about",
  14.                 name: "about",
  15.                 component: About
  16.         },
  17.         {
  18.                 path: "/user/:uid",  // 动态参数
  19.                 name: "user",
  20.                 component: User
  21.         }
  22. ]
  23. export const router = createRouter({
  24.         history: createWebHashHistory(),
  25.         routes: routes
  26. })
复制代码
创建组件:
  1. Home.vue
复制代码
  1. About.vue
复制代码
  1. User.vue
复制代码
  1. src/components/Home.vue
复制代码
  1. <template>
  2.   <div>home组件</div>
  3. </template>

  4. <script lang="ts">
  5. import { defineComponent } from "vue";

  6. export default defineComponent({
  7.   name: "Home",
  8.   setup() {
  9.         return {
  10.           // 返回的数据
  11.         };
  12.   },
  13. });
  14. </script>
复制代码
  1. src/components/About.vue
复制代码
  1. <template>
  2.   <div>About组件</div>
  3. </template>

  4. <script lang="ts">
  5. import { defineComponent } from "vue";

  6. export default defineComponent({
  7.   name: "About",
  8.   setup() {
  9.         return {
  10.           // 返回的数据
  11.         };
  12.   },
  13. });
  14. </script>
复制代码
  1. src/components/User.vue
复制代码
  1. <template>
  2.   <div>User组件</div>
  3. </template>

  4. <script lang="ts">
  5. import { defineComponent } from "vue";

  6. export default defineComponent({
  7.   name: "User",
  8.   setup() {
  9.         return {
  10.           // 返回的数据
  11.         };
  12.   },
  13. });
  14. </script>
复制代码
修改
  1. App.vue
复制代码
  1. <template>
  2.   <div>{{ appMessage }}</div>
  3.   <!-- router-link会被渲染成a标签 -->
  4.   <router-link to="/home">home</router-link>
  5.   <router-link to="/about">about</router-link>
  6.   <router-link to="/user/lczmx">user</router-link>

  7.   <!-- 路由出口 -->
  8.   <!-- 路由匹配到的组件将渲染在这里 -->
  9.   <router-view></router-view>
  10. </template>

  11. <script lang="ts">
  12. import { defineComponent } from "vue";

  13. export default defineComponent({
  14.   name: "App",
  15.   setup() {
  16.         const appMessage = "App组件";
  17.         return {
  18.           // 返回的数据
  19.           appMessage,
  20.         };
  21.   },
  22. });
  23. </script>
  24. <style>
  25. /* 添加样式 */
  26. #app {
  27.   text-align: center;
  28.   margin-top: 50px;
  29. }
  30. a {
  31.   margin: 30px;
  32.   display: inline-block;
  33. }
  34. </style>
复制代码
修改入口ts

修改
  1. src/main.ts
复制代码
  1. import { createApp } from 'vue'
  2. import App from './App.vue'
  3. import './index.css'

  4. import { router } from './router'

  5. // 创建应用 返回对应的实例对象
  6. const app = createApp(App)

  7. // 安装 vue-router 插件
  8. app.use(router)
  9. // 调用mount方法
  10. app.mount('#app')
复制代码
启动vue
  1. $npm run serve

  2. > my-project@0.1.0 serve
  3. > vue-cli-service serve

  4. INFO  Starting development server...
  5. 98% after emitting CopyPlugin

  6. DONE  Compiled successfully in 6387ms                                                                                               下午4:14:30

  7.   App running at:
  8.   - Local:   http://localhost:8080/
  9.   - Network: http://192.168.43.12:8080/

  10.   Note that the development build is not optimized.
  11.   To create a production build, run npm run build.

  12. No issues found.
复制代码
在浏览器中访问

根据提示, 访问
  1. http://localhost:8080/
复制代码
, 如下图


文件结构图片



综合使用


动态参数

假如我们需要的路由是:
  1. /user/lczmx
复制代码
  1. /user/jack
复制代码
, 但是我们明显不可能为这两个路由定义两个不同的组件, 最好的方法就是使用动态参数:
  1. const routes = [
  2.   // 动态段以冒号开始
  3.   { path: '/users/:id', component: User },
  4.   // 使用正则表达式  `()` 里面的东西会传给前面的pathMatch
  5.   // 值在route.params.pathMatch下
  6.   { path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound },
  7. ]
复制代码
匹配时, 会将参数映射到
  1. router
复制代码
实例的
  1. currentRoute.value.params
复制代码
  1. 注意vue2中: 由于在[code]setup
复制代码
无法使用
  1. this.$route
复制代码
  1. this.$router
复制代码
至于如何获取, 看我的另一篇博客: vue3获取当前路由 和 官网: Vue Router 和 组合式 API[/code]匹配列表
匹配模式匹配路径当前路由的参数
  1. /users/:username
复制代码
  1. /users/eduardo
复制代码
  1. { username: &#39;eduardo&#39; }
复制代码
  1. /users/:username/posts/:postId
复制代码
  1. /users/eduardo/posts/123
复制代码
  1. { username: &#39;eduardo&#39;, postId: &#39;123&#39; }
复制代码
在使用带有参数的路由时需要注意: 由于相同的组件实例将被重复使用,所以组件的生命周期钩子不会被调用
但是我们可以对路由进行监听

使用watch监听动态参数

修改
  1. src/components/User.vue
复制代码
:
  1. <template>
  2.   <div>User组件</div>
  3.   <p>当前用户: {{ uid }}</p>

  4.   <router-link to="/user/lczmx">lczmx</router-link>
  5.   <router-link to="/user/jack">jack</router-link>
  6. </template>

  7. <script lang="ts">
  8. import { defineComponent, watch, ref } from "vue";
  9. import { useRouter } from "vue-router";

  10. export default defineComponent({
  11.   name: "User",
  12.   setup() {
  13.     const router = useRouter();
  14.     const uid = ref(router.currentRoute.value.params.uid);
  15.     watch(
  16.       // 监听非响应式数据
  17.       () => router.currentRoute.value,
  18.       (val) => {
  19.         // 修改uid
  20.         uid.value = val.params.uid;
  21.       }
  22.     );
  23.     return {
  24.       // 返回的数据
  25.       uid,
  26.     };
  27.   },
  28. });
  29. </script>
复制代码


使用组合API监听动态参数

https://next.router.vuejs.org/zh/guide/advanced/composition-api.html

重定向

下面使用
  1. router
复制代码
的全部参数:
  1. const routes = [
  2.     {
  3.         path: "/",
  4.         // 写法1 写死url
  5.         // redirect: "/home", // 访问 "/" 时 跳转到 "/home"

  6.         // 写法2 跳转到对应的命名路由
  7.         redirect: { name: "home" },

  8.         // 写法3 定义一个方法
  9.                 // 该方法亦可以 返回一个相对路径
  10.         /*
  11.         redirect: to => {
  12.             // 方法接收目标路由作为参数 "to"

  13.             // return 重定向的字符串路径/路径对象
  14.                        
  15.                         // query指定参数
  16.             return { path: '/home', query: { q: to.params.searchText } }
  17.         },
  18.         */
  19.     },
  20.     {
  21.         path: "/home",
  22.         name: "home",
  23.         component: Home
  24.     }
  25. ]
复制代码
  1. 注意, 重定向不会触发 导航守卫
复制代码
  1. 另附官网的例子: <a href="https://codesandbox.io/s/named-views-vue-router-4-examples-rd20l" rel="external nofollow" target="_blank">Named Views - Vue Router 4 examples</a>
复制代码
命名与别名


命名路由
  1. 给路由一个名称, 可以在其他路由中使用, 如: [code]redirect
复制代码
  1. router-link
复制代码
[/code]
  1. const routes = [
  2.   {
  3.     path: '/user/:username',
  4.     name: 'user',
  5.     component: User
  6.   }
  7. ]
复制代码
  1. redirect
复制代码
的使用如上文, 而
  1. router-link
复制代码
如下:
  1. <template>
  2.   <div>User组件</div>
  3.   <p>当前用户: {{ uid }}</p>

  4.   <router-link :to="{ name: 'user', params: { uid: 'lczmx' } }"
  5.     >lczmx</router-link
  6.   >
  7.   <router-link :to="{ name: 'user', params: { uid: 'jack' } }"
  8.     >jack</router-link
  9.   >
  10. </template>
复制代码
  1. router.push
复制代码
(
  1. router
复制代码
  1. router
复制代码
对象)中使用:
  1. router.push({ name: 'user', params: { uid: 'lczmx' } })
复制代码
命名视图
  1. 即, 我们可以[code]router-view
复制代码
定义一个名字, 已达到实现可复用的效果我们可以使用这个功能实现 一个侧边栏等[/code]举个例子
定义路由:
  1. import { createRouter, createWebHashHistory } from "vue-router"

  2. import Home from '../components/Home.vue'
  3. import About from '../components/About.vue'
  4. import User from '../components/User.vue'

  5. const routes = [
  6.         {
  7.                 path: "/",
  8.                 components: {
  9.                         default: Home,  // 默认用Home组件
  10.                         a: About,  // a用About组件
  11.                         b: User,  // b用User组件
  12.                 },

  13.         },
  14.         {
  15.                 path: "/home",
  16.                 components: {
  17.                         default: About,   // 默认用About组件
  18.                         a: Home,  // a用Home组件
  19.                         b: User,  // b用User组件
  20.                 },

  21.         },
  22. ]


  23. export const router = createRouter({
  24.         history: createWebHashHistory(),
  25.         routes: routes
  26. })
复制代码
修改
  1. App.vue
复制代码
  1. <template>
  2.   <div>{{ appMessage }}</div>

  3.   <!-- router-link会被渲染成a标签 -->
  4.   <router-link to="/">/</router-link>
  5.   <router-link to="/home">/home</router-link>

  6.   <!-- 路由出口 -->
  7.   <!-- 路由匹配到的组件将渲染在这里 -->
  8.   <!-- default -->
  9.   <router-view></router-view>
  10.   <router-view name="about"></router-view>
  11.   <router-view name="user"></router-view>
  12. </template>

  13. <script lang="ts">
  14. import { defineComponent } from "vue";

  15. export default defineComponent({
  16.   name: "App",
  17.   setup() {
  18.         const appMessage = "App组件";
  19.         return {
  20.           // 返回的数据
  21.           appMessage,
  22.         };
  23.   },
  24. });
  25. </script>
  26. <style>
  27. /* 添加样式 */
  28. #app {
  29.   text-align: center;
  30.   margin-top: 50px;
  31. }
  32. a {
  33.   margin: 30px;
  34.   display: inline-block;
  35. }
  36. </style>
复制代码
其他组件
  1. About.vue
复制代码
:
  1. <template>
  2.   <div>about组件</div>
  3. </template>
复制代码
  1. Home.vue
复制代码
:
  1. <template>
  2.   <div>home组件</div>
  3. </template>
复制代码
  1. User.vue
复制代码
  1. <template>
  2.   <div>user组件</div>
  3. </template>
复制代码
启动服务并访问vue
如图:
  1. 假如不指定视图名, 那么为[code]default
复制代码
[/code]
别名
  1. 可以实现 不同url 访问同一路由的效果
复制代码
  1. const routes = [
  2.     // 可以访问 "/home" 也可以访问 "/"
  3.     // 且访问的路径不会改变
  4.     {
  5.         path: "/home",
  6.         name: "home",
  7.         component: Home,
  8.         alias: "/"
  9.     }
复制代码
嵌套路由

之前我们在
  1. App.vue
复制代码
中定义
  1. router-view
复制代码
, 让其他组件在哪里渲染
但假如我们需要在其他组件中渲染的话, 就需要嵌套路由了
  1. 使用[code]children
复制代码
嵌套路由, 它的值是路由数据, 就好像外部的
  1. router
复制代码
那样定义[/code]例子:
  1. router.index.ts
复制代码
  1. import { createRouter, createWebHashHistory } from "vue-router"

  2. import Home from '../components/Home.vue'
  3. import About from '../components/About.vue'
  4. import User from '../components/User.vue'
  5. import UserHome from '../components/UserHome.vue'
  6. import UserSettings from '../components/UserSettings.vue'
  7. import UserProfile from '../components/UserProfile.vue'

  8. const routes = [
  9.         // 可以访问 "/home" 也可以访问 "/"
  10.         // 且访问的路径不会改变
  11.         {
  12.                 path: "/home",
  13.                 name: "home",
  14.                 component: Home,
  15.                 alias: "/"
  16.         },
  17.         {
  18.                 path: "/about",
  19.                 name: "about",
  20.                 component: About
  21.         },
  22.         {
  23.                 path: "/user/:uid",  // 动态参数
  24.                 name: "user",
  25.                 component: User,  // 内部有router-view渲染要嵌套的路由
  26.                 children: [
  27.                         // 匹配形如 /user/lczmx 的url
  28.                         { path: "", component: UserHome },

  29.                         // 匹配形如 /user/lczmx/settings 的url
  30.                         { path: "settings", component: UserSettings, name: "user-settings" },

  31.                         // 匹配形如 /user/lczmx/profile 的url
  32.                         { path: "profile", component: UserProfile, name: "user-profile" }
  33.                 ]
  34.         }
  35. ]


  36. export const router = createRouter({
  37.         history: createWebHashHistory(),
  38.         routes: routes
  39. })
复制代码
  1. 注意: 假如[code]children
复制代码
中没有
  1. path: ""
复制代码
的话, 那么访问
  1. /user/lczmx
复制代码
, 只能得到一个页面空白[/code]
  1. User.vue
复制代码
  1. <template>
  2.   <div>
  3.         <router-link :to="{ name: 'user-settings' }">settings</router-link>
  4.         <router-link :to="{ name: 'user-profile' }">profile</router-link>
  5.   </div>

  6.   <router-view></router-view>
  7. </template>
复制代码
  1. UserHome.vue
复制代码
  1. <template>
  2.   <div>用户主页</div>
  3. </template>
复制代码
  1. UserProfile.vue
复制代码
  1. <template>
  2.   <div>用户详细信息页面</div>
  3. </template>
复制代码
  1. UserSettings.vue
复制代码
  1. <template>
  2.   <div>用户设置页面</div>
  3. </template>
复制代码
启动并访问
在浏览器中测试:


编程式路由

即不通过a标签, 而是通过
  1. js/ts
复制代码
改变路由, 原理是向
  1. history
复制代码
栈添加一个新的记录
在vue3中, 有以下写法
  1. <template>
  2.   <div>about组件</div>
  3.   <button @click="changeRouter">修改路由</button>
  4. </template>


  5. <script lang="ts">
  6. import { defineComponent } from "vue";

  7. import { useRouter } from "vue-router";

  8. export default defineComponent({
  9.   name: "About",
  10.   setup() {
  11.     // 获得router对象
  12.     const router = useRouter();

  13.     const changeRouter = () => {
  14.       /* 修改路由的例子 */

  15.       // 1 字符串路径
  16.       router.push("/users/lczmx");

  17.       // 2 带有路径的对象
  18.       router.push({ path: "/users/lczmx" });

  19.       // 3 命名的路由,并加上参数,让路由建立 url
  20.       router.push({ name: "user", params: { username: "lczmx" } });

  21.       // 4 带查询参数,结果是 /register?plan=private
  22.       router.push({ path: "/register", query: { plan: "private" } });

  23.       // 5 带 hash,结果是 /about#team
  24.       router.push({ path: "/about", hash: "#team" });

  25.       // 6 我们可以手动建立 url,但我们必须自己处理编码
  26.       const username = "lczmx";
  27.       router.push(`/user/${username}`); // -> /user/lczmx
  28.       // 同样
  29.       router.push({ path: `/user/${username}` }); // -> /user/lczmx
  30.       // 如果可能的话,使用 `name` 和 `params` 从自动 URL 编码中获益
  31.       router.push({ name: "user", params: { username } }); // -> /user/lczmx

  32.       // 7 `params` 不能与 `path` 一起使用, 否则 `params` 将会被忽略
  33.       router.push({ path: "/user", params: { username } }); // -> /user

  34.       // 8 replace为true 不向history 中添加
  35.       router.push({ path: "/home", replace: true });
  36.       // 等同于
  37.       router.replace({ path: "/home" });

  38.       // 9 横跨历史
  39.       // 向前移动一条记录,与 router.forward() 相同
  40.       router.go(1);
  41.       // 返回一条记录,与router.back() 相同
  42.       router.go(-1);
  43.       // 前进 3 条记录
  44.       router.go(3);
  45.       // 如果没有那么多记录,静默失败
  46.       router.go(-100);
  47.       router.go(100);
  48.     };
  49.     return {
  50.       // 返回的数据
  51.       changeRouter,
  52.     };
  53.   },
  54. });
  55. </script>

  56. <style>
  57. button {
  58.   margin: 30px;
  59. }
  60. </style>
复制代码
  1. 更多见vue-router4官网: <a href="https://next.router.vuejs.org/zh/" rel="external nofollow" target="_blank">Vue Router</a>
复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
                                                        
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
免责声明
1. 本论坛所提供的信息均来自网络,本网站只提供平台服务,所有账号发表的言论与本网站无关。
2. 其他单位或个人在使用、转载或引用本文时,必须事先获得该帖子作者和本人的同意。
3. 本帖部分内容转载自其他媒体,但并不代表本人赞同其观点和对其真实性负责。
4. 如有侵权,请立即联系,本网站将及时删除相关内容。
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表