1.前端路由
1.1为什么做单页面应用
(1)传统的开发方式 url改变后,立马发送请求,响应整个页面,有可能资源过多,传统开发会让前端的页面出现 “白屏” 用户体验不好
(2)SPA 单页面应用 : 锚点值的改变后,不会立刻发送请求,而是在某个合适的时机,发送ajax请求,局部改变页面中的数据,页面不立刻跳转用户体验好
1.2前端路由的原理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<!--
SPA : Single Page Application
前端路由
1.锚点值 监视
2.ajax获取动态的数据
3.核心点是锚点值的改变
前端中 vue|react|angular 都很适合做单页面应用
-->
<a href="#/login">登录页面</a>
<a href="#/register">注册页面</a>
<div id="app">
</div>
<script type="text/javascript">
// onhashchange 事件 url上的锚点数据(#/xxx改变)
var oDiv = document.getElementById('app');
window.onhashchange = function(){
console.log(location.hash);
// 根据不同的锚点值,对页面不同的切换。
switch (location.hash) {
case '#/login':
oDiv.innerHTML = '<h2>登录页面</h2>';
break;
case '#/register':
oDiv.innerHTML = '<h2>注册页面</h2>';
break;
default:
// statements_def
break;
}
}
</script>
</body>
</html>
1.3vue-router的基本使用
npm init --yes
npm install vue-router --save
1.4vue-router集成
它是vue中核心插件
1. 下载vue-router
npm init --yes
npm install vue-router --save
- 引入vue-router的模块 默认会抛出一个VueRouter对象 另外还有两个全局的组件router-link 和router-view
2. Vue.use(VueRouter)
3. 创建路由对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script>
<!-- 1.引入 vue-router的对象 -->
<script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script>
<!-- 全局的VueRouter对象 vue-router 还给咱们提供了两个全局的组件 router-link router-view-->
<script type="text/javascript">
// 2.让Vue使用该VueRouter创建
Vue.use(VueRouter);
var Login = {
template:`
<div>登录页面</div>
`
};
var Register = {
template:`
<div>注册页面</div>
`
};
// 3.创建一个路由对象
var router = new VueRouter({
// 配置路由对象
routes:[
{
path:'/login',
component:Login
},
{
path:'/register',
component:Register
}
]
});
var App = {
template:`
<div>
<!--router-link默认会被渲染成a标签 to属性默认会被渲染成href属性-->
<router-link to="/login">登录页面</router-link>
<router-link to="/register">注册页面</router-link>
<!--路由组件的出口-->
<router-view></router-view>
</div>
`
};
new Vue({
el:'#app',
components:{
App
},
router,
template:`<App />`
});
</script>
</body>
</html>
1.5命名路由
给当前的配置路由信息对象设置name:'login'属性
:to = "{name:'login'}"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script>
<!-- 1.引入 vue-router的对象 -->
<script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script>
<!-- 全局的VueRouter对象 vue-router 还给咱们提供了两个全局的组件 router-link router-view-->
<script type="text/javascript">
// 2.让Vue使用该VueRouter创建
Vue.use(VueRouter);
var Login = {
template:`
<div>登录页面</div>
`
};
var Register = {
template:`
<div>注册页面</div>
`
};
// 3.创建一个路由对象
var router = new VueRouter({
// 配置路由对象
routes:[
{
path:'/login',
name:'login',
component:Login
},
{
path:'/register',
name:'register',
component:Register
}
]
});
var App = {
template:`
<div>
<!--router-link默认会被渲染成a标签 to属性默认会被渲染成href属性-->
<router-link :to="{name:'login'}">登录页面</router-link>
<router-link :to="{name:'register'}">注册页面</router-link>
<!--路由组件的出口-->
<router-view></router-view>
</div>
`
};
new Vue({
el:'#app',
components:{
App
},
router,
template:`<App />`
});
</script>
</body>
</html>
1.6路由范式----路由参数之params,query
(1)xxxx.html#/user/1
配置路由对象中
{
path:'/user/:id',
component:User
}
<router-link :to = "{name:'user',params:{id:1}}"></router-link>
(2)xxxx.html#/user?userId = 1
{
path:'/user'
}
<router-link :to = "{name:'user',query:{id:1}}"></router-link>
在组件内部通过this.$route 获取路由信息对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script>
<!-- 1.引入 vue-router的对象 -->
<script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script>
<!-- 全局的VueRouter对象 vue-router 还给咱们提供了两个全局的组件 router-link router-view-->
<script type="text/javascript">
// 路由范式
// (1)xxxx.html#/user/1 params
// (2)xxxx.html#/user?userId = 2 query
// 2.让Vue使用该VueRouter创建
Vue.use(VueRouter);
var UserParams = {
template:`
<div>我是用户1</div>
`,
created(){
console.log("用户1this.$route--------",this.$route);
console.log("用户1this.$route.params.userId--------",this.$route.params.userId);
// 发送ajax请求
console.log("this.$router--------",this.$router);
}
};
var UserQuery = {
template:`
<div>我是用户2</div>
`,
created(){
console.log("用户2this.$route--------",this.$route);
// 发送ajax请求
console.log("用户2this.$router--------",this.$router);
}
};
// 3.创建一个路由对象
var router = new VueRouter({
// 配置路由对象
routes:[
{
// 动态的路由参数 以冒号开头
path:'/user/:userId',
name:'userp',
component:UserParams
},
{
path:'/user',
name:'userq',
component:UserQuery
}
]
});
var App = {
template:`
<div>
<!--router-link默认会被渲染成a标签 to属性默认会被渲染成href属性-->
<router-link :to="{name:'userp',params:{userId:1}}">用户1</router-link>
<router-link :to="{name:'userq',query:{userId:2}}">用户2</router-link>
<!--路由组件的出口-->
<router-view></router-view>
</div>
`
};
new Vue({
el:'#app',
components:{
App
},
router,
template:`<App />`
});
</script>
</body>
</html>
1.7编程式导航
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script>
<!-- 1.引入 vue-router的对象 -->
<script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script>
<!-- 全局的VueRouter对象 vue-router 还给咱们提供了两个全局的组件 router-link router-view-->
<script type="text/javascript">
// 路由范式
// (1)xxxx.html#/user/1 params
// (2)xxxx.html#/user?userId = 2 query
// 2.让Vue使用该VueRouter创建
Vue.use(VueRouter);
var UserParams = {
template:`
<div>我是用户1</div>
`,
created(){
console.log("用户1this.$route--------",this.$route);
console.log("用户1this.$route.params.userId--------",this.$route.params.userId);
// 发送ajax请求
console.log("this.$router--------",this.$router);
}
};
var UserQuery = {
template:`
<div>我是用户2</div>
`,
created(){
console.log("用户2this.$route--------",this.$route);
// 发送ajax请求
console.log("用户2this.$router--------",this.$router);
}
};
// 3.创建一个路由对象
var router = new VueRouter({
// 配置路由对象
routes:[
{
// 动态的路由参数 以冒号开头
path:'/user/:userId',
name:'userp',
component:UserParams
},
{
path:'/user',
name:'userq',
component:UserQuery
}
]
});
var App = {
template:`
<div>
<button @click = 'paramsHandler'>用户1</button>
<button @click = 'queryHandler'>用户2</button>
<!--路由组件的出口-->
<router-view></router-view>
</div>
`,
methods:{
paramsHandler(){
// 编程式导航
this.$router.push({ name: 'userp', params: { userId: 123 }})
},
queryHandler(){
this.$router.push({ name: 'userq', query: { userId: 321 }})
}
}
};
new Vue({
el:'#app',
components:{
App
},
router,
template:`<App />`
});
</script>
</body>
</html>
1.8嵌套路由
一个router-view 嵌套另外一个router-view
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script>
<!-- 1.引入 vue-router的对象 -->
<script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script>
<!-- 全局的VueRouter对象 vue-router 还给咱们提供了两个全局的组件 router-link router-view-->
<script type="text/javascript">
// 嵌套路由:
// 需求:进入首页之后 点击 音乐 /home/music 电影 /home/movie
Vue.use(VueRouter);
var Home = {
template: `
<div>
<br />
<router-link to = '/home/music'>音乐</router-link>
<router-link to = '/home/movie'>电影</router-link>
<!--子路由组件的出口-->
<router-view></router-view>
</div>
`
};
var Music = {
template: `
<div>我是音乐</div>
`
};
var Movie = {
template: `
<div>我是电影</div>
`
};
// 3.创建一个路由对象
var router = new VueRouter({
// 配置路由对象
routes: [{
path: '/',
// redirect:{name:'home'}
redirect: '/home'
},
{
// 动态的路由参数 以冒号开头
path: '/home',
//这里不能使用别名,会报警告
// name:'home',
component: Home,
children: [
// 动态路由匹配 表示你的子组件中的结构是不同的
// 当访问/home时,Home组件的出口是不会渲染任何内容,这是因为没有匹配到合适的子路由
{
path: '',
component: Music
},
{
path: 'music',
component: Music,
},
{
path: 'movie',
component: Movie
}
]
}
]
});
var App = {
template: `
<div>
<router-link to = "/home">首页</router-link>
<!--路由组件的出口-->
<router-view></router-view>
</div>
`
};
new Vue({
el: '#app',
components: {
App
},
router,
template: `<App />`
});
</script>
</body>
</html>
1.9动态路由匹配
// 共同的子组件
var ComDesc = {
data() {
return {
msg: ''
}
},
template: `
<div>
我是{{msg}}
</div>
`,
created() {
// alert(1);
this.msg = 'andorid';
},
watch: {
// 提醒一下,当使用路由参数时,例如从 /user/foo 导航到 /user/bar,原来的组件实例会被复用。
//因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。
'$route' (to, from) {
// 对路由变化作出响应...
console.log("to------------------", to);
console.log("from------------------", from);
this.msg = to.params.id;
}
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script>
<!-- 1.引入 vue-router的对象 -->
<script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script>
<!-- 全局的VueRouter对象 vue-router 还给咱们提供了两个全局的组件 router-link router-view-->
<script type="text/javascript">
// 嵌套路由:
// 需求:进入首页之后 点击 音乐 /home/music 电影 /home/movie
Vue.use(VueRouter);
var Timeline = {
template: `
<div>
<router-link :to = "{name:'comDesc',params:{id:'android'}}">Android</router-link>
<router-link :to = "{name:'comDesc',params:{id:'frontend'}}">前端</router-link>
<router-view></router-view>
</div>
`
};
var Pins = {
template: `
<div>
我是沸点
</div>
`
};
// 共同的子组件
var ComDesc = {
data() {
return {
msg: ''
}
},
template: `
<div>
我是{{msg}}
</div>
`,
created() {
// alert(1);
this.msg = 'andorid';
},
watch: {
// 提醒一下,当使用路由参数时,例如从 /user/foo 导航到 /user/bar,原来的组件实例会被复用。
//因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。
'$route' (to, from) {
// 对路由变化作出响应...
console.log("to------------------", to);
console.log("from------------------", from);
this.msg = to.params.id;
}
}
}
// 3.创建一个路由对象
var router = new VueRouter({
// 配置路由对象
routes: [{
// 动态的路由参数 以冒号开头
path: '/timeline',
component: Timeline,
children: [{
path: "",
component: ComDesc
},
{
path: '/timelin/:id',
name: 'comDesc',
component: ComDesc
}
]
},
{
// 动态的路由参数 以冒号开头
path: '/pins',
name: 'pins',
component: Pins,
}
]
});
var App = {
template: `
<div>
<router-link to = "/timeline">首页</router-link>
<router-link to = "/pins">沸点</router-link>
<!--路由组件的出口-->
<router-view></router-view>
</div>
`
};
new Vue({
el: '#app',
components: {
App
},
router,
template: `<App />`
});
</script>
</body>
</html>
1.10keep-alive
<keep-alive>
<router-view></router-view>
</keep-alive>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script>
<!-- 1.引入 vue-router的对象 -->
<script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script>
<!-- 全局的VueRouter对象 vue-router 还给咱们提供了两个全局的组件 router-link router-view-->
<script type="text/javascript">
// 嵌套路由:
// 需求:进入首页之后 点击 音乐 /home/music 电影 /home/movie
Vue.use(VueRouter);
var Timeline = {
template: `
<div>
我是首页
</div>
`,
created() {
console.log('首页组件创建了');
},
mounted() {
console.log('首页组件DOM加载了')
},
destroyed() {
console.log('首页销毁了');
}
};
var Pins = {
template: `
<div>
<h3 @click = 'clickHandler'> 我是沸点</h3>
</div>
`,
methods: {
clickHandler(e) {
e.target.style.color = 'red';
}
},
created() {
console.log('沸点组件创建了');
},
mounted() {
console.log('沸点组件DOM加载了')
},
destroyed() {
console.log('沸点销毁了');
}
};
// 3.创建一个路由对象
var router = new VueRouter({
// 配置路由对象
routes: [{
// 动态的路由参数 以冒号开头
path: '/timeline',
component: Timeline
},
{
// 动态的路由参数 以冒号开头
path: '/pins',
name: 'pins',
component: Pins,
}
]
});
var App = {
template: `
<div>
<router-link to = "/timeline">首页</router-link>
<router-link to = "/pins">沸点</router-link>
<!--路由组件的出口-->
<keep-alive>
<router-view></router-view>
</keep-alive>
</div>
`
};
new Vue({
el: '#app',
components: {
App
},
router,
template: `<App />`
});
</script>
</body>
</html>
1.11路由meta实现权限控制
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script>
<!-- 1.引入 vue-router的对象 -->
<script type="text/javascript" src="./node_modules/vue-router/dist/vue-router.js"></script>
<!-- 全局的VueRouter对象 vue-router 还给咱们提供了两个全局的组件 router-link router-view-->
<script type="text/javascript">
// 嵌套路由:
// 需求:进入首页之后 点击 音乐 /home/music 电影 /home/movie
Vue.use(VueRouter);
// 导航栏上 有首页 智能题库 登录退出 四个按钮
// 用户访问首页时 看到的是首页的内容
// 1.当用户访问智能题库时,此时我们检测用户是否有权限访问该智能题库的内容,
// 如果没有 检测用户是否登录过,如果没有,则跳转登录页面,登录完成之后。
// 在localStroage中通存储该用户的用户名和密码,并且立刻跳转到智能题库页面
// 2.当用户点击黜退,该用户直接删除
var Home = {
template: `
<div>
我是首页
</div>
`
};
var Questionbank = {
template: `
<div>
我是题库
</div>
`
};
// 登录组件
var Login = {
data(){
return {
name:'',
pwd:''
}
},
template:`
<div>
<input type="text" v-model = 'name' />
<input type="text" v-model = 'pwd' />
<input type="button" value = '登录' @click = 'loginHandler'/>
</div>
`,
methods:{
loginHandler(){
alert(1);
// 要登录了
// 存储用户名会被密码 保存到 localStorage 然后跳转相应的路由(智能题库)
localStorage.setItem('user', {name:this.name,pwd:this.pwd});
// 编程式导航
this.$router.push({name:'questionbank'});
}
}
};
// 3.创建一个路由对象
var router = new VueRouter({
// 配置路由对象
routes: [{
// 动态的路由参数 以冒号开头
path: '/home',
component: Home
},
{
// 动态的路由参数 以冒号开头
path: '/questionbank',
name: 'questionbank',
component: Questionbank,
// 给未来的路由 做权限控制
meta:{
// 表明访问该组件时需要登录
auth: true
}
},
{
path:'/login',
component:Login
}
]
});
// 全局的导航守卫
router.beforeEach(function(to,from,next){
console.log(to.meta.auth);
console.log(from);
// 如果不调用next 那么页面会卡主
if(to.meta.auth){
// 用户点击了智能题库的导航 该用户未登录,需要登录判断
if (localStorage.getItem('user')) {
// 不为空 放行
next()
}else{
// 为空 进入登录页面
next({path:'/login'});
}
}else{
// 直接放行
next();
}
});
var App = {
template: `
<div>
<router-link to = "/home">首页</router-link>
<router-link to = "/questionbank">智能题库</router-link>
<router-link to = '/login'>登录</router-link>
<a href="javascript:void(0)" @click = 'clear'>退出</a>
<!--路由组件的出口-->
<keep-alive>
<router-view></router-view>
</keep-alive>
</div>
`,
methods:{
clear(){
// 退出
localStorage.removeItem('user');
this.$router.push('/login');
}
}
};
new Vue({
el: '#app',
components: {
App
},
router,
template: `<App />`
});
</script>
</body>
</html>