vue-router
路由的简介
路由的理解
什么是路由?
-
一个路由就是一个映射关系(
key:value
)。 -
key为路径,value可能是function或component。
路由分类
-
后端路由:
-
理解:value是function, 用来处理客户端提交的请求。 -
注册路由: router.get(path, function(req, res))
。 -
工作过程:当服务器接收到一个请求时, 根据请求路径找到匹配的路由, 调用路由中的函数来处理请求, 返回响应数据。 -
前端路由:
-
浏览器端路由,value是component,用于展示页面内容。 -
注册路由: <Route path="/test" component={Test}>
。 -
工作过程:当浏览器的path变为 /test
时, 当前组件就会变为Test
组件。
SPA的理解
-
单页Web应用(single page web application,SPA)。
-
整个应用只有
一个完整页面
。 -
点击页面中的超链接
不会刷新页面
,只会做页面的局部更新
。 -
数据都是通过ajax请求获取,并在前端异步展示。
vue-router的理解
路由的基本使用
使用步骤
-
① 安装vue-router:
yarn add vue-router
-
② 安装插件:
import Vue from 'vue';
import App from './App';
import VueRouter from 'vue-router';
import router from './router';
//关闭生产提示
Vue.config.productionTip = false;
//安装VueRouter
Vue.use(VueRouter);
new Vue({
el: '#app',
render: h => h(App),
router
});
-
③ 编写router配置项:
// 该文件专门用来创建整个应用的路由器
import VueRouter from 'vue-router';
//引入组件
import About from '../components/About';
import Home from '../components/Home';
//创建并暴露路由器
const router = new VueRouter({
routes: [
{
path: '/about',
component: About
},
{
path: '/home',
component: Home
},
]
});
export default router;
-
④ 实现切换(active-class可以配置高亮样式):
<router-link active-class="active" class="list-group-item " to="/home">Home</router-link>
<router-link active-class="active" class="list-group-item" to="/about">About</router-link>
-
⑤ 指定展示位置:
<router-view></router-view>
应用示例
-
示例:
-
目录:
|-- README.md
|-- babel.config.js
|-- package.json
|-- public
| |-- css
| | `-- bootstrap.css
| |-- favicon.ico
| `-- index.html
|-- src
| |-- App.vue
| |-- assets
| | `-- logo.png
| |-- components
| | |-- About.vue
| | `-- Home.vue
| |-- main.js
| `-- router
| `-- index.js
|-- vue.config.js
`-- yarn.lock
-
main.js
import Vue from 'vue';
import App from './App';
import VueRouter from 'vue-router';
import router from './router';
//关闭生产提示
Vue.config.productionTip = false;
//安装VueRouter
Vue.use(VueRouter);
new Vue({
el: '#app',
render: h => h(App),
router
});
-
App.vue
<template>
<div>
<div class="row">
<div class="col-xs-offset-2 col-xs-8">
<div class="page-header"><h2>Vue Router Demo</h2></div>
</div>
</div>
<div class="row">
<div class="col-xs-2 col-xs-offset-2">
<div class="list-group">
<!-- 原始HTML中我们使用a标签实现页面的跳转 -->
<!-- <a class="list-group-item" href="./about.html">About</a> -->
<!-- <a class="list-group-item active" href="./home.html">Home</a> -->
<!-- Vue中借助router-link标签实现路由的切换 -->
<router-link active-class="active" class="list-group-item " to="/home">Home</router-link>
<router-link active-class="active" class="list-group-item" to="/about">About</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>
export default {
name: 'App',
};
</script>
-
router/index.js
// 该文件专门用来创建整个应用的路由器
import VueRouter from 'vue-router';
//引入组件
import About from '../components/About';
import Home from '../components/Home';
//创建并暴露路由器
const router = new VueRouter({
routes: [
{
path: '/about',
component: About
},
{
path: '/home',
component: Home
},
]
});
export default router;
-
components/About.vue
<template>
<div>我是About的内容</div>
</template>
<script>
export default {
name: 'About'
};
</script>
<style scoped>
</style>
-
components/Home.vue
<template>
<div>我是Home的内容</div>
</template>
<script>
export default {
name: 'Home'
};
</script>
<style scoped>
</style>
路由的注意点
-
路由组件
通常存放在pages
目录下,一般组件
通常存放在components
目录下。 -
通过切换,”隐藏”了的路由组件,默认是被销毁的,需要的时候再去挂载。
-
每个组件都有自己的
$route
属性,里面存储自己的路由信息。 -
整个应用只有一个router,可以通过组件的
$router
属性获取到。
嵌套路由
使用步骤
-
① 配置路径规则,使用children配置项:
// 该文件专门用来创建整个应用的路由器
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';
//创建并暴露路由器
const router = new VueRouter({
routes: [
{
path: '/about',
component: About
},
{
path: '/home',
component: Home,
children: [ //通过children配置自己路由
{
path: 'news', //此处一定不要写 /news
component: News
},
{
path: 'message', //此处一定不要写 /message
component: Message
},
]
},
]
});
export default router;
-
② 路径(要写完整路径):
<router-link active-class="active" class="list-group-item" to="/home/message">Message</router-link>
应用示例
-
示例:
-
目录结构:
|-- README.md
|-- babel.config.js
|-- package.json
|-- public
| |-- css
| | `-- bootstrap.css
| |-- favicon.ico
| `-- index.html
|-- src
| |-- App.vue
| |-- assets
| | `-- logo.png
| |-- components
| | `-- Banner.vue
| |-- main.js
| |-- pages
| | |-- About.vue
| | |-- Home.vue
| | |-- Message.vue
| | `-- News.vue
| `-- router
| `-- index.js
|-- vue.config.js
`-- yarn.lock
-
main.js
import Vue from 'vue';
import App from './App';
import VueRouter from 'vue-router';
import router from './router';
//关闭生产提示
Vue.config.productionTip = false;
//安装VueRouter
Vue.use(VueRouter);
new Vue({
el: '#app',
render: h => h(App),
router
});
-
App.vue
<template>
<div>
<div class="row">
<div class="col-xs-offset-2 col-xs-8">
<div class="page-header">
<Banner/>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-2 col-xs-offset-2">
<div class="list-group">
<!-- Vue中借助router-link标签实现路由的切换 -->
<router-link active-class="active" class="list-group-item " to="/home">Home</router-link>
<router-link active-class="active" class="list-group-item" to="/about">About</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';
export default {
name: 'App',
components: {
Banner
}
};
</script>
-
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';
//创建并暴露路由器
const router = new VueRouter({
routes: [
{
path: '/about',
component: About
},
{
path: '/home',
component: Home,
children: [ //通过children配置自己路由
{
path: 'news', //此处一定不要写 /news
component: News
},
{
path: 'message', //此处一定不要写 /message
component: Message
},
]
},
]
});
export default router;
-
components/Banner.vue
<template>
<h2>Vue Router Demo</h2>
</template>
<script>
export default {
name: 'Banner'
};
</script>
<style scoped>
</style>
-
pages/About.vue
<template>
<div>我是About的内容</div>
</template>
<script>
export default {
name: 'About'
};
</script>
<style scoped>
</style>
-
pages/Home.vue
<template>
<div>
<h2>Home组件内容</h2>
<div>
<ul class="nav nav-tabs">
<li>
<router-link active-class="active" class="list-group-item" to="/home/news">News</router-link>
</li>
<li>
<router-link active-class="active" class="list-group-item" to="/home/message">Message</router-link>
</li>
</ul>
<ul>
<router-view></router-view>
</ul>
</div>
</div>
</template>
<script>
export default {
name: 'Home'
};
</script>
<style scoped>
</style>
-
pages/News.vue
<template>
<ul>
<li>news001</li>
<li>news002</li>
<li>news003</li>
</ul>
</template>
<script>
export default {
name: 'News'
};
</script>
<style scoped>
</style>
-
pages/Message.vue
<template>
<div>
<ul>
<li>
<a href="/message1">message001</a>
</li>
<li>
<a href="/message2">message002</a>
</li>
<li>
<a href="/message/3">message003</a>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'Message'
};
</script>
<style scoped>
</style>
路由传参(query参数)
使用步骤
-
① 传递参数:
<!-- 跳转路由并携带query参数,to的字符串写法 -->
<router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`">{{ m.title }}</router-link>
<!-- 跳转路由并携带query参数,to的对象写法 -->
<router-link :to="{
path:'/home/message/detail',
query:{id:m.id,title:m.title}
}">{{ m.title }}</router-link>
-
② 接收参数:
<ul>
<li>消息编号:{{ $route.query.id }}</li>
<li>消息标题:{{ $route.query.title }}</li>
</ul>
应用示例
-
示例:
-
目录结构:
|-- README.md
|-- babel.config.js
|-- package.json
|-- public
| |-- css
| | `-- bootstrap.css
| |-- favicon.ico
| `-- index.html
|-- src
| |-- App.vue
| |-- assets
| | `-- logo.png
| |-- components
| | `-- Banner.vue
| |-- main.js
| |-- pages
| | |-- About.vue
| | |-- Detail.vue
| | |-- Home.vue
| | |-- Message.vue
| | `-- News.vue
| `-- router
| `-- index.js
|-- vue.config.js
`-- yarn.lock
-
main.js
import Vue from 'vue';
import App from './App';
import VueRouter from 'vue-router';
import router from './router';
//关闭生产提示
Vue.config.productionTip = false;
//安装VueRouter
Vue.use(VueRouter);
new Vue({
el: '#app',
render: h => h(App),
router
});
-
App.vue
<template>
<div>
<div class="row">
<div class="col-xs-offset-2 col-xs-8">
<div class="page-header">
<Banner/>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-2 col-xs-offset-2">
<div class="list-group">
<!-- Vue中借助router-link标签实现路由的切换 -->
<router-link active-class="active" class="list-group-item" to="/about">About</router-link>
<router-link active-class="active" class="list-group-item " 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';
export default {
name: 'App',
components: {
Banner
}
};
</script>
-
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: [
{
path: '/about',
component: About
},
{
path: '/home',
component: Home,
children: [ //通过children配置自己路由
{
path: 'news', //此处一定不要写 /news
component: News
},
{
path: 'message', //此处一定不要写 /message
component: Message,
children: [
{
path: 'detail',
component: Detail
}
]
},
]
},
]
});
export default router;
-
components/Banner.vue
<template>
<h2>Vue Router Demo</h2>
</template>
<script>
export default {
name: 'Banner'
};
</script>
<style scoped>
</style>
-
pages/About.vue
<template>
<div>我是About的内容</div>
</template>
<script>
export default {
name: 'About'
};
</script>
<style scoped>
</style>
-
pages/Home.vue
<template>
<div>
<h2>Home组件内容</h2>
<div>
<ul class="nav nav-tabs">
<li>
<router-link active-class="active" class="list-group-item" to="/home/news">News</router-link>
</li>
<li>
<router-link active-class="active" class="list-group-item" to="/home/message">Message</router-link>
</li>
</ul>
<ul>
<router-view></router-view>
</ul>
</div>
</div>
</template>
<script>
export default {
name: 'Home'
};
</script>
<style scoped>
</style>
-
pages/News.vue
<template>
<ul>
<li>news001</li>
<li>news002</li>
<li>news003</li>
</ul>
</template>
<script>
export default {
name: 'News'
};
</script>
<style scoped>
</style>
-
pages/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>-->
<!-- 跳转路由并携带query参数,to的对象写法 -->
<router-link :to="{path:'/home/message/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 scoped>
</style>
-
pages/Detail.vue
<template>
<ul>
<li>消息编号:{{ $route.query.id }}</li>
<li>消息标题:{{ $route.query.title }}</li>
</ul>
</template>
<script>
export default {
name: 'Detail',
mounted () {
console.log(this.$route.query);
}
};
</script>
<style scoped>
</style>
命名路由
概述
-
命名路由可以简化路由的跳转。
使用步骤
-
① 给路由命名:
// 该文件专门用来创建整个应用的路由器
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
},
{
path: '/home',
component: Home,
children: [
{
path: 'news',
component: News
},
{
path: 'message',
component: Message,
children: [
{
name: 'detail', //给路由命名
path: 'detail',
component: Detail
}
]
},
]
},
]
});
export default router;
-
② 简化跳转:
<!-- 简化前,需要写完整的路径 -->
<router-link :to="{path:'/home/message/detail',query:{id:m.id,title:m.title}}">{{ m.title }}</router-link>
<!-- 简化后,直接通过名字跳转 -->
<router-link :to="{name:'detail'}">{{ m.title }}</router-link>
<!-- 简化后,配合传递参数 -->
<router-link :to="{name:'detail',query:{id:m.id,title:m.title}}">{{ m.title }}</router-link>
应用示例
-
示例:
-
目录结构:
|-- README.md
|-- babel.config.js
|-- package.json
|-- public
| |-- css
| | `-- bootstrap.css
| |-- favicon.ico
| `-- index.html
|-- src
| |-- App.vue
| |-- assets
| | `-- logo.png
| |-- components
| | `-- Banner.vue
| |-- main.js
| |-- pages
| | |-- About.vue
| | |-- Detail.vue
| | |-- Home.vue
| | |-- Message.vue
| | `-- News.vue
| `-- router
| `-- index.js
|-- vue.config.js
`-- yarn.lock
-
main.js
import Vue from 'vue';
import App from './App';
import VueRouter from 'vue-router';
import router from './router';
//关闭生产提示
Vue.config.productionTip = false;
//安装VueRouter
Vue.use(VueRouter);
new Vue({
el: '#app',
render: h => h(App),
router
});
-
App.vue
<template>
<div>
<div class="row">
<div class="col-xs-offset-2 col-xs-8">
<div class="page-header">
<Banner/>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-2 col-xs-offset-2">
<div class="list-group">
<!-- Vue中借助router-link标签实现路由的切换 -->
<router-link :to="{name:'about'}" active-class="active" class="list-group-item">About</router-link>
<router-link active-class="active" class="list-group-item " 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';
export default {
name: 'App',
components: {
Banner
}
};
</script>
-
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
},
{
path: '/home',
component: Home,
children: [
{
path: 'news',
component: News
},
{
path: 'message',
component: Message,
children: [
{
name: 'detail',
path: 'detail',
component: Detail
}
]
},
]
},
]
});
export default router;
-
components/Banner.vue
<template>
<h2>Vue Router Demo</h2>
</template>
<script>
export default {
name: 'Banner'
};
</script>
<style scoped>
</style>
-
pages/About.vue
<template>
<div>我是About的内容</div>
</template>
<script>
export default {
name: 'About'
};
</script>
<style scoped>
</style>
-
pages/Home.vue
<template>
<div>
<h2>Home组件内容</h2>
<div>
<ul class="nav nav-tabs">
<li>
<router-link active-class="active" class="list-group-item" to="/home/news">News</router-link>
</li>
<li>
<router-link active-class="active" class="list-group-item" to="/home/message">Message</router-link>
</li>
</ul>
<ul>
<router-view></router-view>
</ul>
</div>
</div>
</template>
<script>
export default {
name: 'Home'
};
</script>
<style scoped>
</style>
-
pages/News.vue
<template>
<ul>
<li>news001</li>
<li>news002</li>
<li>news003</li>
</ul>
</template>
<script>
export default {
name: 'News'
};
</script>
<style scoped>
</style>
-
pages/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>-->
<!-- 跳转路由并携带query参数,to的对象写法 -->
<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 scoped>
</style>
-
pages/Detail.vue
<template>
<ul>
<li>消息编号:{{ $route.query.id }}</li>
<li>消息标题:{{ $route.query.title }}</li>
</ul>
</template>
<script>
export default {
name: 'Detail',
mounted () {
console.log(this.$route.query);
}
};
</script>
<style scoped>
</style>
路由传参(params参数)
使用步骤
-
① 配置路由,声明接收params参数:
// 该文件专门用来创建整个应用的路由器
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
},
{
path: '/home',
component: Home,
children: [
{
path: 'news',
component: News
},
{
path: 'message',
component: Message,
children: [
{
name: 'detail',
path: 'detail/:id/:title', //使用占位符声明接收params参数
component: Detail
}
]
},
]
},
]
});
export default router;
-
② 传递参数:
<!-- 跳转路由并携带params参数,to的字符串写法 -->
<router-link :to="`/home/message/detail/${m.id}/${m.title}`">{{ m.title }}</router-link>
<!-- 跳转路由并携带params参数,to的对象写法 -->
<router-link :to="{name:'detail',params:{id:m.id,title:m.title}}">{{ m.title }}</router-link>
注意:路由携带params参数时,如果使用to的对象写法,则不能使用path,必须使用name配置
-
③ 接收参数:
<ul>
<li>消息编号:{{ $route.params.id }}</li>
<li>消息标题:{{ $route.params.title }}</li>
</ul>
应用示例
-
示例:
-
目录结构:
|-- README.md
|-- babel.config.js
|-- package.json
|-- public
| |-- css
| | `-- bootstrap.css
| |-- favicon.ico
| `-- index.html
|-- src
| |-- App.vue
| |-- assets
| | `-- logo.png
| |-- components
| | `-- Banner.vue
| |-- main.js
| |-- pages
| | |-- About.vue
| | |-- Detail.vue
| | |-- Home.vue
| | |-- Message.vue
| | `-- News.vue
| `-- router
| `-- index.js
|-- vue.config.js
`-- yarn.lock
-
main.js
import Vue from 'vue';
import App from './App';
import VueRouter from 'vue-router';
import router from './router';
//关闭生产提示
Vue.config.productionTip = false;
//安装VueRouter
Vue.use(VueRouter);
new Vue({
el: '#app',
render: h => h(App),
router
});
-
App.vue
<template>
<div>
<div class="row">
<div class="col-xs-offset-2 col-xs-8">
<div class="page-header">
<Banner/>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-2 col-xs-offset-2">
<div class="list-group">
<!-- Vue中借助router-link标签实现路由的切换 -->
<router-link :to="{name:'about'}" active-class="active" class="list-group-item">About</router-link>
<router-link active-class="active" class="list-group-item " 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';
export default {
name: 'App',
components: {
Banner
}
};
</script>
-
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
},
{
path: '/home',
component: Home,
children: [
{
path: 'news',
component: News
},
{
path: 'message',
component: Message,
children: [
{
name: 'detail',
path: 'detail/:id/:title', //使用占位符声明接收params参数
component: Detail
}
]
},
]
},
]
});
export default router;
-
components/Banner.vue
<template>
<h2>Vue Router Demo</h2>
</template>
<script>
export default {
name: 'Banner'
};
</script>
<style scoped>
</style>
-
pages/About.vue
<template>
<div>我是About的内容</div>
</template>
<script>
export default {
name: 'About'
};
</script>
<style scoped>
</style>
-
pages/Home.vue
<template>
<div>
<h2>Home组件内容</h2>
<div>
<ul class="nav nav-tabs">
<li>
<router-link active-class="active" class="list-group-item" to="/home/news">News</router-link>
</li>
<li>
<router-link active-class="active" class="list-group-item" to="/home/message">Message</router-link>
</li>
</ul>
<ul>
<router-view></router-view>
</ul>
</div>
</div>
</template>
<script>
export default {
name: 'Home'
};
</script>
<style scoped>
</style>
-
pages/News.vue
<template>
<ul>
<li>news001</li>
<li>news002</li>
<li>news003</li>
</ul>
</template>
<script>
export default {
name: 'News'
};
</script>
<style scoped>
</style>
-
pages/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的对象写法 -->
<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 scoped>
</style>
-
pages/Detail.vue
<template>
<ul>
<li>消息编号:{{ $route.params.id }}</li>
<li>消息标题:{{ $route.params.title }}</li>
</ul>
</template>
<script>
export default {
name: 'Detail',
mounted () {
console.log(this.$route.params);
}
};
</script>
<style scoped>
</style>
路由的props配置
概述
-
让路由组件更方便的接收到参数。
-
第一种写法:值是对象,该对象中的key和value都会以props的形式传递给Detail组件(几乎不用)
// 该文件专门用来创建整个应用的路由器
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
},
{
path: '/home',
component: Home,
children: [
{
path: 'news',
component: News
},
{
path: 'message',
component: Message,
children: [
{
name: 'detail',
path: 'detail/:id/:title', //使用占位符声明接收params参数
component: Detail,
//props的第一种写法,值为对象,该对象中的key和value都会以props的形式传递给Detail组件
props: {
a: 1,
b: 2
}
}
]
},
]
},
]
});
export default router;
-
第二种写法:值为布尔值,如果布尔值为true,就会把路由组件收到的所有 params
参数,以props的形式传递给Detail组件
// 该文件专门用来创建整个应用的路由器
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
},
{
path: '/home',
component: Home,
children: [
{
path: 'news',
component: News
},
{
path: 'message',
component: Message,
children: [
{
name: 'detail',
path: 'detail/:id/:title', //使用占位符声明接收params参数
component: Detail,
//props的第二种写法,值为布尔值,如果布尔值为true,就会把路由组件收到的所有params参数,以props的形式传递给Detail组件
props: true
}
]
},
]
},
]
});
export default router;
-
第三种写法:值为函数。
// 该文件专门用来创建整个应用的路由器
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
},
{
path: '/home',
component: Home,
children: [
{
path: 'news',
component: News
},
{
path: 'message',
component: Message,
children: [
{
name: 'detail',
path: 'detail/:id/:title', //使用占位符声明接收params参数
component: Detail,
//props的第三种写法:值为函数,
props ($route) {
return { id: $route.params.id, title: $route.params.title };
}
/*props ({ params: { id, title } }) {
return { id, title };
}*/
}
]
},
]
},
]
});
export default router;
应用示例
-
示例:
-
目录结构:
|-- README.md
|-- babel.config.js
|-- package.json
|-- public
| |-- css
| | `-- bootstrap.css
| |-- favicon.ico
| `-- index.html
|-- src
| |-- App.vue
| |-- assets
| | `-- logo.png
| |-- components
| | `-- Banner.vue
| |-- main.js
| |-- pages
| | |-- About.vue
| | |-- Detail.vue
| | |-- Home.vue
| | |-- Message.vue
| | `-- News.vue
| `-- router
| `-- index.js
|-- vue.config.js
`-- yarn.lock
-
main.js
import Vue from 'vue';
import App from './App';
import VueRouter from 'vue-router';
import router from './router';
//关闭生产提示
Vue.config.productionTip = false;
//安装VueRouter
Vue.use(VueRouter);
new Vue({
el: '#app',
render: h => h(App),
router
});
-
App.vue
<template>
<div>
<div class="row">
<div class="col-xs-offset-2 col-xs-8">
<div class="page-header">
<Banner/>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-2 col-xs-offset-2">
<div class="list-group">
<!-- Vue中借助router-link标签实现路由的切换 -->
<router-link :to="{name:'about'}" active-class="active" class="list-group-item">About</router-link>
<router-link active-class="active" class="list-group-item " 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';
export default {
name: 'App',
components: {
Banner
}
};
</script>
-
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
},
{
path: '/home',
component: Home,
children: [
{
path: 'news',
component: News
},
{
path: 'message',
component: Message,
children: [
{
name: 'detail',
path: 'detail/:id/:title', //使用占位符声明接收params参数
component: Detail,
//props的第一种写法,值为对象,该对象中的key和value都会以props的形式传递给Detail组件
/* props: {
a: 1,
b: 2
}*/
//props的第二种写法,值为布尔值,如果布尔值为true,就会把路由组件收到的所有params参数,以props的形式传递给Detail组件
// props: true
//props的第三种写法:值为函数,
props ($route) {
return { id: $route.params.id, title: $route.params.title };
}
/*props ({ params: { id, title } }) {
return { id, title };
}*/
}
]
},
]
},
]
});
export default router;
-
components/Banner.vue
<template>
<h2>Vue Router Demo</h2>
</template>
<script>
export default {
name: 'Banner'
};
</script>
<style scoped>
</style>
-
pages/About.vue
<template>
<div>我是About的内容</div>
</template>
<script>
export default {
name: 'About'
};
</script>
<style scoped>
</style>
-
pages/Home.vue
<template>
<div>
<h2>Home组件内容</h2>
<div>
<ul class="nav nav-tabs">
<li>
<router-link active-class="active" class="list-group-item" to="/home/news">News</router-link>
</li>
<li>
<router-link active-class="active" class="list-group-item" to="/home/message">Message</router-link>
</li>
</ul>
<ul>
<router-view></router-view>
</ul>
</div>
</div>
</template>
<script>
export default {
name: 'Home'
};
</script>
<style scoped>
</style>
-
pages/News.vue
<template>
<ul>
<li>news001</li>
<li>news002</li>
<li>news003</li>
</ul>
</template>
<script>
export default {
name: 'News'
};
</script>
<style scoped>
</style>
-
pages/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的对象写法 -->
<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 scoped>
</style>
-
pages/Detail.vue
<template>
<ul>
<li>消息编号:{{ id }}</li>
<li>消息标题:{{ title }}</li>
</ul>
</template>
<script>
export default {
name: 'Detail',
mounted () {
console.log(this);
},
props: ['id', 'title']
};
</script>
<style scoped>
</style>
router-link的replace属性
-
作用:控制路由跳转时操作浏览器历史记录的模式。
-
浏览器的历史记录有两种写入方式:分别为
push
和replace
,push
是追加历史的记录,replace
是替换当前记录,路由跳转的时候默认为push
。 -
如何开启replace模式?
<!-- 只需要添加replace属性即可 -->
<router-link replace>About</router-link>
编程式路由导航
概述
-
不借助
<router-link>
实现路由跳转,让路由跳转更加灵活。 -
点击路由链接,可以返回到当前路由界面:
this.$router.push({
name: 'detail',
params: { id: m.id, title: m.title }
});
-
点击路由链接,不可以返回到当前路由界面:
this.$router.replace({
name: 'detail',
params: { id: m.id, title: m.title }
});
-
请求返回上一个记录路由:
this.$router.back();
-
请求下一个记录路由:
this.$router.forward();
应用示例
-
示例:
-
目录结构:
|-- README.md
|-- babel.config.js
|-- package.json
|-- public
| |-- css
| | `-- bootstrap.css
| |-- favicon.ico
| `-- index.html
|-- src
| |-- App.vue
| |-- assets
| | `-- logo.png
| |-- components
| | `-- Banner.vue
| |-- main.js
| |-- pages
| | |-- About.vue
| | |-- Detail.vue
| | |-- Home.vue
| | |-- Message.vue
| | `-- News.vue
| `-- router
| `-- index.js
|-- vue.config.js
`-- yarn.lock
-
main.js
import Vue from 'vue';
import App from './App';
import VueRouter from 'vue-router';
import router from './router';
//关闭生产提示
Vue.config.productionTip = false;
//安装VueRouter
Vue.use(VueRouter);
new Vue({
el: '#app',
render: h => h(App),
router
});
-
App.vue
<template>
<div>
<div class="row">
<div class="col-xs-offset-2 col-xs-8">
<div class="page-header">
<Banner/>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-2 col-xs-offset-2">
<div class="list-group">
<!-- Vue中借助router-link标签实现路由的切换 -->
<router-link :to="{name:'about'}" active-class="active" class="list-group-item">About</router-link>
<router-link active-class="active" class="list-group-item " 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';
export default {
name: 'App',
components: {
Banner
}
};
</script>
-
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
},
{
path: '/home',
component: Home,
children: [
{
path: 'news',
component: News
},
{
path: 'message',
component: Message,
children: [
{
name: 'detail',
path: 'detail/:id/:title', //使用占位符声明接收params参数
component: Detail,
//props的第一种写法,值为对象,该对象中的key和value都会以props的形式传递给Detail组件
/* props: {
a: 1,
b: 2
}*/
//props的第二种写法,值为布尔值,如果布尔值为true,就会把路由组件收到的所有params参数,以props的形式传递给Detail组件
// props: true
//props的第三种写法:值为函数,
props ($route) {
return { id: $route.params.id, title: $route.params.title };
}
/*props ({ params: { id, title } }) {
return { id, title };
}*/
}
]
},
]
},
]
});
export default router;
-
components/Banner.vue
<template>
<div>
<h2>Vue Router Demo</h2>
<button @click="back">后退</button>
<button @click="forward">前进</button>
</div>
</template>
<script>
export default {
name: 'Banner',
methods: {
forward () {
this.$router.forward();
},
back () {
this.$router.back();
}
}
};
</script>
<style scoped>
</style>
-
pages/About.vue
<template>
<div>我是About的内容</div>
</template>
<script>
export default {
name: 'About'
};
</script>
<style scoped>
</style>
-
pages/Home.vue
<template>
<div>
<h2>Home组件内容</h2>
<div>
<ul class="nav nav-tabs">
<li>
<router-link active-class="active" class="list-group-item" to="/home/news">News</router-link>
</li>
<li>
<router-link active-class="active" class="list-group-item" to="/home/message">Message</router-link>
</li>
</ul>
<ul>
<router-view></router-view>
</ul>
</div>
</div>
</template>
<script>
export default {
name: 'Home'
};
</script>
<style scoped>
</style>
-
pages/News.vue
<template>
<ul>
<li>news001</li>
<li>news002</li>
<li>news003</li>
</ul>
</template>
<script>
export default {
name: 'News'
};
</script>
<style scoped>
</style>
-
pages/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的对象写法 -->
<router-link :to="{
name:'detail',
params:{id:m.id,title:m.title}
}">{{ m.title }}
</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',
params: { id: m.id, title: m.title }
});
},
replaceShow (m) {
this.$router.replace({
name: 'detail',
params: { id: m.id, title: m.title }
});
}
}
};
</script>
<style scoped>
</style>
-
pages/Detail.vue
<template>
<ul>
<li>消息编号:{{ id }}</li>
<li>消息标题:{{ title }}</li>
</ul>
</template>
<script>
export default {
name: 'Detail',
mounted () {
console.log(this);
},
props: ['id', 'title']
};
</script>
<style scoped>
</style>
缓存路由组件
概述
-
作用:让不展示的路由组件保持挂载,不被销毁。
-
具体编码:
<!-- include里面是组件名,缓存一个路由组件 -->
<keep-alive include="News">
<router-view></router-view>
</keep-alive>
<!-- include里面是组件名,缓存多个路由组件 -->
<keep-alive :include="['News','Message']">
<router-view></router-view>
</keep-alive>
应用示例
-
示例:
-
目录结构:
|-- README.md
|-- babel.config.js
|-- package.json
|-- public
| |-- css
| | `-- bootstrap.css
| |-- favicon.ico
| `-- index.html
|-- src
| |-- App.vue
| |-- assets
| | `-- logo.png
| |-- components
| | `-- Banner.vue
| |-- main.js
| |-- pages
| | |-- About.vue
| | |-- Detail.vue
| | |-- Home.vue
| | |-- Message.vue
| | `-- News.vue
| `-- router
| `-- index.js
|-- vue.config.js
`-- yarn.lock
-
main.js
import Vue from 'vue';
import App from './App';
import VueRouter from 'vue-router';
import router from './router';
//关闭生产提示
Vue.config.productionTip = false;
//安装VueRouter
Vue.use(VueRouter);
new Vue({
el: '#app',
render: h => h(App),
router
});
-
App.vue
<template>
<div>
<div class="row">
<div class="col-xs-offset-2 col-xs-8">
<div class="page-header">
<Banner/>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-2 col-xs-offset-2">
<div class="list-group">
<!-- Vue中借助router-link标签实现路由的切换 -->
<router-link :to="{name:'about'}" active-class="active" class="list-group-item">About</router-link>
<router-link active-class="active" class="list-group-item " 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';
export default {
name: 'App',
components: {
Banner
}
};
</script>
-
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
},
{
path: '/home',
component: Home,
children: [
{
path: 'news',
component: News
},
{
path: 'message',
component: Message,
children: [
{
name: 'detail',
path: 'detail/:id/:title', //使用占位符声明接收params参数
component: Detail,
//props的第一种写法,值为对象,该对象中的key和value都会以props的形式传递给Detail组件
/* props: {
a: 1,
b: 2
}*/
//props的第二种写法,值为布尔值,如果布尔值为true,就会把路由组件收到的所有params参数,以props的形式传递给Detail组件
// props: true
//props的第三种写法:值为函数,
props ($route) {
return { id: $route.params.id, title: $route.params.title };
}
/*props ({ params: { id, title } }) {
return { id, title };
}*/
}
]
},
]
},
]
});
export default router;
-
components/Banner.vue
<template>
<div>
<h2>Vue Router Demo</h2>
<button @click="back">后退</button>
<button @click="forward">前进</button>
</div>
</template>
<script>
export default {
name: 'Banner',
methods: {
forward () {
this.$router.forward();
},
back () {
this.$router.back();
}
}
};
</script>
<style scoped>
</style>
-
pages/About.vue
<template>
<div>我是About的内容</div>
</template>
<script>
export default {
name: 'About'
};
</script>
<style scoped>
</style>
-
pages/Home.vue
<template>
<div>
<h2>Home组件内容</h2>
<div>
<ul class="nav nav-tabs">
<li>
<router-link active-class="active" class="list-group-item" to="/home/news">News</router-link>
</li>
<li>
<router-link active-class="active" class="list-group-item" to="/home/message">Message</router-link>
</li>
</ul>
<!-- include里面是组件名 -->
<keep-alive include="News">
<router-view></router-view>
</keep-alive>
</div>
</div>
</template>
<script>
export default {
name: 'Home'
};
</script>
<style scoped>
</style>
-
pages/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'
};
</script>
<style scoped>
</style>
-
pages/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的对象写法 -->
<router-link :to="{
name:'detail',
params:{id:m.id,title:m.title}
}">{{ m.title }}
</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',
params: { id: m.id, title: m.title }
});
},
replaceShow (m) {
this.$router.replace({
name: 'detail',
params: { id: m.id, title: m.title }
});
}
}
};
</script>
<style scoped>
</style>
-
pages/Detail.vue
<template>
<ul>
<li>消息编号:{{ id }}</li>
<li>消息标题:{{ title }}</li>
</ul>
</template>
<script>
export default {
name: 'Detail',
mounted () {
console.log(this);
},
props: ['id', 'title']
};
</script>
<style scoped>
</style>
activated和deactivated生命周期钩子
概述
-
作用:路由组件所独有的两个钩子,用于捕获路由组件的激活状态。
-
activated
:路由组件被激活的时候触发。 -
deactivated
:路由组件失活的时候触发。
应用示例
-
示例:
-
目录结构:
|-- README.md
|-- babel.config.js
|-- package.json
|-- public
| |-- css
| | `-- bootstrap.css
| |-- favicon.ico
| `-- index.html
|-- src
| |-- App.vue
| |-- assets
| | `-- logo.png
| |-- components
| | `-- Banner.vue
| |-- main.js
| |-- pages
| | |-- About.vue
| | |-- Detail.vue
| | |-- Home.vue
| | |-- Message.vue
| | `-- News.vue
| `-- router
| `-- index.js
|-- vue.config.js
`-- yarn.lock
-
main.js
import Vue from 'vue';
import App from './App';
import VueRouter from 'vue-router';
import router from './router';
//关闭生产提示
Vue.config.productionTip = false;
//安装VueRouter
Vue.use(VueRouter);
new Vue({
el: '#app',
render: h => h(App),
router
});
-
App.vue
<template>
<div>
<div class="row">
<div class="col-xs-offset-2 col-xs-8">
<div class="page-header">
<Banner/>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-2 col-xs-offset-2">
<div class="list-group">
<!-- Vue中借助router-link标签实现路由的切换 -->
<router-link :to="{name:'about'}" active-class="active" class="list-group-item">About</router-link>
<router-link active-class="active" class="list-group-item " 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';
export default {
name: 'App',
components: {
Banner
}
};
</script>
-
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
},
{
path: '/home',
component: Home,
children: [
{
path: 'news',
component: News
},
{
path: 'message',
component: Message,
children: [
{
name: 'detail',
path: 'detail/:id/:title', //使用占位符声明接收params参数
component: Detail,
//props的第一种写法,值为对象,该对象中的key和value都会以props的形式传递给Detail组件
/* props: {
a: 1,
b: 2
}*/
//props的第二种写法,值为布尔值,如果布尔值为true,就会把路由组件收到的所有params参数,以props的形式传递给Detail组件
// props: true
//props的第三种写法:值为函数,
props ($route) {
return { id: $route.params.id, title: $route.params.title };
}
/*props ({ params: { id, title } }) {
return { id, title };
}*/
}
]
},
]
},
]
});
export default router;
-
components/Banner.vue
<template>
<div>
<h2>Vue Router Demo</h2>
<button @click="back">后退</button>
<button @click="forward">前进</button>
</div>
</template>
<script>
export default {
name: 'Banner',
methods: {
forward () {
this.$router.forward();
},
back () {
this.$router.back();
}
}
};
</script>
<style scoped>
</style>
-
pages/About.vue
<template>
<div>我是About的内容</div>
</template>
<script>
export default {
name: 'About'
};
</script>
<style scoped>
</style>
-
pages/Home.vue
<template>
<div>
<h2>Home组件内容</h2>
<div>
<ul class="nav nav-tabs">
<li>
<router-link active-class="active" class="list-group-item" to="/home/news">News</router-link>
</li>
<li>
<router-link active-class="active" class="list-group-item" to="/home/message">Message</router-link>
</li>
</ul>
<!-- include里面是组件名 -->
<keep-alive include="News">
<router-view></router-view>
</keep-alive>
</div>
</div>
</template>
<script>
export default {
name: 'Home'
};
</script>
<style scoped>
</style>
-
pages/News.vue
<template>
<ul>
<li :style="{opacity}">欢迎学习Vue</li>
<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',
data () {
return {
opacity: 1
};
},
/*
mounted () {
this.timer = setInterval(() => {
console.log('@');
this.opacity -= 0.01;
if (this.opacity <= 0) {
this.opacity = 1;
}
}, 16);
},
*/
// beforeDestroy () {
// clearInterval(this.timer);
// }
activated () {
console.log('路由组件被激活了');
this.timer = setInterval(() => {
console.log('@');
this.opacity -= 0.01;
if (this.opacity <= 0) {
this.opacity = 1;
}
}, 16);
},
deactivated () {
console.log('路由组件失活了');
clearInterval(this.timer);
}
};
</script>
<style scoped>
</style>
-
pages/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的对象写法 -->
<router-link :to="{
name:'detail',
params:{id:m.id,title:m.title}
}">{{ m.title }}
</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',
params: { id: m.id, title: m.title }
});
},
replaceShow (m) {
this.$router.replace({
name: 'detail',
params: { id: m.id, title: m.title }
});
}
}
};
</script>
<style scoped>
</style>
-
pages/Detail.vue
<template>
<ul>
<li>消息编号:{{ id }}</li>
<li>消息标题:{{ title }}</li>
</ul>
</template>
<script>
export default {
name: 'Detail',
mounted () {
console.log(this);
},
props: ['id', 'title']
};
</script>
<style scoped>
</style>
路由守卫
概述
-
作用:对路由进行权限控制。
-
分类:全局守卫、独享守卫、组件内守卫。
-
全局守卫:
//全局前置路由守卫---初始化的时候被调用、每次路由切换之前被调用
router.beforeEach((to, from, next) => {
console.log('全局前置路由守卫', to, from);
if (to.meta.isAuth) { //判断是否鉴权
if (localStorage.getItem('school') === 'suzhoudaxue') {
next();
} else {
alert('学校名不对,没有权限');
}
} else {
next();
}
});
//全局后置路由守卫---初始化的时候被调用、每次路由切换之后被调用
router.afterEach((to, from) => {
console.log('全局后置路由守卫', to, from);
document.title = to.meta.title || '后台管理系统';
});
-
独享守卫:
{
name: 'news',
path: 'news',
component: News,
meta: {
isAuth: true,
title: '新闻'
},
beforeEnter (to, from, next) { //独享守卫
if (to.meta.isAuth) { //判断是否鉴权
if (localStorage.getItem('school') === 'suzhoudaxue') {
next();
} else {
alert('学校名不对,没有权限');
}
} else {
next();
}
}
},
-
组件内守卫:
<script>
export default {
name: 'About',
beforeRouteEnter (to, from, next) {//通过路由规则,进入该组件被调用
console.log('beforeRouteEnter', to, from);
if (to.meta.isAuth) { //判断是否鉴权
if (localStorage.getItem('school') === 'suzhoudaxue') {
next();
} else {
alert('学校名不对,没有权限');
}
} else {
next();
}
},
beforeRouteLeave (to, from, next) { //通过路由规则,离开该组件被调用
console.log('beforeRouteLeave', to, from);
next();
}
};
</script>
应用示例
-
示例:
-
目录结构:
|-- README.md
|-- babel.config.js
|-- package.json
|-- public
| |-- css
| | `-- bootstrap.css
| |-- favicon.ico
| `-- index.html
|-- src
| |-- App.vue
| |-- assets
| | `-- logo.png
| |-- components
| | `-- Banner.vue
| |-- main.js
| |-- pages
| | |-- About.vue
| | |-- Detail.vue
| | |-- Home.vue
| | |-- Message.vue
| | `-- News.vue
| `-- router
| `-- index.js
|-- vue.config.js
`-- yarn.lock
-
main.js
import Vue from 'vue';
import App from './App';
import VueRouter from 'vue-router';
import router from './router';
//关闭生产提示
Vue.config.productionTip = false;
//安装VueRouter
Vue.use(VueRouter);
new Vue({
el: '#app',
render: h => h(App),
router
});
-
App.vue
<template>
<div>
<div class="row">
<div class="col-xs-offset-2 col-xs-8">
<div class="page-header">
<Banner/>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-2 col-xs-offset-2">
<div class="list-group">
<!-- Vue中借助router-link标签实现路由的切换 -->
<router-link :to="{name:'about'}" active-class="active" class="list-group-item">About</router-link>
<router-link active-class="active" class="list-group-item " 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';
export default {
name: 'App',
components: {
Banner
}
};
</script>
-
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: false,
title: '关于'
}
},
{
name: 'home',
path: '/home',
component: Home,
meta: {
isAuth: false,
title: '主页'
},
children: [
{
name: 'news',
path: 'news',
component: News,
meta: {
isAuth: true,
title: '新闻'
},
/*
beforeEnter (to, from, next) { //独享守卫
if (to.meta.isAuth) { //判断是否鉴权
if (localStorage.getItem('school') === 'suzhoudaxue') {
next();
} else {
alert('学校名不对,没有权限');
}
} else {
next();
}
}
*/
},
{
name: 'message',
path: 'message',
component: Message,
meta: {
isAuth: true,
title: '消息'
},
children: [
{
name: 'detail',
path: 'detail/:id/:title', //使用占位符声明接收params参数
component: Detail,
//props的第一种写法,值为对象,该对象中的key和value都会以props的形式传递给Detail组件
/* props: {
a: 1,
b: 2
}*/
//props的第二种写法,值为布尔值,如果布尔值为true,就会把路由组件收到的所有params参数,以props的形式传递给Detail组件
// props: true
//props的第三种写法:值为函数,
props ($route) {
return { id: $route.params.id, title: $route.params.title };
}
/*props ({ params: { id, title } }) {
return { id, title };
}*/
}
]
},
]
},
]
});
//全局前置路由守卫---初始化的时候被调用、每次路由切换之前被调用
/*
router.beforeEach((to, from, next) => {
console.log('全局前置路由守卫', to, from);
if (to.meta.isAuth) { //判断是否鉴权
if (localStorage.getItem('school') === 'suzhoudaxue') {
next();
} else {
alert('学校名不对,没有权限');
}
} else {
next();
}
});
*/
//全局后置路由守卫---初始化的时候被调用、每次路由切换之后被调用
/*
router.afterEach((to, from) => {
console.log('全局后置路由守卫', to, from);
document.title = to.meta.title || '后台管理系统';
});
*/
export default router;
-
components/Banner.vue
<template>
<div>
<h2>Vue Router Demo</h2>
<button @click="back">后退</button>
<button @click="forward">前进</button>
</div>
</template>
<script>
export default {
name: 'Banner',
methods: {
forward () {
this.$router.forward();
},
back () {
this.$router.back();
}
}
};
</script>
<style scoped>
</style>
-
pages/About.vue
<template>
<div>我是About的内容</div>
</template>
<script>
export default {
name: 'About',
beforeRouteEnter (to, from, next) {//通过路由规则,进入该组件被调用
console.log('beforeRouteEnter', to, from);
if (to.meta.isAuth) { //判断是否鉴权
if (localStorage.getItem('school') === 'suzhoudaxue') {
next();
} else {
alert('学校名不对,没有权限');
}
} else {
next();
}
},
beforeRouteLeave (to, from, next) { //通过路由规则,离开该组件被调用
console.log('beforeRouteLeave', to, from);
next();
}
};
</script>
<style scoped>
</style>
-
pages/Home.vue
<template>
<div>
<h2>Home组件内容</h2>
<div>
<ul class="nav nav-tabs">
<li>
<router-link active-class="active" class="list-group-item" to="/home/news">News</router-link>
</li>
<li>
<router-link active-class="active" class="list-group-item" to="/home/message">Message</router-link>
</li>
</ul>
<!-- include里面是组件名 -->
<keep-alive include="News">
<router-view></router-view>
</keep-alive>
</div>
</div>
</template>
<script>
export default {
name: 'Home'
};
</script>
<style scoped>
</style>
-
pages/News.vue
<template>
<ul>
<li :style="{opacity}">欢迎学习Vue</li>
<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',
data () {
return {
opacity: 1
};
},
/*
mounted () {
this.timer = setInterval(() => {
console.log('@');
this.opacity -= 0.01;
if (this.opacity <= 0) {
this.opacity = 1;
}
}, 16);
},
*/
// beforeDestroy () {
// clearInterval(this.timer);
// }
activated () {
console.log('路由组件被激活了');
this.timer = setInterval(() => {
console.log('@');
this.opacity -= 0.01;
if (this.opacity <= 0) {
this.opacity = 1;
}
}, 16);
},
deactivated () {
console.log('路由组件失活了');
clearInterval(this.timer);
}
};
</script>
<style scoped>
</style>
-
pages/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的对象写法 -->
<router-link :to="{
name:'detail',
params:{id:m.id,title:m.title}
}">{{ m.title }}
</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',
params: { id: m.id, title: m.title }
});
},
replaceShow (m) {
this.$router.replace({
name: 'detail',
params: { id: m.id, title: m.title }
});
}
}
};
</script>
<style scoped>
</style>
-
pages/Detail.vue
<template>
<ul>
<li>消息编号:{{ id }}</li>
<li>消息标题:{{ title }}</li>
</ul>
</template>
<script>
export default {
name: 'Detail',
mounted () {
console.log(this);
},
props: ['id', 'title']
};
</script>
<style scoped>
</style>
history模式和hash模式
-
对于一个url来说,
#及其后面的内容
就是hash值。 -
hash值不会包含在http请求中,即:hash值不会带给服务器。
-
hash模式:
-
① 地址中永远带着 #
号,不美观。 -
② 如果以后将地址通过第三方手机app分享,如果app校验严格,则地址会被标记为不合法。 -
③ 兼容性较好。 -
history模式:
-
① 地址干净,美观。 -
② 兼容性和hash模式相比略差。 -
③ 应用部署上线后需要后端人员支持,解决刷新页面服务器端404的问题。
vue UI组件库
Vue UI组件库介绍
移动端常用UI组件库
-
Vant:https://youzan.github.io/vant/#/zh-CN/
-
Cube UI:https://didi.github.io/cube-ui/#/zh-CN
-
Mint UI:http://mint-ui.github.io/
PC端常用UI组件库
-
Element UI:https://element.eleme.cn/#/zh-CN
-
IView UI:http://v1.iviewui.com/
Element UI的使用
下载
-
命令:
yarn add element-ui
完整引入
-
完整引入:
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
-
示例:
-
main.js
import Vue from 'vue';
//引入ElementUI组件库
import ElementUI from 'element-ui';
//引入ElementUI全部样式
import 'element-ui/lib/theme-chalk/index.css';
import App from './App';
//关闭Vue的生产提示
Vue.config.productionTip = false;
//应用ElementUI
Vue.use(ElementUI);
new Vue({
el: '#app',
render: h => h(App),
});
Element UI的使用
-
示例:
-
目录结构:
|-- README.md
|-- babel.config.js
|-- package.json
|-- public
| |-- favicon.ico
| `-- index.html
|-- src
| |-- App.vue
| |-- assets
| | `-- logo.png
| |-- components
| `-- main.js
|-- vue.config.js
`-- yarn.lock
-
main.js
import Vue from 'vue';
//引入ElementUI组件库
import ElementUI from 'element-ui';
//引入ElementUI全部样式
import 'element-ui/lib/theme-chalk/index.css';
import App from './App';
//关闭Vue的生产提示
Vue.config.productionTip = false;
//应用ElementUI
Vue.use(ElementUI);
new Vue({
el: '#app',
render: h => h(App),
});
-
App.vue
<template>
<div>
<button>原生的按钮</button>
<el-row>
<el-button>默认按钮</el-button>
<el-button type="primary">主要按钮</el-button>
<el-button type="success">成功按钮</el-button>
<el-button type="info">信息按钮</el-button>
<el-button type="warning">警告按钮</el-button>
<el-button type="danger">危险按钮</el-button>
</el-row>
<el-date-picker
v-model="value1"
type="date"
placeholder="选择日期">
</el-date-picker>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
pickerOptions: {
disabledDate(time) {
return time.getTime() > Date.now();
},
shortcuts: [{
text: '今天',
onClick(picker) {
picker.$emit('pick', new Date());
}
}, {
text: '昨天',
onClick(picker) {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24);
picker.$emit('pick', date);
}
}, {
text: '一周前',
onClick(picker) {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit('pick', date);
}
}]
},
value1: '',
};
}
};
</script>
按需引入
-
下载:
yarn add babel-plugin-component --dev
yarn add babel-preset-es2015 --dev
yarn add @babel/preset-env --dev
-
babel.config.js
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset',
['@babel/preset-env', { 'modules': false }]
],
plugins: [
[
'component',
{
'libraryName': 'element-ui',
'styleLibraryName': 'theme-chalk'
}
]
]
};
-
main.js
import Vue from 'vue';
//按需引入
import { Button, DatePicker, Row } from 'element-ui';
import App from './App';
//关闭Vue的生产提示
Vue.config.productionTip = false;
Vue.component(Button.name, Button);
Vue.component(Row.name, Row);
Vue.component(DatePicker.name, DatePicker);
new Vue({
el: '#app',
render: h => h(App),
});
-
示例:
-
目录结构:
|-- README.md
|-- babel.config.js
|-- package.json
|-- public
| |-- favicon.ico
| `-- index.html
|-- src
| |-- App.vue
| |-- assets
| | `-- logo.png
| `-- main.js
|-- vue.config.js
`-- yarn.lock
-
babel.config.js
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset',
['@babel/preset-env', { 'modules': false }]
],
plugins: [
[
'component',
{
'libraryName': 'element-ui',
'styleLibraryName': 'theme-chalk'
}
]
]
};
-
main.js
import Vue from 'vue';
//按需引入
import { Button, DatePicker, Row } from 'element-ui';
import App from './App';
//关闭Vue的生产提示
Vue.config.productionTip = false;
Vue.component(Button.name, Button);
Vue.component(Row.name, Row);
Vue.component(DatePicker.name, DatePicker);
new Vue({
el: '#app',
render: h => h(App),
});
-
App.vue
<template>
<div>
<button>原生的按钮</button>
<el-row>
<el-button>默认按钮</el-button>
<el-button type="primary">主要按钮</el-button>
<el-button type="success">成功按钮</el-button>
<el-button type="info">信息按钮</el-button>
<el-button type="warning">警告按钮</el-button>
<el-button type="danger">危险按钮</el-button>
</el-row>
<el-date-picker
v-model="value1"
type="date"
placeholder="选择日期">
</el-date-picker>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
pickerOptions: {
disabledDate(time) {
return time.getTime() > Date.now();
},
shortcuts: [{
text: '今天',
onClick(picker) {
picker.$emit('pick', new Date());
}
}, {
text: '昨天',
onClick(picker) {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24);
picker.$emit('pick', date);
}
}, {
text: '一周前',
onClick(picker) {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit('pick', date);
}
}]
},
value1: '',
};
}
};
</script>
原文始发于微信公众号(程序员阿晶):Vue高级部分(二)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/19852.html