欢迎来到3672js教程,我们关注js教程、js框架、js代码特效等。

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

3672Js.Com2022-01-10 00:12 来源:未知 阅读:3913 关注度5

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


目录
  • 简单使用
    • 创建项目
      • vue-cli创建
      • vite创建
    • 安装vue-router
      • 创建/修改组件
        • 修改入口ts
          • 启动vue
            • 在浏览器中访问
              • 文件结构图片
              • 综合使用
                • 动态参数
                  • 使用watch监听动态参数
                  • 使用组合API监听动态参数
                • 重定向
                  • 命名与别名
                    • 命名路由
                    • 命名视图
                    • 别名
                  • 嵌套路由
                    • 编程式路由

                    简单使用

                    创建项目

                    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"
                      }
                    }

                    创建/修改组件

                    创建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
                    })

                    创建组件: 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>

                    修改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定义一个名字, 已达到实现可复用的效果
                    我们可以使用这个功能实现 一个侧边栏等

                    举个例子

                    定义路由:

                    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
                    })

                    修改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>

                    其他组件
                    About.vue:

                    <template>
                      <div>about组件</div>
                    </template>

                    Home.vue:

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

                    User.vue

                    <template>
                      <div>user组件</div>
                    </template>

                    启动服务并访问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

                    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持3672js教程。

                    您可能感兴趣的文章:
                    • Vue3中使用typescript封装axios的实例详解
                    • Vue3结合TypeScript项目开发实战记录
                    • Vue3结合TypeScript项目开发实践总结
                    • Vue3 + TypeScript 开发总结
                    • Vue3+TypeScript实现递归菜单组件的完整实例
                    • Vue3+TypeScript封装axios并进行请求调用的实现
                    • 详解Vue3.0 + TypeScript + Vite初体验
                    • vue3+typeScript穿梭框的实现示例
                    • vue3+typescript实现图片懒加载插件
                    • 浅谈Vue3.0之前你必须知道的TypeScript实战技巧
                    • 详解Vue3.0 前的 TypeScript 最佳入门实践

                    本站文章为3672js教程网友分享投稿,版权归原作者,欢迎任何形式的转载,但请务必注明出处。同时文章内容如有侵犯了您的权益,请联系我们处理。
                    评论已被关闭
                    {dede:include filename="foot.htm"/}