简单使用

创建项目

vue-cli创建

$npm install -g @vue/cli
$vue --version
@vue/cli 4.5.15
$vue create my-project

然后的步骤:

  1. Please pick a preset

    选择 Manually select features
  2. Check the features needed for your project

    选择上TypeScript,特别注意点空格是选择,点回车是下一步
  3. Choose a version of Vue.js that you want to start the project with

    选择 3.x (Preview)
  4. Use class-style component syntax

    直接回车
  5. Use Babel alongside TypeScript

    直接回车
  6. Pick a linter / formatter config

    直接回车
  7. Use history mode for router?

    直接回车
  8. Pick a linter / formatter config

    直接回车
  9. Pick additional lint features

    直接回车
  10. Where do you prefer placing config for Babel, ESLint, etc.?

    直接回车
  11. Save this as a preset for future projects?

    直接回车

文件结构:

my-project
+--- babel.config.js
+--- package-lock.json
+--- package.json
+--- public
| +--- favicon.ico
| +--- index.html
+--- README.md
+--- src
| +--- App.vue
| +--- assets
| | +--- logo.png
| +--- components
| | +--- HelloWorld.vue
| +--- main.ts
| +--- shims-vue.d.ts
+--- tsconfig.json
+--- node_modules
| +--- ...

入口文件为src/main.ts

vite创建

执行以下命令创建项目

$npm init vite-app <project-name>
$cd <project-name>
$npm install
$npm run dev

文件结构:

project-name
+--- index.html
+--- package-lock.json
+--- package.json
+--- public
| +--- favicon.ico
+--- src
| +--- App.vue
| +--- assets
| | +--- logo.png
| +--- components
| | +--- HelloWorld.vue
| +--- index.css
| +--- main.js
+--- node_modules
| +--- ...

入口文件为src/main.ts

注意: 由于使用vite方法创建的项目没有vue的声明文件, 所以需要我们自定义, 否则会报错.

src/shims-vue.d.ts

/* eslint-disable */
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}

安装vue-router

$npm install vue-router@4

至此, package.json如下:

{
"name": "my-project",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "^3.6.5",
"vue": "^3.0.0",
"vue-router": "^4.0.12"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^4.18.0",
"@typescript-eslint/parser": "^4.18.0",
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-typescript": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/compiler-sfc": "^3.0.0",
"@vue/eslint-config-typescript": "^7.0.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^7.0.0",
"typescript": "~4.1.5"
}
}

创建/修改组件

  1. 创建src/router/index.ts

    import { createRouter, createWebHashHistory } from "vue-router"
    
    import Home from '../components/Home.vue'
    import About from '../components/About.vue'
    import User from '../components/User.vue' const routes = [
    // router参数详细看下文
    {
    path: "/home",
    name: "home",
    component: Home
    },
    {
    path: "/about",
    name: "about",
    component: About
    },
    {
    path: "/user/:uid", // 动态参数
    name: "user",
    component: User
    }
    ]
    export const router = createRouter({
    history: createWebHashHistory(),
    routes: routes
    })
  2. 创建组件: Home.vue About.vue User.vue

    src/components/Home.vue

    <template>
    <div>home组件</div>
    </template> <script lang="ts">
    import { defineComponent } from "vue"; export default defineComponent({
    name: "Home",
    setup() {
    return {
    // 返回的数据
    };
    },
    });
    </script>

    src/components/About.vue

    <template>
    <div>About组件</div>
    </template> <script lang="ts">
    import { defineComponent } from "vue"; export default defineComponent({
    name: "About",
    setup() {
    return {
    // 返回的数据
    };
    },
    });
    </script>

    src/components/User.vue

    <template>
    <div>User组件</div>
    </template> <script lang="ts">
    import { defineComponent } from "vue"; export default defineComponent({
    name: "User",
    setup() {
    return {
    // 返回的数据
    };
    },
    });
    </script>
  3. 修改App.vue

    <template>
    <div>{{ appMessage }}</div>
    <!-- router-link会被渲染成a标签 -->
    <router-link to="/home">home</router-link>
    <router-link to="/about">about</router-link>
    <router-link to="/user/lczmx">user</router-link> <!-- 路由出口 -->
    <!-- 路由匹配到的组件将渲染在这里 -->
    <router-view></router-view>
    </template> <script lang="ts">
    import { defineComponent } from "vue"; export default defineComponent({
    name: "App",
    setup() {
    const appMessage = "App组件";
    return {
    // 返回的数据
    appMessage,
    };
    },
    });
    </script>
    <style>
    /* 添加样式 */
    #app {
    text-align: center;
    margin-top: 50px;
    }
    a {
    margin: 30px;
    display: inline-block;
    }
    </style>

修改入口ts

修改src/main.ts

import { createApp } from 'vue'
import App from './App.vue'
import './index.css' import { router } from './router' // 创建应用 返回对应的实例对象
const app = createApp(App) // 安装 vue-router 插件
app.use(router)
// 调用mount方法
app.mount('#app')

启动vue

$npm run serve

> my-project@0.1.0 serve
> vue-cli-service serve INFO Starting development server...
98% after emitting CopyPlugin DONE Compiled successfully in 6387ms 下午4:14:30 App running at:
- Local: http://localhost:8080/
- Network: http://192.168.43.12:8080/ Note that the development build is not optimized.
To create a production build, run npm run build. No issues found.

在浏览器中访问

根据提示, 访问http://localhost:8080/, 如下图

文件结构图片

综合使用

动态参数

假如我们需要的路由是: /user/lczmx/user/jack, 但是我们明显不可能为这两个路由定义两个不同的组件, 最好的方法就是使用动态参数:

const routes = [
// 动态段以冒号开始
{ path: '/users/:id', component: User },
// 使用正则表达式 `()` 里面的东西会传给前面的pathMatch
// 值在route.params.pathMatch下
{ path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound },
]

匹配时, 会将参数映射到router实例的currentRoute.value.params

注意vue2中: 由于在setup无法使用this.$routethis.$router

至于如何获取, 看我的另一篇博客: vue3获取当前路由 和 官网: Vue Router 和 组合式 API

匹配列表

匹配模式 匹配路径 当前路由的参数
/users/:username /users/eduardo { username: 'eduardo' }
/users/:username/posts/:postId /users/eduardo/posts/123 { username: 'eduardo', postId: '123' }

在使用带有参数的路由时需要注意: 由于相同的组件实例将被重复使用,所以组件的生命周期钩子不会被调用

但是我们可以对路由进行监听

使用watch监听动态参数

修改src/components/User.vue:

<template>
<div>User组件</div>
<p>当前用户: {{ uid }}</p> <router-link to="/user/lczmx">lczmx</router-link>
<router-link to="/user/jack">jack</router-link>
</template> <script lang="ts">
import { defineComponent, watch, ref } from "vue";
import { useRouter } from "vue-router"; export default defineComponent({
name: "User",
setup() {
const router = useRouter();
const uid = ref(router.currentRoute.value.params.uid);
watch(
// 监听非响应式数据
() => router.currentRoute.value,
(val) => {
// 修改uid
uid.value = val.params.uid;
}
);
return {
// 返回的数据
uid,
};
},
});
</script>

使用组合API监听动态参数

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

重定向

下面使用router的全部参数:

const routes = [
{
path: "/",
// 写法1 写死url
// redirect: "/home", // 访问 "/" 时 跳转到 "/home" // 写法2 跳转到对应的命名路由
redirect: { name: "home" }, // 写法3 定义一个方法
// 该方法亦可以 返回一个相对路径
/*
redirect: to => {
// 方法接收目标路由作为参数 "to" // return 重定向的字符串路径/路径对象 // query指定参数
return { path: '/home', query: { q: to.params.searchText } }
},
*/
},
{
path: "/home",
name: "home",
component: Home
}
]

注意, 重定向不会触发 导航守卫

另附官网的例子: Named Views - Vue Router 4 examples

命名与别名

命名路由

给路由一个名称, 可以在其他路由中使用, 如: redirectrouter-link

const routes = [
{
path: '/user/:username',
name: 'user',
component: User
}
]

redirect的使用如上文, 而router-link如下:

<template>
<div>User组件</div>
<p>当前用户: {{ uid }}</p> <router-link :to="{ name: 'user', params: { uid: 'lczmx' } }"
>lczmx</router-link
>
<router-link :to="{ name: 'user', params: { uid: 'jack' } }"
>jack</router-link
>
</template>

router.push(routerrouter对象)中使用:

router.push({ name: 'user', params: { uid: 'lczmx' } })

命名视图

即, 我们可以router-view定义一个名字, 已达到实现可复用的效果

我们可以使用这个功能实现 一个侧边栏等

举个例子

  1. 定义路由:
    import { createRouter, createWebHashHistory } from "vue-router"
    
    import Home from '../components/Home.vue'
    import About from '../components/About.vue'
    import User from '../components/User.vue' const routes = [
    {
    path: "/",
    components: {
    default: Home, // 默认用Home组件
    a: About, // a用About组件
    b: User, // b用User组件
    }, },
    {
    path: "/home",
    components: {
    default: About, // 默认用About组件
    a: Home, // a用Home组件
    b: User, // b用User组件
    }, },
    ] export const router = createRouter({
    history: createWebHashHistory(),
    routes: routes
    })
  2. 修改App.vue
    <template>
    <div>{{ appMessage }}</div> <!-- router-link会被渲染成a标签 -->
    <router-link to="/">/</router-link>
    <router-link to="/home">/home</router-link> <!-- 路由出口 -->
    <!-- 路由匹配到的组件将渲染在这里 -->
    <!-- default -->
    <router-view></router-view>
    <router-view name="about"></router-view>
    <router-view name="user"></router-view>
    </template> <script lang="ts">
    import { defineComponent } from "vue"; export default defineComponent({
    name: "App",
    setup() {
    const appMessage = "App组件";
    return {
    // 返回的数据
    appMessage,
    };
    },
    });
    </script>
    <style>
    /* 添加样式 */
    #app {
    text-align: center;
    margin-top: 50px;
    }
    a {
    margin: 30px;
    display: inline-block;
    }
    </style>
  3. 其他组件

    About.vue:
    <template>
    <div>about组件</div>
    </template>

    Home.vue:

    <template>
    <div>home组件</div>
    </template>

    User.vue

    <template>
    <div>user组件</div>
    </template>
  4. 启动服务并访问vue

    如图:

假如不指定视图名, 那么为default

别名

可以实现 不同url 访问同一路由的效果

const routes = [
// 可以访问 "/home" 也可以访问 "/"
// 且访问的路径不会改变
{
path: "/home",
name: "home",
component: Home,
alias: "/"
}

嵌套路由

之前我们在App.vue中定义router-view, 让其他组件在哪里渲染

但假如我们需要在其他组件中渲染的话, 就需要嵌套路由了

使用children嵌套路由, 它的值是路由数据, 就好像外部的router那样定义

例子:

  • router.index.ts

    import { createRouter, createWebHashHistory } from "vue-router"
    
    import Home from '../components/Home.vue'
    import About from '../components/About.vue'
    import User from '../components/User.vue'
    import UserHome from '../components/UserHome.vue'
    import UserSettings from '../components/UserSettings.vue'
    import UserProfile from '../components/UserProfile.vue' const routes = [
    // 可以访问 "/home" 也可以访问 "/"
    // 且访问的路径不会改变
    {
    path: "/home",
    name: "home",
    component: Home,
    alias: "/"
    },
    {
    path: "/about",
    name: "about",
    component: About
    },
    {
    path: "/user/:uid", // 动态参数
    name: "user",
    component: User, // 内部有router-view渲染要嵌套的路由
    children: [
    // 匹配形如 /user/lczmx 的url
    { path: "", component: UserHome }, // 匹配形如 /user/lczmx/settings 的url
    { path: "settings", component: UserSettings, name: "user-settings" }, // 匹配形如 /user/lczmx/profile 的url
    { path: "profile", component: UserProfile, name: "user-profile" }
    ]
    }
    ] export const router = createRouter({
    history: createWebHashHistory(),
    routes: routes
    })

    注意: 假如children中没有path: ""的话, 那么访问/user/lczmx, 只能得到一个页面空白

  • User.vue

    <template>
    <div>
    <router-link :to="{ name: 'user-settings' }">settings</router-link>
    <router-link :to="{ name: 'user-profile' }">profile</router-link>
    </div> <router-view></router-view>
    </template>
  • UserHome.vue

    <template>
    <div>用户主页</div>
    </template>
  • UserProfile.vue

    <template>
    <div>用户详细信息页面</div>
    </template>
  • UserSettings.vue

    <template>
    <div>用户设置页面</div>
    </template>
  • 启动并访问

    在浏览器中测试:

编程式路由

即不通过a标签, 而不是通过js/ts改变路由, 原理是history栈添加一个新的记录

在vue3中, 有以下写法

<template>
<div>about组件</div>
<button @click="changeRouter">修改路由</button>
</template> <script lang="ts">
import { defineComponent } from "vue"; import { useRouter } from "vue-router"; export default defineComponent({
name: "About",
setup() {
// 获得router对象
const router = useRouter(); const changeRouter = () => {
/* 修改路由的例子 */ // 1 字符串路径
router.push("/users/lczmx"); // 2 带有路径的对象
router.push({ path: "/users/lczmx" }); // 3 命名的路由,并加上参数,让路由建立 url
router.push({ name: "user", params: { username: "lczmx" } }); // 4 带查询参数,结果是 /register?plan=private
router.push({ path: "/register", query: { plan: "private" } }); // 5 带 hash,结果是 /about#team
router.push({ path: "/about", hash: "#team" }); // 6 我们可以手动建立 url,但我们必须自己处理编码
const username = "lczmx";
router.push(`/user/${username}`); // -> /user/lczmx
// 同样
router.push({ path: `/user/${username}` }); // -> /user/lczmx
// 如果可能的话,使用 `name` 和 `params` 从自动 URL 编码中获益
router.push({ name: "user", params: { username } }); // -> /user/lczmx // 7 `params` 不能与 `path` 一起使用, 否则 `params` 将会被忽略
router.push({ path: "/user", params: { username } }); // -> /user // 8 replace为true 不向history 中添加
router.push({ path: "/home", replace: true });
// 等同于
router.replace({ path: "/home" }); // 9 横跨历史
// 向前移动一条记录,与 router.forward() 相同
router.go(1);
// 返回一条记录,与router.back() 相同
router.go(-1);
// 前进 3 条记录
router.go(3);
// 如果没有那么多记录,静默失败
router.go(-100);
router.go(100);
};
return {
// 返回的数据
changeRouter,
};
},
});
</script> <style>
button {
margin: 30px;
}
</style>

更多见vue-router4官网: Vue Router

vue3+TypeScript+vue-router使用的更多相关文章

  1. Vue3: 如何以 Vite 创建,以 Vue Router, Vuex, Ant Design 开始应用

    本文代码: https://github.com/ikuokuo/start-vue3 在线演示: https://ikuokuo.github.io/start-vue3/ Vite 创建 Vue ...

  2. vue3+typescript引入外部文件

    vue3+typescript中引入外部文件有几种方法 (eg:引入echarts) 第一种方法: 1 indext.html中用script引入 <div id="app" ...

  3. Vue Router路由管理器介绍

    参考博客:https://www.cnblogs.com/avon/p/5943008.html 安装介绍:Vue Router 版本说明 对于 TypeScript 用户来说,vue-router@ ...

  4. Vue3 + TypeScript 开发实践总结

    前言 迟来的Vue3文章,其实早在今年3月份时就把Vue3过了一遍.在去年年末又把 TypeScript 重新学了一遍,为了上 Vue3 的车,更好的开车.在上家公司4月份时,上级领导分配了一个内部的 ...

  5. 基于SqlSugar的开发框架循序渐进介绍(14)-- 基于Vue3+TypeScript的全局对象的注入和使用

    刚完成一些前端项目的开发,腾出精力来总结一些前端开发的技术点,以及继续完善基于SqlSugar的开发框架循序渐进介绍的系列文章,本篇随笔主要介绍一下基于Vue3+TypeScript的全局对象的注入和 ...

  6. Vue 2.0 + Vue Router + Vuex

    用 Vue.js 2.x 与相配套的 Vue Router.Vuex 搭建了一个最基本的后台管理系统的骨架. 当然先要安装 node.js(包括了 npm).vue-cli 项目结构如图所示: ass ...

  7. vue router 只需要这么几步

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  8. Vue.js 2.x笔记:路由Vue Router(6)

    1. Vue Router简介与安装 1.1 Vue Router简介 Vue Router 是 Vue.js 官方的路由管理器.它和 Vue.js 的核心深度集成,构建单页面应用. Vue Rout ...

  9. 在typeScript+vue项目中使用ref

    因为vue项目是无法直接操作dom的,但是有时候开发需求迫使我们去操作dom. 两个办法,一个是很low的再引入jq,然后通过jq来操作,但是这样就失去了我们使用vue的意义, 可惜的是我曾经这样干过 ...

随机推荐

  1. [学习总结]2、android中的VelocityTracker(获得速率用的类)

    参考资料:http://blog.jrj.com.cn/4586793646,5298605a.html 感谢这位兄弟! android.view.VelocityTracker主要用跟踪触摸屏事件( ...

  2. mysql死锁com.mysql.cj.jdbc.exception.MYSQLTransactionRollbackException Deadlock found when trying to get lock;try restarting transaction

    1.生产环境出现以下报错 该错误发生在update操作中,该表并未建立索引,也就是只有InnoDB默认的主键索引,发生错误的程序是for循环中update. 什么情况下会出现Deadlock foun ...

  3. 【Java 设计】如何优雅避免空指针调用

    空指针引入 为了避免空指针调用,我们经常会看到这样的语句 if (someobject != null) { someobject.doCalc();} 最终,项目中会存在大量判空代码,多么丑陋繁冗! ...

  4. 程序员Meme 第02期

  5. Tableau如何绘制凹凸图

    一.把订单日期拖拽至列,把销售额拖拽至行,类别拖拽至标记,并把订单日期拖拽至筛选器选择2017年 二.创建计算字段销售排名 三.将刚刚创建的销售排名拖拽至行,计算依据-类别 四.销量排名拖拽成两个,图 ...

  6. Win7远程连接问题:凭据不工作 & 没有授权此用户账户

    一 您的凭据不工作 1.问题描述 win7系统远程桌面到某个电脑的一个账户名为admin 的用户,但提示"您的凭据不工作,之前连到 *.*.*.*的凭据无法使用,请输入新凭据",即 ...

  7. time_formatter(uaf)

    拿到题目先例行检查 然后进入主函数查看程序流程, 进入函数 这些字符串对我们选择1的输入进行了限制 在输入里面,可以看到strdup这个关键性的函数 调用了malloc这个函数 在选择四里面,可以看到 ...

  8. w4sp-lab安装

    扯淡 i春秋有个答题活动,苟了个奖品,我选了一本书:<wireshark与metasploit实战指南>,里面有个配套环境,本来看着书上说使用docker搭建的,以为很简单,只需要pull ...

  9. 【web】BUUCTF-web刷题记录

    本来一题一篇文章,结果发现太浪费了,所以整合起来了,这篇博文就记录 BUUCTF 的  web 题目的题解吧! 随便注 随便输入一个单引号,报错 order by 3就不行了 尝试联合查询的时候出现提 ...

  10. CF108A Palindromic Times 题解

    Content 现在是 \(h\) 时 \(m\) 分,请求出在此之后(不包含此时)的第一个回文时间. 数据范围:\(0\leqslant h\leqslant 23,0\leqslant m\leq ...