路由(router):Hash地址与组件之间的对应关系。
SPA与前端路由:
SPA指的是一个web网站只有唯一的一个html页面,所有组件的展示与切换都在这唯一的一个页面内完成。此时,不同组件之间的切换需要通过前端路由来实现。
前端路由的工作方式主要可以分为以下四步:
1.用户点击页面上的路由链接。
2.导致URL地址栏中的Hash值发生了变化。
3.前端路由监听到了Hash地址发生变化。
4.前端路由把当前Hash地址对应的组件渲染到浏览器中。
原理小案例:
<template lang="">
<div>
<h1>根组件</h1>
<a href="#/firstPage">首页</a>
<a href="#/img">图片</a>
<a href="#/video">视频</a>
<components :is="tapName"></components>
</div>
</template>
<script>
import child from "@/components/child.vue"
import left from "@/components/left.vue"
import right from "@/components/right.vue"
export default{
data(){
return{
// 在动态组件的位置,要展示组件的名字,值必须是字符串
tapName:"child"
}
},
created(){
// 只要当前App组件一被创建,就立即监听window对象的onhashchange事件
window.onhashchange=()=>{
switch(location.hash){
case "#/firstPage":
this.tapName="child"
break
case "#/img":
this.tapName="left"
break
case "#/video":
this.tapName="right"
break
}
}
},
components:{
child,
left,
right
}
}
</script>
<style lang="less" scoped>
a{
margin-left: 20px;
}
</style>
vue-router是vue.js官方给出的路由解决方案。只能结合vue项目使用,能够轻松的管理SPA项目中组件的切换。
vue-router安装和配置的步骤:
1.安装vue-router包(在vue2项目中,命令如下)
npm i vue-router@3.5.2 -S
2.创建路由版块
在src源代码目录下,新建router文件夹并在其下建index.js文件 路由模块,并初始化以下代码:
在index.js文件中创建以下内容
3.导入并挂载路由版块
// 导入vue这个包,得到vue构造函数
import Vue from 'vue'
// 导入app.vue根组件,将来要把app.vue中的模板结构,渲染到html页面中
// import App from './App.vue'
import App from "./App.vue"
// 导入需要被全局注册的那个组件
import count from "./components/child.vue"
// 第一个参数随便起,第二个是要注册的组件
Vue.component("MyCount","count")
// 导入路由模块,拿到路由的实例对象
import router from "@/router/index.js"
// 阻止启动生产消息
Vue.config.productionTip = false
// 创建vue的实例对象
new Vue({
// el:"#app",
el:"#app",
// 把render函数指定的组件,渲染到html页面中
render: h => h(App),
// 在vue项目中,要想使用路由,必须将路由实例对象进行如下挂载
// router:路由的实例对象
// router:router 属性名和属性值一样的情况下,可简写如下格式
router
})
// .$mount('#app')和el:"#app"效果一样,二选一
4.声明路由链接和占位符
路由重定向:
用户在访问地址A的时候,强制用户跳转到地址C,从而展示特定的组件页面。通过路由规则的redirect属性,指定一个新的路由地址,可以很方便的设置路由的重定向。
<template lang="">
<div>
<h1>根组件</h1>
<!-- 当安装配置了vue-router后,就可以使用router-link来代替a链接
比较专业的写法
-->
<!-- <a href="#/firstPage">首页</a> -->
<router-link to="/firstPage">首页</router-link>
<a href="#/img">图片</a>
<a href="#/video">视频</a>
<!-- 只要在项目中安装和配置了vue-router,就可以使用router-view这个组件 -->
<!-- 作用:占位符 -->
<router-view></router-view>
</div>
</template>
<script>
import child from "@/components/child.vue"
import left from "@/components/left.vue"
import right from "@/components/right.vue"
export default{
components:{
child,
left,
right
}
}
</script>
<style lang="less" scoped>
a{
margin-left: 20px;
}
</style>
index.js
// 1.导入Vue和VueRouter的包
import Vue from "vue";
import VueRouter from "vue-router";
import child from "@/components/child.vue"
import left from "@/components/left.vue"
import right from "@/components/right.vue"
// 2.调用Vue.use()函数,把VueRouter安装为Vue的插件
Vue.use(VueRouter)
// 3.创建路由的实例对象
const router=new VueRouter({
// routes是一个数组,定义hash地址与组件之间的对应关系。
routes:[
// 重定向路由规则,当用户访问/时,直接到达重定向后的首页
{path:"/",redirect:"/firstPage"},
{path:"/firstPage",component:child},
{path:"/img",component:left},
{path:"/video",component:right}
]
})
// 4.向外共享路由的实例对象
export default router
嵌套路由:通过路由实现组件的嵌套展示。
子路由规则:通过children声明子路由规则,在src/router/index.js路由模块中,导入需要的组件,并使用children属性声明子路由规则。
<template lang="">
<div>
<h1>根组件</h1>
<!-- 当安装配置了vue-router后,就可以使用router-link来代替a链接
比较专业的写法
-->
<!-- <a href="#/firstPage">首页</a> -->
<router-link to="/firstPage">首页</router-link>
<a href="#/img">图片</a>
<a href="#/video">视频</a>
<!-- 只要在项目中安装和配置了vue-router,就可以使用router-view这个组件 -->
<!-- 作用:占位符 -->
<router-view></router-view>
</div>
</template>
<script>
import child from "@/components/child.vue"
import left from "@/components/left.vue"
import right from "@/components/right.vue"
import Tab1 from "@/components/tabs/Tab1.vue"
import Tab2 from "@/components/tabs/Tab2.vue"
export default{
components:{
child,
left,
right,
Tab1,
Tab2
}
}
</script>
<style lang="less" scoped>
a{
margin-left: 20px;
}
</style>
index.js
// 1.导入Vue和VueRouter的包
import Vue from "vue";
import VueRouter from "vue-router";
import child from "@/components/child.vue"
import left from "@/components/left.vue"
import right from "@/components/right.vue"
import Tab1 from "@/components/tabs/Tab1.vue"
import Tab2 from "@/components/tabs/Tab2.vue"
// 2.调用Vue.use()函数,把VueRouter安装为Vue的插件
Vue.use(VueRouter)
// 3.创建路由的实例对象
const router=new VueRouter({
// routes是一个数组,定义hash地址与组件之间的对应关系。
routes:[
// 重定向路由规则,当用户访问/时,直接到达重定向后的首页
{path:"/",redirect:"/firstPage"},
{path:"/firstPage",component:child,redirect:"/firstPage/tab1",children:[
// 可通过重定向或者默认子路由来改变初始状态
// 默认子路由:如果children数组中,某个路由规则的path值为空字符串,则这条路由规则,叫做默认子路由。例:{path:"",component:Tab1}
{path:"tab1",component:Tab1},{path:"tab2",component:Tab2}]},
{path:"/img",component:left},
{path:"/video",component:right}
]
})
// 4.向外共享路由的实例对象
export default router
动态路由:
把Hash地址中可变的部分定义为参数项,从而提高路由规则的复用性。在vue-router中使用英文的冒号(:)来定义路由的参数项。
<template lang="">
<div>
<h1>根组件</h1>
<router-link to="/firstPage">首页</router-link>
<router-link to="/music1">牧马城市</router-link>
<!-- 注意:在hash地址中,/后面的参数项叫做路径参数,
在参数对象中,需要使用this.$route.params来访问路径参数
-->
<!-- 在hash地址中,?后面的参属项,叫做查询参数
在参数对象中,需要使用this.$route.query来访问查询参数
-->
<!--
在this.$route中,path只是路径部分,fullPath是完整地址
例:fullPath:/music2?name=张三
path:/music2
-->
<router-link to="/music2?name=张三">难却</router-link>
<router-link to="/music3">好一点</router-link>
<router-link to="/music4">金玉良缘</router-link>
<a href="#/img">图片</a>
<a href="#video">视频</a>
<router-view></router-view>
</div>
</template>
<script>
import child from "@/components/child.vue"
import left from "@/components/left.vue"
import right from "@/components/right.vue"
import Tab1 from "@/components/tabs/Tab1.vue"
import Tab2 from "@/components/tabs/Tab2.vue"
import music from "@/components/music.vue"
export default{
components:{
child,
left,
right,
Tab1,
Tab2,
music
}
}
</script>
<style lang="less" scoped>
a{
margin-left: 20px;
}
</style>
index.js
// 1.导入Vue和VueRouter的包
import Vue from "vue";
import VueRouter from "vue-router";
import child from "@/components/child.vue"
import left from "@/components/left.vue"
import right from "@/components/right.vue"
import Tab1 from "@/components/tabs/Tab1.vue"
import Tab2 from "@/components/tabs/Tab2.vue"
import music from "@/components/music.vue"
Vue.use(VueRouter)
const router=new VueRouter({
routes:[
{path:"/",redirect:"/firstPage"},
// 在music组件中,希望根据id值(此处id可自定义名字),展示对应music的信息
// props:true,开启传参
{path:"/music:id",component:music,props:true},
{path:"/firstPage",component:child,redirect:"/firstPage/tab1",children:[
{path:"tab1",component:Tab1},{path:"tab2",component:Tab2}]},
{path:"/img",component:left},
{path:"/video",component:right}
]
})
// 4.向外共享路由的实例对象
export default router
music.vue
<template lang="">
<div>
music组件
<!-- <p>{{this.$route.params.id}}</p> -->
<p>{{id}}</p>
<button @click="btn">点击打印this</button>
</div>
</template>
<script>
export default{
props:["id"],
methods:{
btn(){
console.log(this);
}
}
}
</script>
<style lang="less" scoped>
div{
width: 100%;
height: 50px;
background-color:orangered;
}
</style>