vue 声明式导航与编程式导航

294 阅读1分钟

前言

想做这样一个效果:

image.png

一、创建项目及初始化操作

  1. 找一块风水宝地,cmd 下 vue create my-vue-router
  2. 切换到目录文件夹下 cd my-vue-router
  3. 顺便下包 yarn add vue-router@3.5.3npm i vue-router@3.5.3
  4. 运行项目 yarn servenpm run serve
  5. 回到 VSCode,删除不需要的文件,创建项目所需文件

image.png

vue.config.js

module.exports={
    devServer:{
        open:true
    },
    lintOnSave:false
}

App.vue

<template>
  <div id="app">
    <a href="#/home">我的首页</a>
    <a href="#/find">我的发现</a>
    <a href="#/part">我的朋友</a>
  </div>
</template>
<script>
export default {
  name: 'App'
}
</script>

Home.vue

<template>
    <div>
        我是 Home 组件
    </div>
</template>

<script>
export default {
    name: 'Home'
}
</script>

Find.vue

<template>
    <div>
        我是 Find 组件
    </div>
</template>

<script>
export default {
    name: 'Find'
}
</script>

Part.vue

<template>
    <div>
        我是 Part 组件
    </div>
</template>

<script>
export default {
    name: 'Part'
}
</script>

二、布置路由规则

router/index.js

import Vue from 'vue'
// ◆导入组件
import Home from '../views/Home.vue'
import Find from '../views/Find.vue'
import Part from '../views/Part.vue'
// 0.下包 yarn add vue-router@3.5.3
// 1.引入 VueRouter 函数
import VueRouter from 'vue-router'
// 2.添加到 Vue.use()身上,注册全局 RouterLink 和 RouterView 组件
Vue.use(VueRouter)
// 3.创建路由规则数组,路径和组件名一一对应
const routes=[
  {
    path:'/home',
    component:Home
  },
  {
    path:'/find',
    component:Find,
  },
  {
    path:'/part',
    component:Part
  }
]
// 4.创建路由对象,传入规则
const router=new VueRouter ({
  routes
})
// 5.默认导出路由对象
export default router

main.js

import Vue from 'vue'
import App from './App.vue'
// 6.默认导入路由规则对象
import router from './router'
Vue.config.productionTip = false
new Vue({
  render: h => h(App),
  // 7.把路由对象挂载到 new Vue 实例中
  router
}).$mount('#app')

App.vue

<template>
  <div id="app">
    <div class="nav">
      <a href="#/home">我的首页</a>
      <a href="#/find">我的发现</a>
      <a href="#/part">我的朋友</a>
    </div>
    <div class="content">
      <!-- 8. 用 router-view 作为挂载点,切换不同的路由页面 -->
      <router-view></router-view>
    </div>
  </div>
</template>
<script>
export default {
  name: "App"
}
</script>

页面初始效果

image.png

三、声明式导航

1、声明式导航跳转

把 a 标签换成 router-link,且必须带 to 属性: to="/path"

<template>
  <div id="app">
    <div class="nav">
      <router-link to="/home">我的首页</router-link>
      <router-link to="/find">我的发现</router-link>
      <router-link to="/part">我的朋友</router-link>
    </div>
    <div class="content">
      <!-- 8. 用 router-view 作为挂载点,切换不同的路由页面 -->
      <router-view></router-view>
    </div>
  </div>
</template>
<script>
export default {
  name: "App"
}
</script>
<style scoped>
/* 设置高亮样式 */
  .router-link-active {
    background-color: greenyellow;
  }
</style>

点击“我的发现”,审查元素

image.png

小结:

  1. router-link 替代了 a 标签, 不需要手动写 #, 会自动决定是否加 #
  2. 当前被点击的 a 标签会自动添加类名: router-link-activerouter-link-exact-active
  3. 本质: 最终还是会被渲染成 a 标签

2、声明式导航传参

query 传参

(1)App.vue传递参数

<router-link to="/find?name=晚子&age=18岁">我的发现</router-link>
<!-- <router-link :to="{path:'/find',query:{name:'晚子',age:'18岁'}}">我的发现</router-link> -->

(2)Find.vue获取参数

 <p>{{$route.query.name}}-{{$route.query.age}}</p>

(3)页面效果

image.png

params 传参

(1) router/index.js 中配置

const routes=[
// 省略其他。。。。。。
  {
    path:'/part/:friend/:age',
    component:Part,
    name:'part'
  }
]

(2)App.vue 传递参数

<router-link to="/part/小夏/20岁">我的朋友</router-link>
<!-- <router-link :to="{name:'part',params:{friend:'小夏',age:'20岁'}}">我的朋友</router-link> -->

(3)Part.vue 获取参数

<p>{{$route.params.friend}}-{{$route.params.age}}</p>

(4)页面效果

image.png

四、编程式导航

1、编程式导航跳转

App.vue

法1

<template>
  <div id="app">
    <div class="nav">
      <span @click="$router.push('/home')" >我的首页</span>
      <!-- <span @click="$router.push({path:'/home'})" >我的首页</span> -->
      <span @click="$router.push('/find')" >我的发现</span>
      <span @click="$router.push('/part')" >我的朋友</span>
    </div>
    <div class="content">
      <!-- 8. 用 router-view 作为挂载点,切换不同的路由页面 -->
      <router-view></router-view>
    </div>
  </div>
</template>
<script>
export default {
  name: "App"
}
</script>

法2

<template>
  <div id="app">
    <div class="nav">
      <span @click="goHome()">我的首页</span>
      <span @click="goFind()">我的发现</span>
      <span @click="goPart()">我的朋友</span>
    </div>
    <div class="content">
      <!-- 8. 用 router-view 作为挂载点,切换不同的路由页面 -->
      <router-view></router-view>
    </div>
  </div>
</template>
<script>
export default {
  name: "App",
  methods:{
    goHome(){
      this.$router.push('/home').catch(e=>e)
      // this.$router.push({path:'/home'}).catch(e=>e)
    },
    goFind(){
      this.$router.push('/find').catch(e=>e)
    },
    goPart(){
      this.$router.push('/part').catch(e=>e)
    }
  }
}
</script>

2、编程式导航传参

router/index.js

const routes=[
  {
    path:'/home',
    component:Home,
    name:'home'
  },
  {
    path:'/find',
    component:Find,
    name:'find'
  },
  {
    path:'/part/:friend/:age',
    // path:'/part',
    component:Part,
    name:'part'
  }
]

App.vue

<template>
  <div id="app">
    <div class="nav">
      <span @click="goHome()">我的首页</span>
      <span @click="goFind()">我的发现</span>
      <span @click="goPart()">我的朋友</span>
    </div>
    <div class="content">
      <!-- 8. 用 router-view 作为挂载点,切换不同的路由页面 -->
      <router-view></router-view>
    </div>
  </div>
</template>
<script>
export default {
  name: "App",
  data() {
    return {
      className: "home"
    }
  },
  methods:{
    goHome(){
      this.$router.push('/home').catch(e=>e)
      // this.$router.push({path:'/home'}).catch(e=>e)
    },
    goFind(){
      // 法1:问号传参 (方便)
      this.$router.push('/find/?name=晚子&age=18').catch(e=>e)
      // 法2:path + query 传参 (推荐)
      // this.$router.push({path:'/find',query:{name:'晚子',age:'18岁'}}).catch(e=>e)
      // 法3:name + query 传参 必须在路由规则中配置 name:'find' 
      // this.$router.push({name:'find',query:{name:'晚子',age:'18岁'}}).catch(e=>e)
    },
    goPart(){
      // 法1:动态路径传参,必须在路由规则中配置 path:'/part/:friend/:age'
      this.$router.push('/part/小夏/20岁').catch(e=>e)
      // 法2:name + params(推荐),必须在路由规则中配置 name:'part',刷新参数会丢失
      // this.$router.push({name:'part',params:{friend:'小夏',age:'20岁'}}).catch(e=>e)
      // 法3:path 会忽略 params (不使用)
      // this.$router.push({path:'/part',params:{friend:'小夏',age:'20岁'}}).catch(e=>e)
    }
  }
}
</script>

find.vue

<p>{{$route.query.name}}-{{$route.query.age}}</p>

part.vue

<p>{{$route.params.friend}}-{{$route.params.age}}</p>

结语

  1. 路由规则中,path 和 component 必写,建议把 name 都写上
  2. 声明式导航推荐 path + query 传参;编程式导航推荐 name + params 传参
  3. 获取 query 参数 :$route.query.参数名;获取 params 参数:$route.params.参数名