前端学习--Vue部分下

前端学习–Vue部分下

1.路由

1.1路由简介

vue-router是vue中的插件库,用来实现SPA(单页面)应用。在前端部分中我们可以简单的把路由理解为根据你的路径,由我来展示对应的组件

补充:后端路由可以简单理解为,根据请求路径找到匹配的函数来处理请求,并返回响应数据。

1.2 SPA应用

单页面web应用(single page web application)的数据需要通过ajax请求获取,整个应用只有一个完整的页面。我们点击页面中的导航链接时,整个页面不会被刷新只会做页面的局部更新。

1.3路由的基本使用

  1. 安装vue-router,命令:npm i vue-router@3

    注:vue-router3vue2中使用,vue-router4在vue3中使用。

  2. 应用插件:Vue.use(VueRouter)

  3. 编写router配置项:

    //引入VueRouter
    import VueRouter from 'vue-router'
    //引入路由组件
    import About from '../components/About'
    import Home from '../components/Home'
    //创建router实例对象,去管理一组一组的路由规则
    const router = new VueRouter({
        routes:[
            {
                path:'/about',
                component:About
            },
            {
                path:'/home',
                component:Home
            }
        ]
    })
    
    //暴露router
    export default router
    
  4. 实现切换(active-class可配置高亮样式)

    <router-link active-class="active" to="/about">About</router-link>
    
  5. 指定展示位置

    <router-view></router-view>
    

1.4注意事项

  1. 路由组件通常存放在pages文件夹,一般组件通常存放在components文件夹。

  2. 切换路由组件时,默认是该组件被销毁掉,需要的时候再去挂载。

  3. 每个组件都有属于自己独一无二的$route属性,里面存储着自己的路由信息。

  4. 整个应用只有一个router,可以通过组件的$router属性获取到。

2.嵌套路由

  1. 配置路由规则,使用children配置项:

    routes:[
        {
            path:'/about',
            component:About,
        },
        {
            path:'/home',
            component:Home,
            children:[ //通过children配置子级路由
                {
                    path:'news', //此处一定不要写:/news
                    component:News
                },
                {
                    path:'message',//此处一定不要写:/message
                    component:Message
                }
            ]
        }
    ]
    
    
  2. 跳转(要写完整路径):

    <router-link to="/home/news">News</router-link>
    

3.路由的query参数

  1. 传递参数

    <!-- 跳转并携带query参数,to的字符串写法 -->
    <router-link :to="/home/message/detail?id=666&title=你好">跳转</router-link>
    <!--用模板字符串解析-->
    <!-- <router-link :to="`/home/Message/detail?id=${m.id}&title=${m.title}`">{{m.title}}</router-link>&nbsp;&nbsp; -->    
    
    <!-- 跳转并携带query参数,to的对象写法 -->
    <router-link 
        :to="{
            path:'/home/message/detail',
            query:{
               id:666,
                title:'你好'
            }
        }"
    >跳转</router-link>
    
  2. 接收参数:

    $route.query.id
    $route.query.title
    

4.命名路由

它的主要作用是简化二级以上的路由跳转。一级也可以使用,不过麻烦。使用方法如下:

{
    path:'/demo',
    component:Demo,
    children:[
        {
            path:'test',
            component:Test,
            children:[
                {
                    name:'hello' //给路由命名
                    path:'welcome',
                    component:Hello,
                }
            ]
        }
    ]
}
<!--简化前,需要写完整的路径 -->
<router-link to="/demo/test/welcome">跳转</router-link>
<!--简化后,直接通过名字跳转 -->
<router-link :to="{name:'hello'}">跳转</router-link>
<!--简化写法配合传递参数 -->
<router-link 
    :to="{
        name:'hello',
        query:{
           id:666,
            title:'你好'
        }
    }"
>跳转</router-link>

5.路由的params参数

  1. 配置路由,声明接收params参数

    {
        path:'/home',
        component:Home,
        children:[
            {
                path:'news',
                component:News
            },
            {
                component:Message,
                children:[
                    {
                        name:'xiangqing',
                        path:'detail/:id/:title', //使用占位符声明接收params参数
                        component:Detail
                    }
                ]
            }
        ]
    }
    
  2. 传递参数

    <!-- 跳转并携带params参数,to的字符串写法 -->
    <router-link :to="/home/message/detail/666/你好">跳转</router-link>
    <router-link :to="`/home/Message/detail/${m.id}/${m.title}`">{{ m.title}}</router-link>             
    <!-- 跳转并携带params参数,to的对象写法 -->
    <router-link 
        :to="{
            name:'xiangqing',
            params:{
               id:666,
                title:'你好'
            }
        }"
    
    >跳转</router-link>
    

    特别注意:路由携带params参数时,若使用to的对象写法,则不能使用path配置项,必须使用name配置!

  3. 接收参数:

    $route.params.id
    $route.params.title
    

6.路由的props配置

作用:让路由组件更方便的收到参数。

详细代码见下方案例。

7.<router-link>的replace属性

  1. 作用:控制路由跳转时操作浏览器历史记录的模式

  2. 浏览器的历史记录有两种写入方式:分别为push和replace,push是追加历史记录(可后退,有痕迹),replace是替换当前记录(不可后退,没有痕迹)。路由跳转时候默认为push。

  3. 如何开启replace模式:

    <router-link replace .......>News</router-link>

8.编程式路由导航

作用:不借助<router-link>实现路由跳转,让路由跳转更加灵活。

注:很多方法在VueRouter构造函数的__proto__里面。

//$router的两个API
this.$router.push({
    name:'xiangqing',
        params:{
            id:xxx,
            title:xxx
        }
})

this.$router.replace({
    name:'xiangqing',
        params:{
            id:xxx,
            title:xxx
        }
})
this.$router.forward() //前进
this.$router.back() //后退
this.$router.go() //可前进也可后退,里面的参数是正的时候就是前进的步数,负就是后退的

详细代码见下方案例。

9.缓存路由组件

作用:让不展示的路由组件保持挂载,不被摧毁。

 <!-- 缓存一个路由组件 -->
    <!-- include里面的是组件名 -->
    <keep-alive include="News">
      <router-view></router-view>
    </keep-alive>
    <!-- 缓存多个路由组件 -->
    <!-- <keep-alive include="['News','Message']"> -->

详细代码见下方案例。

10.两个新生命周期钩子

作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态。

  1. activated:路由组件被激活时触发。
  2. deactivated:路由组件被失活时触发。

详细代码见下方案例。

11.全局路由守卫

分为前置路由守卫和后置路由守卫。

在这里插入图片描述

详细代码见下方案例。

12.独享路由守卫

注:它可以搭配全局后置守卫使用。

beforeEnter(to, from, next) {
                console.log('独享路由守卫', to, from)
                // 判断是否需要鉴权
                if (to.meta.isAuth) {
                    if (localStorage.getItem('school') === 'atguigu') {
                        next()
                    } else {
                        alert('学校名不对,无权限查看!')
                    }
                } else {
                    next()
                }
            }

详细代码见下方案例。

13.组件内路由守卫

注:顾名思义写在组件中,它可同样以搭配后置守卫使用。

//进入该组件时被调用
beforeRouteEnter(to,from,next){...},
//离开该组件时被调用
beforeRouteLeave(to,from,next){...},

详细代码见下方案例。

14. 路由的两种工作模式

两种工作模式分别是hash模式和history模式,链接中井号后面的地址不想传给服务器,便作为hash值的存在。

14.1简介

  1. 对于一个url来说,什么是hash值?—— #及其后面的内容就是hash值

  2. hash值不会包含在 HTTP 请求中,即:hash值不会带给服务器

  3. hash模式:

    1. 地址中永远带着#号,不美观
    2. 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法。
    3. 兼容性较好。
  4. history模式:

    1. 地址干净,美观
    2. 兼容性和hash模式相比略差
    3. 应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题
// router文件夹下的index.js文件
const router = new VueRouter({
    mode: 'hash', // 设置模式 更改模式需要重新部署
    routes: [{
        name: 'about',
        path: '/about',
        component: About,
        meta: { isAuth: true, title: '关于' },
    },
......

14.2具体操作

  1. 打包文件:把我们所写的vue文件,通过在vs终端中输入npm run build语句进行打包,生成html文件、css文件、js文件放在dist文件夹下。
  2. 部署:把生成的文件部署到服务器上,这里需要了解一下nodejs或者查看一下我写的Ajax笔记。
    • 在页面随意建一个新的文件夹(这里名为demo),用vs打开这个文件夹。

    • 在vs终端中输入npm init变为合法包。

    • 紧接着在vs终端输入package name给包取个名字。

    • 然后输入npm i express安装express框架。

    • 新建server.js文件,代码见下方。

    • 新建static文件夹,把build生成的文件放在该文件夹。

    • 最后在vs终端输入node server运行服务器(运行server.js文件)。

  3. 解决history模式404问题:很多时候我们需要用history模式。
    • 在vs终端上输入npm i connect-history-api-fallback,下载nodejs中间件。
    • 重新部署:需要重新build生成文件放入static文件夹中,之后配置server.js文件(代码见下方),重新运行服务器完成重新部署。
// server.js文件
//引入express框架
const express = require('express');
//引用中间件,解决history404问题
const history = require('connect-history-api-fallback');
//创建网站服务器
const app = express();
//使用中间件(这句话一定要写在指定静态资源的前面)
app.use(history())
//指定静态资源的绝对路径
app.use(express.static(__dirname+'/static'))

app.get('/server', (request, response) => {
  //设置响应头,设置允许跨域
  response.setHeader('Access-Control-Allow-Origin', '*');
  // 设置响应体
  response.send({
      name:'tom',
      age:18
  });
});
//监听端口
app.listen(8000, (err) => {
  if(!err) console.log("服务已经启动,8000端口监听中。。。")
})

15.Vue UI组件库

15.1 常用UI组件库

15.1.1 移动端常用UI组件库
  1. Vant
  2. Cube UI
  3. Mint UI
15.1.2 PC端常用UI组件库
  1. Element UI
  2. IView UI

15.2 element-ui的使用

安装 element-uinpm i element-ui

想要按需引入element-ui,还需要安装babel-plugin-component在vs终端输入npm install babel-plugin-component -D

15.3实际操作代码

// babel.config.js文件
module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset',
    // 不要写es2015 如果报错他说缺少什么安装什么
    ["@babel/preset-env", { "modules": false }]
  ],
  plugins: [
    [
      "component",
      {
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ]
  ]
}
// main.js文件
import Vue from 'vue'
import App from './App.vue'
// 这种写法并不完美,体积过大
//引入ElementUI组件库
// import ElementUI from 'element-ui';
//引入ElementUtI全部样式
// import 'element-ui/lib/theme-chalk/index.css';

//按需引入
import { Button, Row } from 'element-ui'

Vue.config.productionTip = false
//使用ElementUI
// Vue.use(ElementUI)

// 使用按需引入的ElementUI
// Vue.component(Button.name, Button);
// Vue.component(Row.name, Row);
// 也可以写为以下形式
Vue.use(Button)
Vue.use(Row)

new Vue({
	el: "#app",
	render: h => h(App),
})
<!-- App.vue文件 -->
<template> 
  <div>
    <br />
    <el-row>
      <el-button icon="el-icon-search" circle></el-button>
      <el-button type="primary" icon="el-icon-edit" circle></el-button>
      <el-button type="success" icon="el-icon-check" circle></el-button>
      <el-button type="info" icon="el-icon-message" circle></el-button>
      <el-button type="warning" icon="el-icon-star-off" circle></el-button>
      <el-button type="danger" icon="el-icon-delete" circle></el-button>
    </el-row>
  </div>
</template>

<script>
export default {
  name: "App",
};
</script>

案例

基本路由和嵌套路由(多级路由)

<!-- index.html文件 -->
<!-- 引入bootstrap -->
<link rel="stylesheet" href="<%= BASE_URL %>css/bootstrap.css">
// main.js文件
//引入Vue 
import Vue from 'vue'
//引入App
import App from './App.vue'
//引入VueRouter
import VueRouter from 'vue-router'
//引入路由器
import router from './router'

//关闭Vue的生产提示
Vue.config.productionTip = false
//应用插件
Vue.use(VueRouter)

//创建vm
new Vue({
el: '#app',
render: h => h(App),
router: router
})
// router文件夹下的index.js文件
// 该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
//引入组件
import About from '../pages/About'
import Home from '../pages/Home'

import News from '../pages/News'
import Message from '../pages/Message'

//创建并暴露一个路由器
export default new VueRouter({
routes: [
  {
      path: '/about',
      component: About
  },
  {
      path: '/home',
      component: Home,
      children: [
          {
              // 在这里的path就不要再加斜杠了
              path: 'news',
              component: News,
          },
          {
              path: 'message',
              component: Message
          }
      ]
  }
]
})
<!-- App.vue文件 -->
<template>
<div>
<Banner />
<div class="row">
<div class="col-xs-2 col-xs-offset-2">
  <div class="list-group">
    <!-- 原始html中我们使用a标签实现页面的跳转 -->
    <!-- <a class="list-group-item active" href="./about.html">About</a> -->
    <!-- <a class="list-group-item" href="./home.html">Home</a> -->

    <!-- Vue中借助router-link标签实现路由的切换 -->
    <!-- router-link标签就相当于原先的a标签 -->
    <router-link class="list-group-item" active-class="active" to="/about"
      >About</router-link
    >
    <router-link class="list-group-item" active-class="active" to="/home"
      >Home</router-link
    >
  </div>
</div>
<div class="col-xs-6">
  <div class="panel">
    <div class="panel-body">
      <!-- 指定组件的呈现位置 -->
      <router-view></router-view>
    </div>
  </div>
</div>
</div>
</div>
</template>

<script>
import Banner from "./components/Banner.vue";

export default {
name: "App",
components: { Banner },
};
</script>

<style>
.active {
background-color: yellow;
}
</style>

注:下面是路由组件放在pages文件夹下。

<!-- About.vue文件 -->
<template>
<h2>我是About的内容</h2>
</template>

<script>
export default {
name: "About",
};
</script>

<style>
</style>
<!-- Home.vue文件 -->
<template>
<div>
<h2>我是Home的内容</h2>
<ul class="nav nav-tabs">
<li>
  <!-- 跳转时要带着父级路径 -->
  <router-link
    class="list-group-item"
    active-class="active"
    to="/home/news"
    >News</router-link
  >
</li>
<li>
  <router-link
    class="list-group-item"
    active-class="active"
    to="/home/message"
    >Message</router-link
  >
</li>
</ul>
<router-view></router-view>
</div>
</template>

<script>
export default {
name: "Home",
};
</script>

<style>
</style>
<!-- News.vue文件 -->
<template>
<ul>
<li>news001</li>
<li>news002</li>
<li>news003</li>
</ul>
</template>

<script>
export default {};
</script>

<style>
</style>
<!-- Message.vue文件 -->
<template>
<ul>
<li><a href="/message1">message001</a>&nbsp;&nbsp;</li>
<li><a href="/message2">message002</a>&nbsp;&nbsp;</li>
<li><a href="/message/3">message003</a>&nbsp;&nbsp;</li>
</ul>
</template>

<script>
export default {};
</script>

<style>
</style>

路由的query参数与命名路由

// router文件夹下的index.js文件
// 该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
//引入组件
import About from '../pages/About'
import Home from '../pages/Home'

import News from '../pages/News'
import Message from '../pages/Message'

import Detail from '../pages/Detail'

//创建并暴露一个路由器
export default new VueRouter({
 routes: [
     {

         path: '/about',
         component: About
     },
     {
         path: '/home',
         component: Home,
         children: [
             {
                 path: 'news',
                 component: News,
             },
             {
                 path: 'message',
                 component: Message,
                 children: [
                     {
                         name: 'detail', //路由命名,简化路由命名
                         path: 'detail',
                         component: Detail
                     }]
             }
         ]
     }
 ]
})
<!-- App.vue文件 -->
<template>
<div>
 <Banner />
 <div class="row">
   <div class="col-xs-2 col-xs-offset-2">
     <div class="list-group">
       <!-- 原始html中我们使用a标签实现页面的跳转 -->
       <!-- <a class="list-group-item active" href="./about.html">About</a> -->
       <!-- <a class="list-group-item" href="./home.html">Home</a> -->

       <!-- Vue中借助router-link标签实现路由的切换 -->
       <router-link class="list-group-item" active-class="active" to="/about"
         >About</router-link
       >
       <router-link class="list-group-item" active-class="active" to="/home"
         >Home</router-link
       >
     </div>
   </div>
   <div class="col-xs-6">
     <div class="panel">
       <div class="panel-body">
         <!-- 指定组件的呈现位置 -->
         <router-view></router-view>
       </div>
     </div>
   </div>
 </div>
</div>
</template>

<script>
import Banner from "./components/Banner.vue";
export default {
name: "App",
components: { Banner },
};
</script>
<!-- Home.vue文件 -->
<template>
<div>
 <h2>我是Home的内容</h2>
 <ul class="nav nav-tabs">
   <li>
     <router-link
       class="list-group-item"
       active-class="active"
       to="/home/news"
       >News</router-link
     >
   </li>
   <li>
     <router-link
       class="list-group-item"
       active-class="active"
       to="/home/message"
       >Message</router-link
     >
   </li>
 </ul>
 <router-view></router-view>
</div>
</template>

<script>
export default {
name: "Home",
};
</script>

<style>
</style>
<!-- Message.vue文件 -->
<template>
<div>
 <ul>
   <li v-for="m in MessageList" :key="m.id">
     <!-- 跳转路由由并携带query参数,to的模板字符串写法 -->
     <!-- <router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`">{{m.title}}</router-link>&nbsp;&nbsp; -->

     <!-- 跳转路由由并携带query参数,to的对象写法 -->
     <router-link
       :to="{
         // path:'/home/message/detail',
         // 路由起名之后就可以path简写为name
         name: 'detail',
         query: {
           id: m.id,
           title: m.title,
         },
       }"
     >
       {{ m.title }}
     </router-link>
   </li>
 </ul>
 <hr />
 <router-view></router-view>
</div>
</template>

<script>
export default {
name: "Message",
data() {
 return {
   MessageList: [
     { id: "001", title: "消息001" },
     { id: "002", title: "消息002" },
     { id: "003", title: "消息003" },
   ],
 };
},
};
</script>

<style>
</style>
<!-- Detail.vue文件 -->
<template>
<div>
 <li>消息编号:{{ $route.query.id }}</li>
 <li>消息标题:{{ $route.query.title }}</li>
</div>
</template>

<script>
export default {
name: "Detail",
};
</script>

<style>
</style>

路由的params参数

// index.js文件
// 该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
//引入组件
import About from '../pages/About'
import Home from '../pages/Home'

import News from '../pages/News'
import Message from '../pages/Message'

import Detail from '../pages/Detail'

//创建并暴露一个路由器
export default new VueRouter({
 routes: [{

     path: '/about',
     component: About
 },
 {
     path: '/home',
     component: Home,
     children: [{
         path: 'news',
         component: News,
     },
     {
         path: 'message',
         component: Message,
         children: [{
             name: 'detail', //路由命名,简化路由命名
             path: 'detail/:id:title', //占位符
             component: Detail
         }]
     }
     ]
 }
 ]
})
<!-- Message.vue文件 -->
<template>
<div>
 <ul>
   <li v-for="m in MessageList" :key="m.id">
     <!-- 跳转路由由并携带params参数,to的字符串写法 -->
     <router-link :to="`/home/message/detail/${m.id}/${m.title}`">{{
       m.title
     }}</router-link>

     <!-- 跳转路由由并携带params参数,to的对象写法,必须与路由命名使用,使用path会报错 -->
     <!-- <router-link :to="{
       name:'detail',
       params:{
         id:m.id,
         title:m.title
       }
      }">
      {{m.title}}
      </router-link> -->
   </li>
 </ul>
 <hr />
 <router-view></router-view>
</div>
</template>

<script>
export default {
name: "Message",
data() {
 return {
   MessageList: [
     { id: "001", title: "消息001" },
     { id: "002", title: "消息002" },
     { id: "003", title: "消息003" },
   ],
 };
},
};
</script>

<style>
</style>

路由的props配置

// index.js文件
// 该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
//引入组件
import About from '../pages/About'
import Home from '../pages/Home'

import News from '../pages/News'
import Message from '../pages/Message'

import Detail from '../pages/Detail'

//创建并暴露一个路由器
export default new VueRouter({
 routes: [
     {

         path: '/about',
         component: About
     },
     {
         path: '/home',
         component: Home,
         children: [
             {
                 path: 'news',
                 component: News,
             },
             {
                 path: 'message',
                 component: Message,
                 children: [
                     {
                         name: 'detail', //路由命名,简化路由命名
                         path: 'detail',
                         component: Detail,
                         //对象写法,将对象中的所有key-value都会以props的形式传给Detail组件(数据是写死的,不推荐使用)
                         // props: { a: 1, b: 'hello' }

                         //布尔值写法 布尔值为真则将会将路由组件收到的所有props传给Detail组件(只能是params)
                         // props: true

                         //函数写法(只能是query写法)
                         props($route) {
                             return { id: $route.query.id, title: $route.query.title }
                         }
                     }]
             }
         ]
     }
 ]
})
<!-- detail.vue文件 -->
<template>
<div>
 <li>消息编号:{{ id }}</li>
 <li>消息标题:{{ title }}</li>
</div>
</template>

<script>
export default {
name: "Detail",
props: ["id", "title"],
};
</script>

<style>
</style>

注:此部分Message.vue文件,只是为了代码完整性,内容之前已经学过。

<!-- Message.vue文件 -->
<template>
<div>
 <ul>
   <li v-for="m in MessageList" :key="m.id">
     <!-- 跳转路由由并携带params参数,to的字符串写法 -->
     <!-- <router-link :to="`/home/message/detail/${m.id}/${m.title}`">{{m.title}}</router-link> -->

     <!-- 跳转路由由并携带params参数,to的对象写法,必须与路由命名使用,使用path会报错 -->
     <router-link
       :to="{
         name: 'detail',
         query: {
           id: m.id,
           title: m.title,
         },
       }"
     >
       {{ m.title }}
     </router-link>
   </li>
 </ul>
 <hr />
 <router-view></router-view>
</div>
</template>

<script>
export default {
name: "Message",
data() {
 return {
   MessageList: [
     { id: "001", title: "消息001" },
     { id: "002", title: "消息002" },
     { id: "003", title: "消息003" },
   ],
 };
},
};
</script>

<style>
</style>

编程式路由导航

<!-- message.vue文件 -->
<template>
<div>
 <ul>
   <li v-for="m in MessageList" :key="m.id">
     <!-- 跳转路由由并携带params参数,to的对象写法,必须与路由命名使用,使用path会报错 -->
     <router-link
       :to="{
         name: 'detail',
         query: {
           id: m.id,
           title: m.title,
         },
       }"
       >{{ m.title }}</router-link
     >
     <!-- 不借助 router-link 实现路由跳转,让路由跳转更灵活 -->
     <!-- 注:按同一按钮两次会报重复请求的错误 -->
     <button @click="pushShow(m)">push查看</button>
     <button @click="replaceShow(m)">replace查看</button>
   </li>
 </ul>
 <hr />
 <router-view></router-view>
</div>
</template>

<script>
export default {
name: "Message",
data() {
 return {
   MessageList: [
     { id: "001", title: "消息001" },
     { id: "002", title: "消息002" },
     { id: "003", title: "消息003" },
   ],
 };
},
methods: {
 pushShow(m) {
   this.$router.push({
     name: "detail",
     query: {
       id: m.id,
       title: m.title,
     },
   });
 },
 replaceShow(m) {
   this.$router.replace({
     name: "detail",
     query: {
       id: m.id,
       title: m.title,
     },
   });
 },
},
};
</script>

<style scoped>
button {
margin: 5px;
}
</style>
<!-- components文件夹下的banner.vue文件 -->
<template>
<div class="row">
 <div class="col-xs-offset-2 col-xs-8">
   <div class="page-header"><h2>Vue Router Demo</h2></div>
   <button @click="back">前进</button>
   <button @click="forward">后退</button>
   <button @click="test">测试一下go</button>
 </div>
</div>
</template>

<script>
export default {
name: "Banner",
methods: {
 back() {
   this.$router.back();
 },
 forward() {
   this.$router.back();
 },
 test() {
   // 前进三步,如果参数是负数就是倒退
   this.$router.go(3);
 },
},
};
</script>

<style scoped>
button {
margin: 5px;
}
</style><!-- components文件夹下的banner.vue文件 -->
<template>
<div class="row">
 <div class="col-xs-offset-2 col-xs-8">
   <div class="page-header"><h2>Vue Router Demo</h2></div>
   <button @click="back">前进</button>
   <button @click="forward">后退</button>
   <button @click="test">测试一下go</button>
 </div>
</div>
</template>

<script>
export default {
name: "Banner",
methods: {
 back() {
   this.$router.back();
 },
 forward() {
   this.$router.back();
 },
 test() {
   // 前进三步,如果参数是负数就是倒退
   this.$router.go(3);
 },
},
};
</script>

<style scoped>
button {
margin: 5px;
}
</style>

缓存路由组件和新生命周期钩子

<!-- Home.vue文件 -->
<template>
<div>
 <h2>我是Home的内容</h2>
 <ul class="nav nav-tabs">
   <li>
     <router-link
       class="list-group-item"
       active-class="active"
       to="/home/news"
       >News
     </router-link>
   </li>
   <li>
     <router-link
       class="list-group-item"
       active-class="active"
       to="/home/message"
       >Message
     </router-link>
   </li>
 </ul>
 <!-- 缓存一个路由组件 -->
 <!-- include里面的是组件名 -->
 <keep-alive include="News">
   <router-view></router-view>
 </keep-alive>
 <!-- 缓存多个路由组件 -->
 <!-- <keep-alive include="['News','Message']"> -->
</div>
</template>

<script>
export default {
name: "Home",
};
</script>

<style>
</style>
<!-- News.vue组件 -->
<template>
<ul>
 <li>news001 <input type="text" /></li>
 <li>news002 <input type="text" /></li>
 <li>news003 <input type="text" /></li>
</ul>
</template>

<script>
export default {
name: "News",
// 路由组件缓存 两个新的生命周期钩子
activated() {
 console.log("激活");
},
deactivated() {
 console.log("失活");
},
};
</script>

<style>
</style>

全局路由守卫

// router文件夹下的index.js文件
// 该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
//引入组件
import About from '../pages/About'
import Home from '../pages/Home'

import News from '../pages/News'
import Message from '../pages/Message'

import Detail from '../pages/Detail'

//这里必须这样写,为了路由守卫可以发挥作用
const router = new VueRouter({
    routes: [{
        name: 'about',
        path: '/about',
        component: About,
        meta: { title: '关于' },
    },
    {
        name: 'home',
        path: '/home',
        component: Home,
        meta: { title: '主页' },
        children: [{
            name: 'news',
            path: 'news',
            component: News,
            // meta属性放程序员自定义内容
            meta: { isAuth: true, title: '新闻' }, // 是否授权
        },
        {
            name: 'message',
            path: 'message',
            component: Message,
            meta: { isAuth: true, title: '信息' }, // 是否授权
            children: [{
                name: 'detail', //路由命名,简化路由命名
                path: 'detail',
                component: Detail,
                //函数写法(只能是query写法)
                props($route) {
                    return { id: $route.query.id, title: $route.query.title }
                }
            }]
        }
        ]
    }
    ]
})

//全局前置路由守卫————初始化的时候、每次路由切换之前被调用
router.beforeEach((to, from, next) => {
    console.log('前置路由守卫', to, from)
    // 判断是否需要鉴权
    if (to.meta.isAuth) {
        if (localStorage.getItem('school') === 'atguigu') {
            next()
        } else {
            alert('学校名不对,无权限查看!')
        }
    } else {
        next()
    }
})

//全局后置路由守卫————初始化的时候被调用、每次路由切换之后被调用
router.afterEach((to, from) => {
    console.log('后置路由守卫', to, from)
    document.title = to.meta.title || '硅谷系统'
})

export default router

独享路由守卫

// router文件夹下的index.js文件
// 该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
//引入组件
import About from '../pages/About'
import Home from '../pages/Home'

import News from '../pages/News'
import Message from '../pages/Message'

import Detail from '../pages/Detail'

//这里必须这样写,为了路由守卫可以发挥作用
const router = new VueRouter({
    routes: [{
        name: 'about',
        path: '/about',
        component: About,
        meta: { title: '关于' },
    },
    {
        name: 'home',
        path: '/home',
        component: Home,
        meta: { title: '主页' },
        children: [{
            name: 'news',
            path: 'news',
            component: News,
            // meta属性放程序员自定义内容
            meta: { isAuth: true, title: '新闻' }, // 是否授权
            beforeEnter(to, from, next) {
                console.log('独享路由守卫', to, from)
                // 判断是否需要鉴权
                if (to.meta.isAuth) {
                    if (localStorage.getItem('school') === 'atguigu') {
                        next()
                    } else {
                        alert('学校名不对,无权限查看!')
                    }
                } else {
                    next()
                }
            }
        },
        {
            name: 'message',
            path: 'message',
            component: Message,
            meta: { isAuth: true, title: '信息' }, // 是否授权
            children: [{
                name: 'detail', //路由命名,简化路由命名
                path: 'detail',
                component: Detail,
                //函数写法(只能是query写法)
                props($route) {
                    return { id: $route.query.id, title: $route.query.title }
                }
            }]
        }
        ]
    }
    ]
})

//全局后置路由守卫————初始化的时候被调用、每次路由切换之后被调用
router.afterEach((to, from) => {
    console.log('后置路由守卫', to, from)
    document.title = to.meta.title || '硅谷系统'
})

export default router

组件内路由守卫

<!-- pages/About.vue文件 -->
<template>
  <h2>我是About组件的内容</h2>
</template>

<script>
export default {
  name: "About",
  //通过路由规则,离开该组件时被调用
  beforeRouteEnter(to, from, next) {
    console.log("About--beforeRouteEnter", to, from);
    if (to.meta.isAuth) {
      if (localStorage.getItem("school") === "atguigu") {
        next();
      } else {
        alert("学校名不对,无权限查看!");
      }
    }
  },
  //通过路由规则,离开该组件时被调用,用的不多,因为没有全局后置守卫功能强大
  beforeRouteLeave(to, from, next) {
    console.log("About--beforeRouteLeave", to, from);
    next();
  },
};
</script>s
// router文件夹下的index.js文件
// 该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router'
//引入组件
import About from '../pages/About'
import Home from '../pages/Home'

import News from '../pages/News'
import Message from '../pages/Message'

import Detail from '../pages/Detail'

//这里必须这样写,为了路由守卫可以发挥作用
const router = new VueRouter({
    routes: [{
        name: 'about',
        path: '/about',
        component: About,
        meta: { isAuth: true, title: '关于' },
    },
    {
        name: 'home',
        path: '/home',
        component: Home,
        meta: { title: '主页' },
        children: [{
            name: 'news',
            path: 'news',
            component: News,
            // meta属性放程序员自定义内容
            meta: { isAuth: true, title: '新闻' }, // 是否授权
        },
        {
            name: 'message',
            path: 'message',
            component: Message,
            meta: { isAuth: true, title: '信息' }, // 是否授权
            children: [{
                name: 'detail', //路由命名,简化路由命名
                path: 'detail',
                component: Detail,
                //函数写法(只能是query写法)
                props($route) {
                    return { id: $route.query.id, title: $route.query.title }
                }
            }]
        }
        ]
    }
    ]
})

//全局后置路由守卫————初始化的时候被调用、每次路由切换之后被调用
router.afterEach((to, from) => {
    console.log('后置路由守卫', to, from)
    document.title = to.meta.title || '硅谷系统'
})

export default router
  • 20
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值