1. 程式人生 > 程式設計 >vue3+TypeScript+vue-router的使用方法

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

目錄
  • 簡單使用
    • 建立專案
      • -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. 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
                    |   +--- co
                    mponents | | +--- 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.
                    |   +--- 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",});
                    </script>

                    src/components/User.vue

                    <template>
                      <div>User元件</div>
                    </template>
                     
                    <script lang="ts">
                    import { defineComponent } from "vue";
                     
                    export default defineComponent({
                      name: "User",});
                    </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
                    
                    > [email protected] 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/,如下圖

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

                    檔案結構圖片

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

                    綜合使用

                    動態引數

                    假如我們需要的路由是: /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>

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

                    使用組合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",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,]
                     
                     
                    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 http://www.cppcns.comname="user"></router-view>
                    </template>
                     
                    <script lang="ts">
                    import { defineComponent } from "vue";
                     
                    export default defineComponent({
                      name: "App",});
                    </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

                    如圖:

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

                    假如不指定檢視名,那麼為default

                    別名

                    可以實現 不同url 訪問同一路由的效果

                    const routes = [
                        // 可以訪問 "/home" 也可以訪問 "/"
                        // 且訪問的路徑不會改變
                        {
                            path: "/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",alias: "/"
                    	},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>

                    啟動並訪問

                    在瀏覽器中測試:

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

                    程式設計式路由

                    即不通過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

                    以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。