05-Vue提高之前端路由

01.路由的基本概念与原理(了解)

路由的本质就是一种对应关系,比如说我们在url地址中输入我们要访问的url地址之后,浏览器要去请求这个url地址对应的资源,那么url地址和真实的资源之间就有一种对应的关系,就是路由。

路由分为前端路由后端路由

1.1.后端路由:后端渲染

  • 概念:根据不同的用户 URL 请求,返回不同的内容
  • 本质: URL 请求地址与服务器资源之间的对应关系

1.2.SPA( Single Page Application)

  • 后端渲染(存在性能问题)
  • Ajax前端渲染(前端渲染提高性能,但是不支持浏览器的前进后退操作)
  • SPA( Single Page Application) 单页面应用程序:整个网站只有一个页面,内容的变化通过Ajax局部更新实现、同时支持浏览器地址栏的前进和后退操作。
  • SPA实现原理之一:基于URL地址的hash( hash的变化会导致浏览器记录访问历史的变化、但是hash的变化不会触发新的URL请求)
  • 在实现SPA过程中,最核心的技术点就是前端路由

1.3.前端路由

  • 概念:根据不同的用户事件, 显示不同的页面内容

  • 本质: 用户事件与事件处理函数之间的对应关系

  • 前端路由主要做的事情就是监听事件并分发执行事件处理函数

1.4.实现简易的前端路由

  • 基于URL中的hash实现(点击菜单的时候改变URL的hash,根据hash的变化控制组件的切换)
  • 核心实现依靠一个事件,即监听hash值变化的事件
window.onhashchange = function(){
    //location.hash可以获取到最新的hash值
    location.hash
}
  • 简易的前端路由实现tab栏切换
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>简易的前端路由实现tab栏切换</title>
    <!-- 导入 vue 文件 -->
    <script src="../js/vue.js"></script>
  </head>
  <body>
    <!-- 被 vue 实例控制的 div 区域 -->
    <div id="app">
      <!-- 切换组件的超链接 -->
      <a href="#/zhuye">主页</a> 
      <a href="#/keji">科技</a> 
      <a href="#/caijing">财经</a>
      <a href="#/yule">娱乐</a>

      <!-- 根据 :is 属性指定的组件名称,把对应的组件渲染到 component 标签所在的位置 -->
      <!-- 可以把 component 标签当做是【组件的占位符】 -->
      <component :is="comName"></component>
    </div>

    <script>
      /*定义需要被切换的 4 个组件*/
      //主页组件
      const zhuye = {
        template: '<h1>主页信息</h1>'
      }

      // 科技组件
      const keji = {
        template: '<h1>科技信息</h1>'
      }

      // 财经组件
      const caijing = {
        template: '<h1>财经信息</h1>'
      }

      // 娱乐组件
      const yule = {
        template: '<h1>娱乐信息</h1>'
      }
     
     /*Vue实例对象*/
      const vm = new Vue({
        el: '#app',
        data: {
          comName: 'zhuye'
        },
        // 注册私有组件
        components: {
          zhuye,
          keji,
          caijing,
          yule
        }
      })
      
      // 监听window 的 onhashchange 事件,根据获取到的最新的 hash 值,切换要显示的组件的名称
      window.onhashchange = function() {
        // 通过 location.hash 获取到最新的 hash 值
        console.log(location.hash);
        switch(location.hash.slice(1)){
          case '/zhuye':
            vm.comName = 'zhuye'
          break
          case '/keji':
            vm.comName = 'keji'
          break
          case '/caijing':
            vm.comName = 'caijing'
          break
          case '/yule':
            vm.comName = 'yule'
          break
        }
      }
    </script>
  </body>
</html>

思路分析:

  • 在页面中有一个vue实例对象,vue实例对象中有四个组件,分别是tab栏切换需要显示的组件内容,在页面中有四个超链接,如下:
<a href="#/zhuye">主页</a> 
<a href="#/keji">科技</a> 
<a href="#/caijing">财经</a>
<a href="#/yule">娱乐</a>
  • 当我们点击这些超链接的时候,就会改变url地址中的hash值,当hash值被改变时,就会触发onhashchange事件,在触发onhashchange事件的时候,我们根据hash值来让不同的组件进行显示:
window.onhashchange = function() {
    // 通过 location.hash 获取到最新的 hash 值
    console.log(location.hash);
    switch(location.hash.slice(1)){
        case '/zhuye':
        //通过更改数据comName来指定显示的组件
        //因为 <component :is="comName"></component> ,组件已经绑定了comName
        vm.comName = 'zhuye'
        break
        case '/keji':
        vm.comName = 'keji'
        break
        case '/caijing':
        vm.comName = 'caijing'
        break
        case '/yule':
        vm.comName = 'yule'
        break
    }
}

02.Vue Router基本使用(重要)

2.1.Vue Router简介

它是一个Vue.js官方提供的路由管理器。是一个功能更加强大的前端路由器,推荐使用。

Vue Router和Vue.js非常契合,可以一起方便的实现SPA(single page web application,单页应用程序)应用程序的开发。

Vue Router依赖于Vue,所以需要先引入Vue,再引入Vue Router

Vue Router的特性:

  • 支持H5历史模式或者hash模式
  • 支持嵌套路由
  • 支持路由参数
  • 支持编程式路由
  • 支持命名路由
  • 支持路由导航守卫
  • 支持路由过渡动画特效
  • 支持路由懒加载
  • 支持路由滚动行为

2.2.Vue Router的使用步骤

第一步:导入js文件

  • Vue Router依赖于Vue,所以需要先引入Vue,再引入Vue Router
<script src="../js/vue.js"></script>
<script src="../js/vue-router.js"></script>

第二步:添加路由链接

<!--<router-link>是路由中提供的标签,默认会被渲染为a标签-->
<!--to属性默认被渲染为href属性-->
<!--to属性的值会被渲染为#开头的hash地址-->

<router-link to="/user">User</router-link>
<router-link to="/login">Login</router-link>

第三步:添加路由填充位(路由占位符)

<router-view></router-view>

第四步:定义路由组件

var User = { template:"<div>This is User</div>" }
var Login = { template:"<div>This is Login</div>" }

第五步:配置路由规则并创建路由实例

var myRouter = new VueRouter({
    //routes是路由规则数组
    routes:[
        //每一个路由规则都是一个对象,对象中至少包含path和component两个属性
        //path表示路由匹配的hash地址,component表示路由规则对应要展示的组件对象
        {path:"/user",component:User},
        {path:"/login",component:Login}
    ]
})

第六步:将路由挂载到Vue实例中

new Vue({
    el:"#app",
    //通过router属性挂载路由对象
    router:myRouter
})

小结:

Vue Router的使用步骤还是比较清晰的,按照步骤一步一步就能完成路由操作
A.导入js文件
B.添加路由链接
C.添加路由占位符(最后路由展示的组件就会在占位符的位置显示)
D.定义路由组件
E.配置路由规则并创建路由实例
F.将路由挂载到Vue实例中
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    
    <!-- 第一步:导入js文件:先导入 vue文件, 再导入vue-router文件 -->
    <script src="../js/vue.js"></script>
    <!---->
    <script src="../js/vue-router.js"></script>
  </head>
  <body>
    <div id="app">
    	<!--第二步:添加路由链接-->
      <router-link to="/user">User</router-link>
      <router-link to="/register">Register</router-link>

     <!-- 第三步:添加路由填充位(路由占位符)-->
      <router-view></router-view>
    </div>

    <script>
    	/*第四步:定义路由组件*/
      const User = {
        template: '<h1>User 组件</h1>'
      }

      const Register = {
        template: '<h1>Register 组件</h1>'
      }

      /*第五步:配置路由规则并创建路由实例*/
      const myrouter = new VueRouter({
        // 所有的路由规则
        routes: [
          { path: '/user', component: User },
          { path: '/register', component: Register }
        ]
      })

      // 创建 vm 实例对象
      const vm = new Vue({
        el: '#app',
        data: {},
        /*第六步:将路由挂载到Vue实例中*/
        router: myrouter
      })
    </script>
  </body>
</html>

补充:

  • 路由重定向:可以通过路由重定向为页面设置默认展示的组件,也就是用户在访问地址A的时候,强制用户跳转到地址C,从而展示特定的页面组件。
  • 在路由规则中添加一条路由规则即可,如下:
var myRouter = new VueRouter({
    //routes是路由规则数组
    routes: [
        //path:表示页面最初始的地址 / ,redirect表示要被重定向的新地址,设置为一个路由即可
		//当访问/地址,强制跳转到/user地址
        { path:"/",redirect:"/user"},
        { path: "/user", component: User },
        { path: "/login", component: Login }
    ]
})

03.Vue Router嵌套路由(重要)

3.1.嵌套路由的概念

当我们进行路由的时候显示的组件中还有新的子级路由链接以及内容。

嵌套路由最关键的代码在于理解子级路由的概念:

比如我们有一个/login的路由
那么/login下面还可以添加子级路由,如:
/login/account
/login/phone

参考代码如下:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <!-- 第一步:导入js文件:先导入 vue文件, 再导入vue-router文件 -->
    <script src="../js/vue.js"></script>
    <script src="../js/vue-router.js"></script>
  </head>
  <body>
    <div id="app">
    	<!--第二步:添加路由链接-->
      <router-link to="/user">User</router-link>
      <router-link to="/register">Register</router-link>

      <!-- 第三步:添加路由填充位(路由占位符)-->
      <router-view></router-view>
    </div>

    <script>
    	/*第四步:定义路由组件*/
    	//不带嵌套的路由组件
      const User = {
        template: '<h1>User 组件</h1>'
      }
      //带嵌套的路由组件
      //Register路由组件中的模板代码里面包含了子级路由链接以及子级路由的占位符
      const Register = {
        template: `<div>
          <h1>Register 组件</h1>
          <hr/>
          <!-- 子路由链接 -->
          <router-link to="/register/tab1">tab1</router-link>
          <router-link to="/register/tab2">tab2</router-link>
          <!-- 子路由组件将会在router-view中显示 -->
        	<router-view></router-view>
        <div>`
      }
      
      //定义两个子级路由组件
      const Tab1 = {
        template: '<h3>tab1 子组件</h3>'
      }
      const Tab2 = {
        template: '<h3>tab2 子组件</h3>'
      }
      
       /*第五步:配置路由规则并创建路由实例*/
      // 创建路由实例对象
      const myrouter = new VueRouter({
        routes: [
          { path: '/', redirect: '/user'},
          { path: '/user', component: User },
          // children 数组表示子路由规则
          { path: '/register', component: Register, children: [
            { path: '/register/tab1', component: Tab1 },
            { path: '/register/tab2', component: Tab2 }
          ] }
        ]
      })

      // 创建 vm 实例对象
      const vm = new Vue({
        // 指定控制的区域
        el: '#app',
        data: {},
        /*第六步:将路由挂载到Vue实例中*/
       router: myrouter
      })
    </script>
  </body>
</html>

04.VueRouter动态路由匹配(重要)

  • 动态路由使用场景:多个路径中有一部分是相同的

4.1.动态路由匹配的基本用法:$route.params

  • 思考:有如下3个路由链接 ,该如何定义路由规则
<router-link to="/user/1">User1</router-link>
<router-link to="/user/2">User2</router-link>
<router-link to="/user/3">User3</router-link>
  • 定义成如下三个对应规则可以吗?
可以这样定义,但是不好,多了就会很麻烦
{ path: '/user/1', component: User }
{ path: '/user/2', component: User }
{ path: '/user/3', component: User }
  • 通过动态路由参数的模式进行路由匹配
var myRouter = new VueRouter({
    routes: [
        //动态路径参数,以冒号开头
        { path: "/user/:id", component: User }
        ]
     })
  • 路由组件中通过$route.params获取路由参数
var User = { template:"<div>用户:{{$route.params.id}}</div>"

参考代码如下:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <!-- 第一步:导入js文件:先导入 vue文件, 再导入vue-router文件 -->
    <script src="../js/vue.js"></script>
    <script src="../js/vue-router.js"></script>
  </head>
  <body>
    <!-- 被 vm 实例所控制的区域 -->
    <div id="app">
    	<!--第二步:添加路由链接-->
      <router-link to="/user/1">User1</router-link>
      <router-link to="/user/2">User2</router-link>
      <router-link to="/user/3">User3</router-link>
      <router-link to="/register">Register</router-link>

     <!-- 第三步:添加路由填充位(路由占位符)-->
      <router-view></router-view>
    </div>

    <script>
    	/*第四步:定义路由组件*/
      const User = {
        template: '<h1>User 组件  用户id为: {{$route.params.id}}</h1>'
      }

      const Register = {
        template: '<h1>Register 组件</h1>'
      }

     /*第五步:配置路由规则并创建路由实例*/
      const myrouter = new VueRouter({
        // 所有的路由规则
        routes: [
          { path: '/', redirect: '/user'},
          { path: '/user/:id', component: User },
          { path: '/register', component: Register }
        ]
      })

      // 创建 vm 实例对象
      const vm = new Vue({
        // 指定控制的区域
        el: '#app',
        data: {},
        /*第六步:将路由挂载到Vue实例中*/
        router: myrouter
      })
    </script>
  </body>
</html>

4.2.动态路由匹配的补充用法一:props[“id”]

  • 如果使用$route.params.id来获取路径传参的数据不够灵活,我们可以通过props参数形式来接收参数
/*第四步:定义路由组件*/
var User = { 
	  /*使用props获取path中的id*/
      props:["id"],
      template:"<div>用户:{{id}}</div>"
      }
      
/*第五步:配置路由规则并创建路由实例*/
var myRouter = new VueRouter({
    routes: [
        //如果props设置为true,route.params将会被设置为组件属性
        { path: "/user/:id", component: User,props:true },
        ]
})

4.3.动态路由匹配的补充用法二:props: [‘id’, ‘uname’, ‘age’]

  • 还有一种情况,我们可以将props设置为对象形式,那么就直接将对象的数据传递给组件进行使用。
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <!-- 第一步:导入js文件:先导入 vue文件, 再导入vue-router文件 -->
    <script src="../js/vue.js"></script>
    <script src="../js/vue-router.js"></script>
  </head>
  <body>
    <!-- 被 vm 实例所控制的区域 -->
    <div id="app">
    	<!--第二步:添加路由链接-->
      <router-link to="/user/1">User1</router-link>
      <router-link to="/user/2">User2</router-link>
      <router-link to="/user/3">User3</router-link>
      <router-link to="/register">Register</router-link>

     <!-- 第三步:添加路由填充位(路由占位符)-->
      <router-view></router-view>
    </div>

    <script>
    	/*第四步:定义路由组件*/
      const User = {
        props: ['id', 'uname', 'age'],
        template: '<h1>User 组件 -- 用户id为: {{id}} -- 姓名为:{{uname}} -- 年龄为:{{age}}</h1>'
      }

      const Register = {
        template: '<h1>Register 组件</h1>'
      }

      /*第五步:配置路由规则并创建路由实例*/
      const router = new VueRouter({
        // 所有的路由规则
        routes: [
          { path: '/', redirect: '/user'},
          { path: '/user/:id', component: User, props: { uname: 'lisi', age: 20 } },
          { path: '/register', component: Register }
        ]
      })

      // 创建 vm 实例对象
      const vm = new Vue({
        // 指定控制的区域
        el: '#app',
        data: {},
        /*第六步:将路由挂载到Vue实例中*/
        router: myrouter
      })
    </script>
  </body>
</html>

4.4.动态路由匹配的补充用法三:props: [‘id’, ‘uname’, ‘age’]

  • 如果想要获取传递的参数值还想要获取传递的对象数据,那么props应该设置为函数形式
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <!-- 第一步:导入js文件:先导入 vue文件, 再导入vue-router文件 -->
    <script src="../js/vue.js"></script>
    <script src="../js/vue-router.js"></script>
  </head>
  <body>
    <!-- 被 vm 实例所控制的区域 -->
    <div id="app">
    	<!--第二步:添加路由链接-->
      <router-link to="/user/1">User1</router-link>
      <router-link to="/user/2">User2</router-link>
      <router-link to="/user/3">User3</router-link>
      <router-link to="/register">Register</router-link>

     <!-- 第三步:添加路由填充位(路由占位符)-->
      <router-view></router-view>
    </div>

    <script>
    	/*第四步:定义路由组件*/
    	const User = {
        props: ['id', 'uname', 'age'],
        template: '<h1>User 组件 -- 用户id为: {{id}} -- 姓名为:{{uname}} -- 年龄为:{{age}}</h1>'
      }

      const Register = {
        template: '<h1>Register 组件</h1>'
      }

     /*第五步:配置路由规则并创建路由实例*/
      const myrouter = new VueRouter({
        // 所有的路由规则
        routes: [
          { path: '/', redirect: '/user' },
          {
            path: '/user/:id',
            component: User,
            props: route => ({ uname: 'zs', age: 20, id: route.params.id })
          },
          { path: '/register', component: Register }
        ]
      })
      // 创建 vm 实例对象
      const vm = new Vue({
        // 指定控制的区域
        el: '#app',
        data: {},
        /*第六步:将路由挂载到Vue实例中*/
        router: myrouter
      })
    </script>
  </body>
</html>

05.VueRouter 命名路由

5.1.命名路由的配置规则

  • 为了更加方便的表示路由的路径,可以给路由规则起一个别名,即为命名路由
const router = new VueRouter({
    routes: [
   	 {
    	// 命名路由
    	name: 'user',
    	path: '/user/:id',
   		component: User,
		props: route => ({ uname: 'zs', age: 20, id: route.params.id })
     }
    ]
  })
  • name为指定的别名,通过这个别名找到对应的路径,params为传递的id值
 <router-link :to="{ name: 'user', params: {id: 3} }">User3</router-link>
  • 参考案例
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <!-- 第一步:导入js文件:先导入 vue文件, 再导入vue-router文件 -->
    <script src="../js/vue.js"></script>
    <script src="../js/vue-router.js"></script>
  </head>
  <body>
    <!-- 被 vm 实例所控制的区域 -->
    <div id="app">
    	<!--第二步:添加路由链接-->
    	<!--不使用别名-->
      <router-link to="/user/1">User1</router-link>
      <router-link to="/user/2">User2</router-link>
      
      <!--使用别名:注意to前面是冒号,进行参数绑定-->
      <router-link :to="{name: 'user',params:{id: 1}}">User1</router-link>
      <router-link :to="{name: 'user',params:{id: 2}}">User2</router-link>
      <router-link :to="{ name: 'user', params: {id: 3} }">User3</router-link>
      
      <!-- 第三步:添加路由填充位(路由占位符)-->
      <router-view></router-view>
    </div>

    <script>
    	/*第四步:定义路由组件*/
    	const User = {
        props: ['id', 'uname', 'age'],
        template: '<h1>User 组件 -- 用户id为: {{id}} -- 姓名为:{{uname}} -- 年龄为:{{age}}</h1>'
      }

     /*第五步:配置路由规则并创建路由实例*/
      const myrouter = new VueRouter({
        // 所有的路由规则
        routes: [
          { path: '/', redirect: '/user' },
          {
            name:'user',
            path: '/user/:id',
            component: User,
            props: route => ({ uname: 'zs', age: 20, id: route.params.id })
          }
        ]
      })
      // 创建 vm 实例对象
      const vm = new Vue({
        // 指定控制的区域
        el: '#app',
        data: {},
        /*第六步:将路由挂载到Vue实例中*/
        router: myrouter
      })
    </script>
  </body>
</html>

06.VueRouter 编程式导航(重点:类似路由转发)

6.1.页面导航的两种方式

  • 声明式导航:通过点击链接的方式实现的导航
例如:
	普通网页中的<a></a>链接
	Vue中的<route-link></route-link>
  • 编程式导航:调用js的api方法实现导航
例如:
	普通网页中的location.href
  • Vue-Router中常见的导航方式
this.$router.push("hash地址");
this.$router.push("/login");

this.$router.push({ name:'user' , params: {id:3} });
this.$router.push({ path:"/login"});
this.$router.push({ path:"/login",query:{username:"jack"} });

this.$router.go( n );//n为数字,参考history.go
this.$router.go( -1 );
  • 案例
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <!-- 第一步:导入js文件:先导入 vue文件, 再导入vue-router文件 -->
    <script src="../js/vue.js"></script>
    <script src="../js/vue-router.js"></script>
  </head>
  <body>
    <!-- 被 vm 实例所控制的区域 -->
    <div id="app">
      <router-link to="/user/1">User1</router-link>
      <router-link to="/user/2">User2</router-link>
      <router-link :to="{ name: 'user', params: {id: 3} }">User3</router-link>
      <router-link to="/register">Register</router-link>

      <!-- 路由占位符 -->
      <router-view></router-view>
    </div>

    <script>
      const User = {
        props: ['id', 'uname', 'age'],
        template: `<div>
          <h1>User 组件 -- 用户id为: {{id}} -- 姓名为:{{uname}} -- 年龄为:{{age}}</h1>
          <button @click="goRegister">跳转到注册页面</button>
        </div>`,
        methods: {
          goRegister() {
            this.$router.push('/register')
          }
        },
      }

      const Register = {
        template: `<div>
          <h1>Register 组件</h1>
          <button @click="goBack">后退</button>
        </div>`,
        methods: {
          goBack() {
            this.$router.go(-1)
          }
        }
      }

      // 创建路由实例对象
      const myrouter = new VueRouter({
        // 所有的路由规则
        routes: [
          { path: '/', redirect: '/user' },
          {
            // 命名路由
            name: 'user',
            path: '/user/:id',
            component: User,
            props: route => ({ uname: 'zs', age: 20, id: route.params.id })
          },
          { path: '/register', component: Register }
        ]
      })

      // 创建 vm 实例对象
      const vm = new Vue({
        // 指定控制的区域
        el: '#app',
        data: {},
        router: myrouter
      })
    </script>
  </body>
</html>

07.实现后台管理案例(了解)

点击左侧的"用户管理",“权限管理”,“商品管理”,“订单管理”,"系统设置"都会出现对应的组件并展示内容

其中"用户管理"组件展示的效果如上图所示,在用户管理区域中的详情链接也是可以点击的,点击之后将会显示用户详情信息。

7.1.引入基本素材

  • 先将素材文件夹中的11.基于vue-router的案例.html复制到我们自己的文件夹中,看一下这个文件中的代码编写了一些什么内容,这个页面已经把后台管理页面的基本布局实现了。
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>基于vue-router的案例</title>
    <style type="text/css">
      html,
      body,
      #app {
        margin: 0;
        padding: 0px;
        height: 100%;
      }
      .header {
        height: 50px;
        background-color: #545c64;
        line-height: 50px;
        text-align: center;
        font-size: 24px;
        color: #fff;
      }
      .footer {
        height: 40px;
        line-height: 40px;
        background-color: #888;
        position: absolute;
        bottom: 0;
        width: 100%;
        text-align: center;
        color: #fff;
      }
      .main {
        display: flex;
        position: absolute;
        top: 50px;
        bottom: 40px;
        width: 100%;
      }
      .content {
        flex: 1;
        text-align: center;
        height: 100%;
      }
      .left {
        flex: 0 0 20%;
        background-color: #545c64;
      }
      .left a {
        color: white;
        text-decoration: none;
      }
      .right {
        margin: 5px;
      }
      .btns {
        width: 100%;
        height: 35px;
        line-height: 35px;
        background-color: #f5f5f5;
        text-align: left;
        padding-left: 10px;
        box-sizing: border-box;
      }
      button {
        height: 30px;
        background-color: #ecf5ff;
        border: 1px solid lightskyblue;
        font-size: 12px;
        padding: 0 20px;
      }
      .main-content {
        margin-top: 10px;
      }
      ul {
        margin: 0;
        padding: 0;
        list-style: none;
      }
      ul li {
        height: 45px;
        line-height: 45px;
        background-color: #a0a0a0;
        color: #fff;
        cursor: pointer;
        border-bottom: 1px solid #fff;
      }

      table {
        width: 100%;
        border-collapse: collapse;
      }

      td,
      th {
        border: 1px solid #eee;
        line-height: 35px;
        font-size: 12px;
      }

      th {
        background-color: #ddd;
      }
    </style>
  </head>
  <body>
    <div>
      <!-- 头部区域 -->
      <header class="header">后台管理系统</header>
      <!-- 中间主体区域 -->
      <div class="main">
        <!-- 左侧菜单栏 -->
        <div class="content left">
          <ul>
            <li>用户管理</li>
            <li>权限管理</li>
            <li>商品管理</li>
            <li>订单管理</li>
            <li>系统设置</li>
          </ul>
        </div>
        <!-- 右侧内容区域 -->
        <div class="content right"><div class="main-content">添加用户表单</div></div>
      </div>
      <!-- 尾部区域 -->
      <footer class="footer">版权信息</footer>
    </div>
  </body>
</html>

7.2.在页面中引入vue,vue-router

<script src="../js/vue.js"></script>
<script src="../js/vue-router.js"></script>

7.3.创建Vue实例对象,准备开始编写代码实现功能

const vm = new Vue({
        el: '#app',
        router
      })

7.4.定义根组件

  • 希望是通过组件的形式展示页面的主体内容,而不是写死页面结构,所以我们可以定义一个根组件:
//只需要把原本页面中的html代码设置为组件中的模板内容即可
const app = {
    template:`<div>
        <!-- 头部区域 -->
        <header class="header">传智后台管理系统</header>
        <!-- 中间主体区域 -->
        <div class="main">
          <!-- 左侧菜单栏 -->
          <div class="content left">
            <ul>
              <li>用户管理</li>
              <li>权限管理</li>
              <li>商品管理</li>
              <li>订单管理</li>
              <li>系统设置</li>
            </ul>
          </div>
          <!-- 右侧内容区域 -->
          <div class="content right">
            <div class="main-content">添加用户表单</div>
          </div>
        </div>
        <!-- 尾部区域 -->
        <footer class="footer">版权信息</footer>
      </div>`
  }

7.5.创建路由对象

  • 当我们访问页面的时候,默认需要展示刚刚创建的app根组件,我们可以创建一个路由对象来完成这个事情,然后将路由挂载到Vue实例对象中即可
const myRouter = new VueRouter({
    routes:[
        {path:"/",component:app}
    ]
})

const vm = new Vue({
    el:"#app",
    data:{},
    methods:{},
    router:myRouter
})

7.6.设置路由占位符

  • 补充:到此为止,基本的js代码都处理完毕了,我们还需要设置一个路由占位符
<body>
  <div id="app">
    <router-view></router-view>
  </div>
</body>

7.7.设置嵌套路由

  • 此时我们打开页面应该就可以得到一个VueRouter路由出来的根组件了
  • 我们需要在这个根组件中继续路由实现其他的功能子组件
  • 先让我们更改根组件中的模板:更改左侧li为子级路由链接,并在右侧内容区域添加子级组件占位符
const app = {
    template:`<div>
        ........
        <div class="main">
          <!-- 左侧菜单栏 -->
          <div class="content left">
            <ul>
              <!-- 注意:我们把所有li都修改为子路由链接 -->
              <li><router-link to="/users">用户管理</router-link></li>
              <li><router-link to="/accesses">权限管理</router-link></li>
              <li><router-link to="/goods">商品管理</router-link></li>
              <li><router-link to="/orders">订单管理</router-link></li>
              <li><router-link to="/systems">系统设置</router-link></li>
            </ul>
          </div>
          <!-- 右侧内容区域 -->
          <div class="content right">
            <div class="main-content">
                <!-- 在 -->
                <router-view></router-view> 
            </div>
          </div>
        </div>
        .......
      </div>`
  }

7.8.设置嵌套路由的子组件

  • 然后,我们要为子级路由创建并设置需要显示的子级组件
//建议创建的组件首字母大写,和其他内容区分
const Users = {template:`<div>
    <h3>用户管理</h3>
</div>`}
const Access = {template:`<div>
    <h3>权限管理</h3>
</div>`}
const Goods = {template:`<div>
    <h3>商品管理</h3>
</div>`}
const Orders = {template:`<div>
    <h3>订单管理</h3>
</div>`}
const Systems = {template:`<div>
    <h3>系统管理</h3>
</div>`}

//添加子组件的路由规则
const myRouter = new VueRouter({
    routes:[
        {path:"/",component:app , children:[
            { path:"/users",component:Users },
            { path:"/accesses",component:Access },
            { path:"/goods",component:Goods },
            { path:"/orders",component:Orders },
            { path:"/systems",component:Systems },
        ]}
    ]
})

const vm = new Vue({
    el:"#app",
    data:{},
    methods:{},
    router:myRouter
})

7.9.展示用户信息列表

  • 为Users组件添加私有数据,并在模板中循环展示私有数
const Users = {
    data(){
        return {
            userList:[
                {id:1,name:"zs",age:18},
                {id:2,name:"ls",age:19},
                {id:3,name:"wang",age:20},
                {id:4,name:"jack",age:21},
            ]
        }
    },
   template:`<div>
        <h3>用户管理区域</h3>
        <table>
          <thead>
            <tr><th>编号</th><th>姓名</th><th>年龄</th><th>操作</th></tr>
          </thead>
          <tbody>
            <tr v-for="item in userlist" :key="item.id">
              <td>{{item.id}}</td>
              <td>{{item.name}}</td>
              <td>{{item.age}}</td>
              <td>
                <a href="javascript:;" @click="goDetail(item.id)">详情</a>
              </td>
            </tr>
          </tbody>
        </table>
      </div>`
      }

7.10.设置详情

  • 当用户列表展示完毕之后,我们可以点击列表中的详情来显示用户详情信息,首先我们需要创建一个组件,用来展示详情信息
const UserInfo = {
    props:["id"],
    template:`<div>
      <h5>用户详情</h5>
      <p>查看 {{id}} 号用户信息</p>
      <button @click="goBack">返回用户详情页</button>
    </div> `,
    methods:{
      goBack(){
        //当用户点击按钮,后退一页
        this.$router.go(-1);
      }
    }
  }
  • 然后我们需要设置这个组件的路由规则
const myRouter = new VueRouter({
    routes:[
        {path:"/",component:app , children:[
            { path:"/users",component:Users },
            //添加一个/userinfo的路由规则
            { path:"/userinfo/:id",component:UserInfo,props:true},
            { path:"/accesses",component:Access },
            { path:"/goods",component:Goods },
            { path:"/orders",component:Orders },
            { path:"/systems",component:Systems },
        ]}
    ]
})

const vm = new Vue({
    el:"#app",
    data:{},
    methods:{},
    router:myRouter
})
  • 再接着给用户列表中的详情a连接添加事件
const Users = {
    data(){
        return {
            userList:[
                {id:1,name:"zs",age:18},
                {id:2,name:"ls",age:19},
                {id:3,name:"wang",age:20},
                {id:4,name:"jack",age:21},
            ]
        }
    },
    template:`<div>
        <h3>用户管理</h3>
        <table>
            <thead>
                <tr>
                    <th>编号</th>
                    <th>姓名</th>
                    <th>年龄</th>
                    <th>操作</th>
                </tr>
            </thead>
            <tbody>
                <tr :key="item.id" v-for="item in userList">
                    <td>{{item.id}}</td>
                    <td>{{item.name}}</td>
                    <td>{{item.age}}</td>
                    <td><a href="javascript:;" @click="goDetail(item.id)">详情</a></td>
                </tr>
            </tbody>
        </table>
    </div>`,
    methods:{
        goDetail(id){
            this.$router.push("/userinfo/"+id);
        }
    }
}

7.11.综合代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>基于vue-router的案例</title>
    <style type="text/css">
      html,
      body,
      #app {
        margin: 0;
        padding: 0px;
        height: 100%;
      }
      .header {
        height: 50px;
        background-color: #545c64;
        line-height: 50px;
        text-align: center;
        font-size: 24px;
        color: #fff;
      }
      .footer {
        height: 40px;
        line-height: 40px;
        background-color: #888;
        position: absolute;
        bottom: 0;
        width: 100%;
        text-align: center;
        color: #fff;
      }
      .main {
        display: flex;
        position: absolute;
        top: 50px;
        bottom: 40px;
        width: 100%;
      }
      .content {
        flex: 1;
        text-align: center;
        height: 100%;
      }
      .left {
        flex: 0 0 20%;
        background-color: #545c64;
      }
      .left a {
        color: white;
        text-decoration: none;
      }
      .right {
        margin: 5px;
      }
      .btns {
        width: 100%;
        height: 35px;
        line-height: 35px;
        background-color: #f5f5f5;
        text-align: left;
        padding-left: 10px;
        box-sizing: border-box;
      }
      button {
        height: 30px;
        background-color: #ecf5ff;
        border: 1px solid lightskyblue;
        font-size: 12px;
        padding: 0 20px;
      }
      .main-content {
        margin-top: 10px;
      }
      ul {
        margin: 0;
        padding: 0;
        list-style: none;
      }
      ul li {
        height: 45px;
        line-height: 45px;
        background-color: #a0a0a0;
        color: #fff;
        cursor: pointer;
        border-bottom: 1px solid #fff;
      }

      table {
        width: 100%;
        border-collapse: collapse;
      }

      td,
      th {
        border: 1px solid #eee;
        line-height: 35px;
        font-size: 12px;
      }

      th {
        background-color: #ddd;
      }
    </style>
    <script src="../js/vue.js"></script>
    <script src="../js/vue-router.js"></script>
  </head>
  <body>
    <!-- 要被 vue 实例所控制的区域 -->
    <div id="app">
      <!-- 路由占位符 -->
      <router-view></router-view>
    </div>

    <script>
      // 定义 APP 根组件
      const App = {
        template: `<div>
          <!-- 头部区域 -->
          <header class="header">后台管理系统</header>
          <!-- 中间主体区域 -->
          <div class="main">
            <!-- 左侧菜单栏 -->
            <div class="content left">
              <ul>
              	 <!-- 子路由链接 -->
                <li><router-link to="/users">用户管理</router-link></li>
                <li><router-link to="/rights">权限管理</router-link></li>
                <li><router-link to="/goods">商品管理</router-link></li>
                <li><router-link to="/orders">订单管理</router-link></li>
                <li><router-link to="/settings">系统设置</router-link></li>
              </ul>
            </div>
            <!-- 右侧内容区域 -->
            <div class="content right"><div class="main-content">
            <!-- 子路由组件将会在router-view中显示 -->
        		<router-view></router-view>
            </div>
          </div>
          <!-- 尾部区域 -->
          <footer class="footer">版权信息</footer>
        </div>`
      }

      const Users = {
        data() {
          return {
            userlist: [
              { id: 1, name: '张三', age: 10 },
              { id: 2, name: '李四', age: 20 },
              { id: 3, name: '王五', age: 30 },
              { id: 4, name: '赵六', age: 40 }
            ]
          }
        },
        methods: {
          goDetail(id) {
            console.log(id)
            this.$router.push('/userinfo/' + id)
          }
        },
        template: `<div>
        <h3>用户管理区域</h3>
        <table>
          <thead>
            <tr><th>编号</th><th>姓名</th><th>年龄</th><th>操作</th></tr>
          </thead>
          <tbody>
            <tr v-for="item in userlist" :key="item.id">
              <td>{{item.id}}</td>
              <td>{{item.name}}</td>
              <td>{{item.age}}</td>
              <td>
                <a href="javascript:;" @click="goDetail(item.id)">详情</a>
              </td>
            </tr>
          </tbody>
        </table>
      </div>`
      }

      const UserInfo = {
        props: ['id'],
        template: `<div>
          <h5>用户详情页 --- 用户Id为:{{id}}</h5>
          <button @click="goback()">后退</button>
        </div>`,
        methods: {
          goback() {
            // 实现后退功能
            this.$router.go(-1)
          }
        }
      }

      const Rights = {
        template: `<div>
        <h3>权限管理区域</h3>
      </div>`
      }
      const Goods = {
        template: `<div>
        <h3>商品管理区域</h3>
      </div>`
      }
      const Orders = {
        template: `<div>
        <h3>订单管理区域</h3>
      </div>`
      }
      const Settings = {
        template: `<div>
        <h3>系统设置区域</h3>
      </div>`
      }

      // 创建路由对象
      const router = new VueRouter({
        routes: [
          {
            path: '/',
            component: App,
            redirect: '/users',
            children: [
              { path: '/users', component: Users },
              { path: '/userinfo/:id', component: UserInfo, props: true },
              { path: '/rights', component: Rights },
              { path: '/goods', component: Goods },
              { path: '/orders', component: Orders },
              { path: '/settings', component: Settings }
            ]
          }
        ]
      })

      const vm = new Vue({
        el: '#app',
        router
      })
    </script>
  </body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

彤彤的小跟班

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值