【Vue.js】Vue.js中常用的UI组件库和Vue Router
时间:2022-07-26
本文章向大家介绍【Vue.js】Vue.js中常用的UI组件库和Vue Router,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
1、Vue生态中常用的UI组件库
1. vant
介绍
- 轻量级、可靠的移动端 Vue 组件库
- 有赞前端团队出品
- GitHub地址:https://github.com/youzan/vant
特性
- 拥有60+ 个组件
- 90% 单元测试覆盖率
- 完善的中英文文档和示例
- 支持按需引入
- 支持主题定制
- 支持国际化
- 支持 TypeScript
- 支持 SSR
使用
- 通过 npm 安装:
>> npm install vant --save
- 通过 yarn 安装:
>> yarn add vant
- 安装babel-plugin-import插件,babel-plugin-import 是一款 babel 插件,它会在编译过程中将 import 的写法自动转换为按需引入的方式:
>> npm install babel-plugin-import -D
- 配置babel.config.js:
module.exports = {
plugins: [
['import', {
libraryName: 'vant',
libraryDirectory: 'es',
style: true
}, 'vant']
]
};
- 在代码中直接引入 Vant 组件,插件会自动将代码转化为按需引入形式:
import { Button } from 'vant';
代码示例
## App.vue
<template>
<div id="app">
<van-button class="btn" type="default">默认按钮</van-button>
<van-button class="btn" type="primary">主要按钮</van-button>
<van-button class="btn" type="info">信息按钮</van-button>
<van-button disabled class="btn" type="warning">警告按钮</van-button>
<van-button class="btn" type="danger">危险按钮</van-button>
<p></p>
<van-cell-group>
<van-cell title="单元格" value="内容"></van-cell>
<van-cell title="单元格" value="内容" label="描述信息"></van-cell>
</van-cell-group>
<p></p>
<van-datetime-picker
v-model="currentDate"
type="datetime"
:min-date="minDate"
:max-date="maxDate"
></van-datetime-picker>
</div>
</template>
<script>
export default {
name: 'app',
components: {},
data() {
return {
minHour: 10,
maxHour: 20,
minDate: new Date(),
maxDate: new Date(2019, 10, 1),
currentDate: new Date()
};
}
}
</script>
<style>
.btn {
margin: 10px;
}
</style>
## main.js
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false;
import { Button } from 'vant';
Vue.use(Button);
import { Cell, CellGroup } from 'vant';
Vue.use(Cell).use(CellGroup);
import { DatetimePicker } from 'vant';
Vue.use(DatetimePicker);
new Vue({
render: h => h(App),
}).$mount('#app');
2. Ant Design Vue
介绍
- 社区主导
- 蚂蚁金服技术支持
- https://github.com/vueComponent/ant-design-vue
特性
- 55+ 个组件
- 87% 单元测试覆盖率
3. Element UI
Mint UI
- GitHub地址:http://mint-ui.github.io/#!/zh-cn
- 饿了么开源的基于 vue 的移动端 UI 组件库
Elment UI
- 官网地址:http://element-cn.eleme.io/#/zh-CN
- 饿了么开源的基于 vue 的 PC 端 UI 组件库
- vue-cli@3快速安装 Element 插件:
>> vue create my-app
>> cd my-app
>> vue add element
一般移动端建议使用vant,后台管理系统建议使用Ant Design Vue或Element UI。
## index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>lk-element-demo</title>
</head>
<body>
<noscript>
<strong>We're sorry but lk-element-demo doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
## App.vue
<template>
<div id="app">
<div>
<div class="block">
<span class="demonstration">默认</span>
<el-date-picker
v-model="value1"
type="date"
placeholder="选择日期">
</el-date-picker>
</div>
<div class="block">
<span class="demonstration">带快捷选项</span>
<el-date-picker
v-model="value2"
align="right"
type="date"
placeholder="选择日期"
:picker-options="pickerOptions">
</el-date-picker>
</div>
<el-container style="height: 500px; border: 1px solid #eee">
<el-aside width="200px" style="background-color: rgb(238, 241, 246)">
<el-menu :default-openeds="['1', '3']">
<el-submenu index="1">
<template slot="title"><i class="el-icon-message"></i>导航一</template>
<el-menu-item-group>
<template slot="title">分组一</template>
<el-menu-item index="1-1">选项1</el-menu-item>
<el-menu-item index="1-2">选项2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="分组2">
<el-menu-item index="1-3">选项3</el-menu-item>
</el-menu-item-group>
<el-submenu index="1-4">
<template slot="title">选项4</template>
<el-menu-item index="1-4-1">选项4-1</el-menu-item>
</el-submenu>
</el-submenu>
<el-submenu index="2">
<template slot="title"><i class="el-icon-menu"></i>导航二</template>
<el-menu-item-group>
<template slot="title">分组一</template>
<el-menu-item index="2-1">选项1</el-menu-item>
<el-menu-item index="2-2">选项2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="分组2">
<el-menu-item index="2-3">选项3</el-menu-item>
</el-menu-item-group>
<el-submenu index="2-4">
<template slot="title">选项4</template>
<el-menu-item index="2-4-1">选项4-1</el-menu-item>
</el-submenu>
</el-submenu>
<el-submenu index="3">
<template slot="title"><i class="el-icon-setting"></i>导航三</template>
<el-menu-item-group>
<template slot="title">分组一</template>
<el-menu-item index="3-1">选项1</el-menu-item>
<el-menu-item index="3-2">选项2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="分组2">
<el-menu-item index="3-3">选项3</el-menu-item>
</el-menu-item-group>
<el-submenu index="3-4">
<template slot="title">选项4</template>
<el-menu-item index="3-4-1">选项4-1</el-menu-item>
</el-submenu>
</el-submenu>
</el-menu>
</el-aside>
<el-container>
<el-header style="text-align: right; font-size: 12px">
<el-dropdown>
<i class="el-icon-setting" style="margin-right: 15px"></i>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>查看</el-dropdown-item>
<el-dropdown-item>新增</el-dropdown-item>
<el-dropdown-item>删除</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<span>王小虎</span>
</el-header>
<el-main>
<el-table :data="tableData">
<el-table-column prop="date" label="日期" width="140">
</el-table-column>
<el-table-column prop="name" label="姓名" width="120">
</el-table-column>
<el-table-column prop="address" label="地址">
</el-table-column>
</el-table>
</el-main>
</el-container>
</el-container>
</div>
</div>
</template>
<script>
export default {
name: 'app',
data() {
const item = {
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
};
return {
tableData: Array(20).fill(item),
value1: '',
value2: ''
}
}
}
</script>
<style>
.el-header {
background-color: #B3C0D1;
color: #333;
line-height: 60px;
}
.el-aside {
color: #333;
}
</style>
## element.js
import Vue from 'vue'
import Element from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(Element)
## main.js
import Vue from 'vue'
import App from './App.vue'
import './plugins/element.js'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
2、Vue Router
1. 概念
- Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得更加轻松
Vue Router主要功能
- 嵌套的路由/视图表
- 模块化的、基于组件的路由配置
- HTML5 历史模式或 hash 模式
- 路由参数
- 基于 Vue.js 过渡系统的视图过渡效果
- 细粒度的导航控制
- 带有自动激活的 CSS class 的链接
- 将组件(components)映射到路由(routes),然后告诉 vue-router 在哪里渲染它们
- 组件与组件之间可以通过路由进行灵活切换
- 在切换过程中可以进行各种参数传递、权限控制等
2. 基本配置
初始化工程项目
>> vue create lk-vue-router
>> npm install vue-router --save # 安装Vue-Router
>> npm run serve
路由默认配置
# main.js
import router from './router'
new Vue({
router,
render: h => h(App)
}).$mount('#app');
# router.js
import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
import About from './views/About.vue'
Vue.use(Router);
export default new Router({
routes: [
{path: '/', name: 'home', component: Home},
{path: '/about', name: 'about', component: About}
]
})
路由导航
<div id="nav">
<router-link to="/">首页</router-link>|
<router-link to="/about">关于</router-link>
</div>
路由出口
<router-view/>
3. history模式
概念
- vue-router 默认 hash 模式 ,url使用#后面定位路由,对seo不利,设置history,就可以使用普通的url模式
- history 模式即普通url模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面
- 修改的只是URL中的hash,则不会导致页面被刷新
使用
const router = new VueRouter({
mode: 'history',
routes: [...]
})
hash和history区别
- hash模式url带#号,history模式不带#号
- 如果考虑url的规范,那么就需要使用history模式,因为history模式没有#号,是个正常的url,适合开发习惯
- 把用Vue或者React做的页面分享至三方app,有的app里面url是不允许带有#号的,所以要将#号去除那么就要使用history模式
- 使用history模式还有一个问题就是,在访问二级页面的时候,做刷新操作,会出现404错误,那么就需要和后端人配合让他配置一下apache或是nginx的url重定向,重定向到你的首页路由
hash |
history |
|
---|---|---|
url显示 |
有#,不好看 |
无#,好看 |
回车刷新 |
可以加载到hash值对应页面 |
一般就是404了 |
支持版本 |
支持低版本浏览器和IE浏览器 |
HTML5新推出的API |
代码示例
## router.js
import Vue from 'vue'
import Router from 'vue-router'
// 引入页面
import Home from './views/Home'
import About from './views/About'
Vue.use(Router);
export default new Router({
// mode: 'history',
routes: [
{ path: '/', redirect: '/home' },
// { path: '/', redirect: {name: 'about'} },
// { path: '/', redirect: to => { return '/home'}},
{path: '/home', name: 'home', component: Home},
{path: '/about', name: 'about', component: About},
]
})
## main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false;
new Vue({
router,
render: h => h(App),
}).$mount('#app');
## App.vue
<template>
<div id="app">
<!--设置路由导航-->
<div id="nav">
<router-link to="/home">首页</router-link>
<router-link to="/about">关于</router-link>
</div>
<!--设置路由出口-->
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'app',
components: {}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
#nav{
padding: 30px;
}
#nav a{
font-size: 18px;
color: #484848;
margin: 0 10px;
}
#nav a.router-link-exact-active{
color: #e9232c;
}
</style>
## Home.vue
<template>
<div id="home">
<h2>首页</h2>
</div>
</template>
<script>
export default {
name: "Home"
}
</script>
<style scoped>
#home{
width: 300px;
height: 500px;
background-color: skyblue;
margin: 0 auto;
}
h2{
color: red;
}
</style>
## About.vue
<template>
<div id="about">
<h2>关于我们</h2>
</div>
</template>
<script>
export default {
name: "About"
}
</script>
<style scoped>
#about{
width: 300px;
height: 500px;
background-color: red;
margin: 0 auto;
}
h2{
color: green;
}
</style>
4. 动态路由
概念
- 动态路由指路由可以携带一些参数,使用this.$router获取
使用
{path: '/mine/:name', name: 'mine', component: Mine}
export default {
name: "Mine",
created() {
// 输出当前路由
console.log(this.$route);
}
}
参数属性传递
- 设置props属性,获取路由的变量就和普通的属性传递没什么区别
- 参数属性传递方式:
- 对象模式:如果 props 是一个对象,它会被按原样设置为组件属性。当 props 是静态的时候有用
- 布尔模式:如果 props 被设置为 true,route.params 将会被设置为组件属性
- 函数模式:可以创建一个函数返回 props。这样你便可以将参数转换成另一种类型,将静态值与基于路由的值结合等等
代码示例
## router.js
import Vue from 'vue'
import Router from 'vue-router'
// 引入页面
import Home from './views/Home'
import About from './views/About'
import Mine from './views/Mine'
Vue.use(Router);
/*
let func = ({params, query})=>{
return {
name: params.name,
sex: params.sex,
height: query.height,
dog: query.dog,
}
};
*/
let func = (route)=>{
return {
name: route.params.name,
sex: route.params.sex,
height: route.query.height,
dog: route.query.dog,
}
};
export default new Router({
routes: [
{ path: '/', redirect: '/home' },
{ path: '/home', name: 'home', component: Home },
{ path: '/about', name: 'about', component: About },
// { path: '/mine/:name/:sex', name: 'mine', component: Mine }
// { path: '/mine', name: 'mine', component: Mine, props: {name: '小撩'} }
// { path: '/mine/:name/:sex', name: 'mine', component: Mine, props: true }
{ path: '/mine/:name/:sex', name: 'mine', component: Mine, props: func }
]
})
## main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false;
new Vue({
router,
render: h => h(App),
}).$mount('#app');
## App.vue
<template>
<div id="app">
<!--设置路由导航-->
<div id="nav">
<router-link to="/home">首页</router-link>
<router-link to="/about">关于</router-link>
<router-link to="/mine">我的</router-link>
</div>
<!--设置路由出口-->
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'app',
components: {}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
#nav{
padding: 30px;
}
#nav a{
font-size: 18px;
color: #484848;
margin: 0 10px;
}
#nav a.router-link-exact-active{
color: #e9232c;
}
</style>
## Home.vue
<template>
<div id="home">
<h2>首页</h2>
</div>
</template>
<script>
export default {
name: "Home"
}
</script>
<style scoped>
#home{
width: 300px;
height: 500px;
background-color: skyblue;
margin: 0 auto;
}
h2{
color: red;
}
</style>
## About.vue
<template>
<div id="about">
<h2>关于我们</h2>
</div>
</template>
<script>
export default {
name: "About"
}
</script>
<style scoped>
#about{
width: 300px;
height: 500px;
background-color: red;
margin: 0 auto;
}
h2{
color: green;
}
</style>
## Mine.vue
<template>
<div id="mine">
<h2>个人中心</h2>
<p>------------------------------------------</p>
<h2>根据路由对象获取的路径参数</h2>
<p>姓名:{{$route.params.name}}</p>
<p>性别:{{$route.params.sex}}</p>
<p>身高:{{$route.query.height}}</p>
<p>小狗:{{$route.query.dog}}</p>
<h2>根据属性对象获取的路径参数</h2>
<p>姓名:{{name}}</p>
<p>性别:{{sex}}</p>
<p>身高:{{height}}</p>
<p>小狗:{{dog}}</p>
</div>
</template>
<script>
export default {
name: "Mine",
props: ['name', 'sex', 'height', 'dog'],
created() {
console.log(this.$route);
/*
console.log(this.$route);
console.log(this.$route.path);
console.log(this.$route.params);
console.log(this.$route.query);
*/
// console.log(this.$router);
}
}
</script>
<style scoped>
#mine{
width: 300px;
height: 500px;
background-color: orange;
margin: 0 auto;
}
h2{
color: green;
}
</style>
5. 嵌套路由
概念
- 一级界面中可以通过嵌套路由配置二级界面切换
使用
{path: '/mine/:name', name: 'mine', component: Mine}
export default {
name: "Mine",
created() {
// 输出当前路由
console.log(this.$route);
}
}
代码示例
## router.js
import Vue from 'vue'
import Router from 'vue-router'
// 一级界面
import Home from './views/Home'
import About from './views/About'
import Mine from './views/Mine'
// 二级界面
import News from './views/News'
import Shop from './views/Shop'
Vue.use(Router);
export default new Router({
routes: [
{ path: '/', redirect: '/home' },
{
path: '/home',
name: 'home',
component: Home,
children: [
{ path: '/home', redirect: '/home/news' },
{path: 'news', name: 'news', component: News},
{path: 'shop', name: 'shop', component: Shop},
]
},
{path: '/about', name: 'about', component: About},
{path: '/mine', name: 'mine', component: Mine}
]
})
## main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false;
new Vue({
router,
render: h => h(App),
}).$mount('#app');
## App.vue
<template>
<div id="app">
<!--设置路由导航-->
<div id="nav">
<router-link to="/home">首页</router-link>
<router-link to="/about">关于</router-link>
<router-link to="/mine">我的</router-link>
</div>
<!--设置路由出口-->
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'app',
components: {}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
#nav{
padding: 30px;
}
#nav a{
font-size: 18px;
color: #484848;
margin: 0 10px;
}
#nav a.router-link-exact-active{
color: #e9232c;
}
</style>
## Home.vue
<template>
<div id="home">
<h2>首页</h2>
<!--路由导航-->
<ul>
<li><router-link to="/home/news">新闻</router-link></li>
<li><router-link to="/home/shop">商品</router-link></li>
</ul>
<!--路由出口-->
<router-view></router-view>
</div>
</template>
<script>
export default {
name: "Home"
}
</script>
<style scoped>
#home{
width: 300px;
height: 500px;
background-color: skyblue;
margin: 0 auto;
}
h2{
color: red;
}
</style>
## News.vue
<template>
<div id="news">
<h3>首页-新闻版块</h3>
</div>
</template>
<script>
export default {
name: "News"
}
</script>
<style scoped>
#news{
width: 100px;
height: 100px;
background-color: purple;
}
</style>
## Shop.vue
<template>
<div id="shop">
<h3>首页-商品版块</h3>
</div>
</template>
<script>
export default {
name: "Shop"
}
</script>
<style scoped>
#shop{
width: 100px;
height: 100px;
background-color: greenyellow;
}
</style>
## About.vue
<template>
<div id="about">
<h2>关于我们</h2>
</div>
</template>
<script>
export default {
name: "About"
}
</script>
<style scoped>
#about{
width: 300px;
height: 500px;
background-color: red;
margin: 0 auto;
}
h2{
color: green;
}
</style>
## Mine.vue
<template>
<div id="mine">
<h2>个人中心</h2>
</div>
</template>
<script>
export default {
name: "Mine",
}
</script>
<style scoped>
#mine{
width: 300px;
height: 500px;
background-color: orange;
margin: 0 auto;
}
h2{
color: green;
}
</style>
6. 路由(导航)守卫
概念
- 通过路由守卫可以对每次刷新或进入的路由界面进行权限验证,相当于Vue中的全局中间件
全局守卫
- router.beforeEach 注册一个全局前置守卫
- 参数
- to:Route: 即将要进入的目标 路由对象
- from:Route: 当前导航正要离开的路由
- next:Function: 一定要调用该方法来 resolve 这个钩子
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
router.beforeEach((to,from,next)=>{
if (to.path !== '/login') { // 要求登录
if (window.isLogin) {
next();
} else {
next('/login?redirect='+to.path);
}
} else {
next();
}
next();
});
全局后置钩子
- 可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身
router.afterEach((to, from) => {
// ...
})
路由独享守卫
- 可以在路由配置上直接定义 beforeEnter 守卫
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
- 这些守卫与全局前置守卫的方法参数是一样的
7. 组件内的守卫
概念
- 可以在组件内部实现相应钩子,在组件内部进行相应的守卫
方法
- beforeRouteEnter
- beforeRouteUpdate
- beforeRouteLeave
使用
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用,不能获取组件实例 `this`,因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用,举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用,可以访问组件实例 `this`
}
}
beforeRouteEnter(to, from, next) {
console.log("Mine路由进入前调用");
next();
},
beforeRouteUpdate(to, from, next) {
console.log("Mine路由,但是参数变了");
next();
},
beforeRouteLeave(to, from, next) {
console.log("Mine路由离开前");
next();
}
路由守卫流程
- 导航被触发
- 在失活的组件里调用离开守卫
- 调用全局的 beforeEach 守卫
- 在重用的组件里调用 beforeRouteUpdate 守卫(2.2+)
- 在路由配置里调用 beforeEnter
- 解析异步路由组件
- 在被激活的组件里调用 beforeRouteEnter
- 调用全局的 beforeResolve 守卫(2.5+)
- 导航被确认
- 调用全局的 afterEach 钩子
- 触发 DOM 更新
- 用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数
8. 异步组件
- 按需加载,用到时加载
{
path:'/about',
component: () => import('./views/About.vue')
}
9. 相关API
- this.$router.push(path):相当于点击路由链接(可以返回到当前路由界面)
- this.$router.replace(path):用新路由替换当前路由(不可以返回到当前路由界面)
- this.$router.back():请求(返回)上一个记录路由
- this.$router.go(-1):请求(返回)上一个记录路由
- this.$router.go(1):请求下一个记录路由
10. $router 和 $route的区别
router
- router是VueRouter的一个对象,通过Vue.use(VueRouter)和VueRouter构造函数得到一个router的实例对象
- 这个对象中是一个全局的对象,他包含了所有的路由包含了许多关键的对象和属性
route
- route是一个跳转的路由对象,每一个路由都会有一个route对象,是一个局部的对象
- 可以获取对应的name,path,params,query等
代码示例
## router.js
import Vue from 'vue'
import Router from 'vue-router'
// 一级界面
import Login from './views/Login'
import DashBoard from './views/DashBoard'
// 二级界面
import Home from './views/Home'
// import About from './views/About'
import Mine from './views/Mine'
const About = ()=> import('./views/About');
Vue.use(Router);
const router = new Router({
routes: [
{ path: '/', redirect: '/dashboard' },
{
path: '/dashboard',
name: 'dashboard',
component: DashBoard,
children: [
{ path: '/dashboard', redirect: '/dashboard/home' },
{ path: 'home', name: 'home', component: Home },
{ path: 'about', name: 'about', component: About },
{ path: 'mine', name: 'mine', component: Mine }
],
},
{ path: '/login', name: 'login', component: Login }
]
});
// 全局路由前置守卫
router.beforeEach((to, from, next)=>{
// console.log(to, from);
if(to.path !== '/login'){ // 验证是否登录
if(window.isLogin){ // 已经登录
next();
}else { // 没有登录
// next('/login?redirect='+ to.path);
// next('/login?redirect=/dashboard/mine');
next('/login');
}
}else { // 不需要验证
next();
}
// 放行
next();
});
// 全局路由后置守卫
router.afterEach((to, from) => {
// console.log('来了!');
});
export default router;
# main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false;
new Vue({
router,
render: h => h(App),
}).$mount('#app');
## App.vue
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'app',
components: {}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
## Login.vue
<template>
<div>
<h2>登录界面</h2>
<button @click="login">登录</button>
</div>
</template>
<script>
export default {
name: "Login",
methods: {
login(){
// 1. 登录成功
window.isLogin = true;
// 2. 获取回调地址
const redirect = this.$route.query.redirect;
if(redirect){ // 有回调地址
this.$router.push(redirect);
}else { // 没有回调地址
// 去首页
this.$router.replace('/');
}
}
}
}
</script>
<style scoped>
</style>
## DashBoard.vue
<template>
<div>
<h3>主面板</h3>
<!--设置路由导航-->
<div id="nav">
<router-link to="/dashboard/home">首页</router-link>
<router-link to="/dashboard/about">关于</router-link>
<router-link to="/dashboard/mine">我的</router-link>
</div>
<!--设置路由出口-->
<router-view></router-view>
</div>
</template>
<script>
export default {
name: "DashBoard"
}
</script>
<style scoped>
#nav{
padding: 30px;
}
#nav a{
font-size: 18px;
color: #484848;
margin: 0 10px;
}
#nav a.router-link-exact-active{
color: #e9232c;
}
</style>
## Home.vue
<template>
<div id="home">
<h2>首页</h2>
</div>
</template>
<script>
export default {
name: "Home"
}
</script>
<style scoped>
#home{
width: 300px;
height: 500px;
background-color: skyblue;
margin: 0 auto;
}
h2{
color: red;
}
</style>
## About.vue
<template>
<div id="about">
<h2>关于我们</h2>
</div>
</template>
<script>
export default {
name: "About"
}
</script>
<style scoped>
#about{
width: 300px;
height: 500px;
background-color: red;
margin: 0 auto;
}
h2{
color: green;
}
</style>
## Mine.vue
<template>
<div id="mine">
<h2>个人中心</h2>
</div>
</template>
<script>
export default {
name: "Mine",
beforeRouteEnter(to, from, next){
console.log('进入之前调用');
next();
},
beforeRouteUpdate(to, from, next){
console.log('路由的参数变了');
next();
},
beforeRouteLeave(to, from, next){
console.log('路由离开前调用');
next();
}
}
</script>
<style scoped>
#mine{
width: 300px;
height: 500px;
background-color: orange;
margin: 0 auto;
}
h2{
color: green;
}
</style>
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- linux系统挂载数据盘的方法(视频图文教程)
- CentOS7 Docker Nginx部署及运行详解
- linux下安装memcached_动力节点Java学院整理
- OneinStack一键安装PHP/JAVA/HHVM和超详细的VPS手动安装LNMP的方法
- RTSP协议视频平台EasyNVR如何将静态广告位修改为动态广告位?
- keeplive+mysql+drbd高可用架构安装步骤
- IP摄像头RTSP协议视频平台EasyNVR录像列表没有按照开始时间倒序排序的问题修复
- leetcode哈希表之两数之和
- Linux系统下Tomcat8启动速度很慢的解决方法
- Linux下查看binlog文件创建时间的命令
- Linux下修改文件权限(所有权)
- Sticks(UVA - 307)【DFS+剪枝】
- Linux CentOS服务器搭建与初始化配置教程
- Centos6.9安装vsftpd并配置多用户的方法
- linux c下log输出代码模板示例代码