Vue 学习总结笔记 (十二)

1. 缓存路由组件


在这里插入图片描述

keepalive标签就可以实现组件的缓存。

  • 组件缓存后,是被挂载起来,并不会被销毁的!
  • 注意:include属性里面必须是组件的属性名!!!
<div>
	<ul class="nav nav-tabs">
		<li>
			<router-link class="list-group-item" active-class="active" to="/home/news">News</router-link>
		</li>
		<li>
			<router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link>
		</li>
	</ul>
	<!-- 
		keep-alive默认是里面所有的内容全部缓存。
			include属性:定义哪个组件需要缓存!
		
		如下面就是让组件名为News的组件进行缓存。
		缓存后,这个News组件不会被销毁的。
	-->
	<!--对于单个组件缓存,直接写字符串就行。-->
	<keep-alive include="News">
		<router-view></router-view>
	</keep-alive>
	<!--对于多个组件缓存,用数组形式。-->
	<keep-alive :include="['News','Message']">
		<router-view></router-view>
	</keep-alive>
	
</div>

多个组件需要缓存,可以写成数组形式:
在这里插入图片描述


总结:
在这里插入图片描述

2. 路由组件对应的两个特别的 钩子函数


activated激活,deactivated失活。

使用场景,当我们缓存了一些组件,切换组件的时候该组件是被挂载并不会销毁,组件中的一些东西仍然是在进行的,例如:定时器;这个时候想要关闭定时器,就需要这个两个特别的钩子函数来操作了。

export default {
	name:'News',
	data(){
		return {
			opacity:1,
		}
	},
	//激活
	activated(){
		console.log('News组件被激活了')
		this.timer = setInterval(()=>{
			console.log("定时器在工作。")
			this.opacity -= 0.01
			if(this.opacity <= 0) this.opacity = 1
		})
	},
	//失活
	deactivated() {
		console.log('News组件失活了')
		clearInterval(this.timer)
	}
}

在这里插入图片描述


this.nextTick(function(){})的nextTick也是个生命周期的钩子函数。

  • 当dom元素加载完成后,再加载里面的function函数内容。

总结:
在这里插入图片描述

3. 路由守卫

3.1 全局前置路由守卫


路由守卫:负责管理路由的权限。

例如:用户在没有登录的情况下,能看到个人中心的组件么?显然是不可以的,这就由路由守卫来管理,判断有没有进入该路由组件的权限。


全局前置路由守卫(router.beforeEach()):

  • 什么时候出发全局前置守卫?初始化的时候会调用。每次切换路由之前会被调用。
  • beforeEach函数的三个参数:to参数:要去哪个路由的信息。from参数:来自哪个路由的信息。next参数:是一个函数它是放行的意思。
//该文件专门用于创建整个应用的路由器

import VueRouter from 'vue-router'

import About from '../pages/About.vue'
import Home from '../pages/Home.vue'
import News from '../pages/News.vue'
import Message from '../pages/Message.vue'
import Detail from '../pages/Detail.vue'

const router = new VueRouter({
	routes:[
		{
			name:'guanyu',
			path:'/about',
			component:About
		},
		{	
			name:'zhuye',
			path:'/home',
			component:Home,
		},
	]
})

/*
	全局前置路由守卫:
		before在...之前,each每一次的意思。
		从英文意思就是在每次切换路由之前,都会调用beforeEach里面的函数。
		此外,初始化的时候也会调用它。
		
	什么时候出发全局前置守卫?
		初始化的时候会调用。
		每次切换路由之前会被调用。
	beforeEach函数的三个参数:
		to参数:要去哪个路由的信息(路由规则)。
		from参数:来自哪个路由的信息(路由规则)。
		next参数:是一个函数它是放行的意思。
*/
router.beforeEach((to,from,next)=>{
	console.log(to)
	console.log(from)
	//接下来就是判断什么时候放行,什么时候不放行!
	//判断to里面path或者name去哪里。
	if(to.path === '/home/news' || to.path === '/home/message'){
		//模拟登录效果
		if(sessionStorage.getItem('username') === 'itholmse'){
			next()
		}else{
			alert('请先登录')
		}
		
	}else{
		next()
	}
})

//暴露router路由器
export default router

打印两个参数:
在这里插入图片描述

3.2 this.$route的meta


在这里插入图片描述
我们定义的这些都是配置对象!都是系统自己设计好的!因此,不能随便添加内容。vue为了能让我们存信息,专门设置了meta。

可以将判断的权限存到meta中,进而直接判断,避免一些繁琐的内容。

//该文件专门用于创建整个应用的路由器

import VueRouter from 'vue-router'

import About from '../pages/About.vue'
import Home from '../pages/Home.vue'
import News from '../pages/News.vue'
import Message from '../pages/Message.vue'
import Detail from '../pages/Detail.vue'

const router = new VueRouter({
	routes:[
		{
			//定义的这些都是配置对象,都是系统自己设计好的!
			name:'guanyu',
			path:'/about',
			component:About,
			//使用meta中的isAuth来做权限校验,这样就不需要乱七八糟的校验了。
			meta:{
				isAuth:false
			}
		},
		{	
			name:'zhuye',
			path:'/home',
			component:Home,
			children:[
				{
					name:'xinwen',
					path:'news',
					component:News,
					meta:{
						isAuth:true
					}
				},
				{
					name:'xiaoxi',
					path:'message',
					component:Message,
					meta:{
						isAuth:true
					},
					children:[
						{
							name:'xiangqing',
							path:'detail/:id/:title',
							component:Detail,
							props({query:{id,title}}){
								//解构赋值
								return {
									id,
									title
								}
							}
						}
					]
				}
			]
		},
	]
})

router.beforeEach((to,from,next)=>{
	// 直接判断每个路由中,meta中的isAuth来判别是否需要权限验证。
	if(to.meta.isAuth){
		if(sessionStorage.getItem('username') === 'itholmse'){
			next()
		}else{
			alert('请先登录')
		}
	}else{
		next()
	}
})

//暴露router路由器
export default router

3.3 全局后置路由守卫


全局后置路由守卫什么时候调用?

  • 初始化的使用被调用。每次路由切换之后被调用。

全局后置路由守卫的to,from参数都和前置路由守卫也一样。并且没有next()方法(不需要)。

//该文件专门用于创建整个应用的路由器

import VueRouter from 'vue-router'

import About from '../pages/About.vue'
import Home from '../pages/Home.vue'
import News from '../pages/News.vue'
import Message from '../pages/Message.vue'
import Detail from '../pages/Detail.vue'

const router = new VueRouter({
	routes:[
		{
			//我们定义的这些都是配置对象,都是系统自己设计好的!
			name:'guanyu',
			path:'/about',
			component:About,
			//使用meta中的isAuth来做权限校验,这样就不需要乱七八糟的校验了。
			meta:{
				isAuth:false,
				title:'关于'
			}
		},
		{	
			name:'zhuye',
			path:'/home',
			component:Home,
			meta:{
				isAuth:false,
				title:'主页'
			},
			children:[
				{
					name:'xinwen',
					path:'news',
					component:News,
					meta:{
						isAuth:true,
					}
				},
				{
					name:'xiaoxi',
					path:'message',
					component:Message,
					meta:{
						isAuth:true
					},
				}
			]
		},
	]
})

router.beforeEach((to,from,next)=>{
	if(to.meta.isAuth){
		if(sessionStorage.getItem('username') === 'itholmse'){
			next()
		}else{
			alert('请先登录')
		}
	}else{
		next()
	}
})

/*
	全局后置路由守卫什么时候调用?
		初始化的使用被调用。
		每次路由切换之后被调用。
	to,from参数都和全局前置路由守卫也一样。并且没有next()方法(不需要)。
*/
router.afterEach((to,from)=>{
	//当通过了全局前置路由守卫得到放行后,可以修改一些内容!
	document.title = to.meta.title || 'itholmes' // 如果为空,就让他为itholmes。
	console.log(to,from)
})


//暴露router路由器
export default router

4. 独享路由守卫


某一个路由所单独响应的路由守卫。

独享路由守卫:beforeEnter:(to,from,next)=>{} , 是在路由器配置项里面配置。

  • 注意:独享路由守卫只有前置,没有后置。
  • 如果需要在后置搞东西,直接用全局后置路由守卫也是一样的。
{
	name:'xinwen',
	path:'news',
	component:News,
	meta:{
		isAuth:true,
	},
	//独享路由守卫
	beforeEnter:(to,from,next)=>{
		if(to.meta.isAuth){
			if(sessionStorage.getItem('username') === 'itholmse'){
				next()
			}else{
				alert('请先登录')
			}
		}else{
			next()
		}
	}
},

5. 组件内路由守卫


beforeRouteEnter和beforeRouteLeave函数,是定义在组件内部的配置项中。

  • beforeRouteEnter函数是通过路由规则,进入该组件时被调用。注意是路由规则,并不是组件。
  • beforeRouteLeave函数是通过路由规则,离开该组件时被调用。同样注意是路由规则,并不是组件。
<template>
	<h2>我是About内容</h2>
</template>

<script>
	export default {
		name:'About',
		//通过路由规则,进入该组件时被调用
		//注意:这里是通过路由规则,beforeRouteEnter才会被调用。并不是看组件!
		beforeRouteEnter(to,from,next) {
			console.log('Enter == >beforeRouteEnter')
			//要放行才能进入
			next()
			// console.log(to)
			// console.log(from)
		},
		//通过路由规则,离开该组件时被调用
		// 注意:这里是通过路由规则,beforeRouteLeave才会被调用。并不是看组件!
		beforeRouteLeave(to,from,next) {
			console.log('Leave == >beforeRouteLeave')
			//要放行才能离开
			next()
		}
	}
</script>

<style>
</style>

在这里插入图片描述

6. hash模式和history模式

6.1 什么是hash?


这里平时看到的#号,叫做hash。
在这里插入图片描述


hash后面的内容是不会发给后台服务器的,不走http协议的。
在这里插入图片描述


hash后面的内容全部以hash值的形式存在的。

  • 前端的js就可以操作这些hash值,来控制。前端服务器只是一个提供html,js等资源的。这些hash值并不会传给前端服务器的。
    在这里插入图片描述

6.2 hash模式和history模式


在Vue-router中,有两种工作模式:hash模式和history模式。
在这里插入图片描述
设置history模式:
在这里插入图片描述

hash的兼容性要比history好一些。就是一些浏览器hash就能兼容。


部署前端项目后,history模式有一个严重的问题,就是当直接访问组件中的组件路径,它不识别!也就是history模式刷新404问题!
在这里插入图片描述
hash模式,因为不会收到服务器的限制,所以hash模式是可以避免history模式上面的问题的。

6.3 项目的安装,部署


项目打包:npm run build 将项目打包。
在这里插入图片描述

打包后会生成一个dist文件,会将当前项目的一些内容,转成css,js,html的文件。
在这里插入图片描述


npm init命令

npm i express命令

在这里插入图片描述

server.js文件内容:

const express = require('express')

const app = express()

//配置好进入的目录。
app.use(express.static(__dirname + '/static'))

app.get('/person',(req,resp)=>{
	resp.send({
		name:'tom',
		age:18
	})
})



app.listen(5005,(err)=>{
	if(!err){
		console.log("服务器启动成功")
	}
})

6.4 如何解决history模式刷新404问题?


问题根源就是服务器端没有固定的路径来访问:
在这里插入图片描述


我们可以在服务器端一个个配置,这样太麻烦了,可以通过第三方库解决。

对于不同的服务器,有不同的库来解决history模式刷新404问题。

对于nodejs服务器而言,可以在npmjs官方上面找到connect-history-api-fallback

安装:

  • npm install --save connect-history-api-fallback

server.js配置:

const express = require('express')

const app = express()

//解决history模式刷新404错误。
var history = require('connect-history-api-fallback');
app.use(history())

app.use(express.static(__dirname + '/static'))

app.get('/person',(req,resp)=>{
	resp.send({
		name:'tom',
		age:18
	})
})

app.listen(5005,(err)=>{
	if(!err){
		console.log("服务器启动成功")
	}
})

6.5 总结


在这里插入图片描述

7. Vue UI组件库


UI组件库分两类:移动端组件库 和 PC端组件库。
在这里插入图片描述

京东也出了一个移动端的UI组件库。叫做NutUI组件库。

饿了么团队业开发了一个PC端的组件库,ElementUI组件。

elementui是vue中的插件库。

8. elementui组件库

8.1 elementUI安装和引入


elementUI组件不用记住,如何安装,如何引入,如何使用都可以直接去官方文档上面看。

在这里插入图片描述


安装elementUI组件:

  • npm i element-ui

在main.js中引入elementUI组件库和elementUI所有样式。

import Vue from "vue"
import App from "./App.vue"

//引入vue的elementUI组件库
import ElementUI from 'element-ui';
//引入elementUI全部样式
import 'element-ui/lib/theme-chalk/index.css';
//应用elementUI插件。
Vue.use(ElementUI)

Vue.config.productionTip = false;

const vm = new Vue({
	el:'#app',
	render:h=>h(App),
})

8.2 elementUI操作


注意两种标签命名的写法规则:

<!-- 
	标签的几种格式写法:
		el-row 通过vue开发者工具查看其实也就是ElRow。
		这两种写法是最常用的!
-->
<el-row>
  <el-button>默认按钮</el-button>
  <el-button type="primary">主要按钮</el-button>
</el-row>

对于elementUI组件,只要导入了elementUI组件库和样式并且应用了(use)。

组件就可以随便调用。

如果先要修改组件的一些信息,在每一个elementui组件上面都会有标识的!
在这里插入图片描述


像刚才的main.js中引入,有一个弊端!

  • 因为我们引入了全部的elementUI样式库和组件库。这样相当于将全部的内容发给了前端,这样就会发送很多的内容!
    在这里插入图片描述
  • 因此,我们要按需引入才行!

8.3 elementUI的 按需引入


在官方也是有说到,如何进行按需引入。
在这里插入图片描述


安装 babel-plugin-component:

  • npm install babel-plugin-component -D (-D是开发依赖,还有一个生产依赖)

一个注意点:官方要修改一个.babelrc,但是babel的最新版文件已经成为了js文件。
在这里插入图片描述

因为配置文件不同了,我们只需要按照对象形式引入就可以:(babel.config.js)

module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset',
	//官方的es2015会报错的,可能是版本更新导致。
	//这里我们使用@babel/preset-env。
	["@babel/preset-env", { "modules": false }]
  ],
  plugins: [
	  [
		"component",
		{
		  "libraryName": "element-ui",
		  "styleLibraryName": "theme-chalk"
		}
	  ]
	]
}

这样我们只需要一个个引入,并且全局注册组件就可以了。
在这里插入图片描述

总结如下:

  • mian.js文件:
import Vue from "vue"
import App from "./App.vue"

/*
	完整引入:
		//引入vue的elementUI组件库
		import ElementUI from 'element-ui';
		//引入elementUI全部样式
		import 'element-ui/lib/theme-chalk/index.css';
		//应用elementUI插件。
		Vue.use(ElementUI)
*/

/*
	按需引入
		这里的引入如果标签是el-button ,那么就是引入Button,将el去掉,首字母大写。
		el-date-picker就是DatePicker,去掉el和- , 使用大驼峰写法。
*/
import {Button ,Row,DatePicker} from 'element-ui';

//这里的Button.name是就是组件名,也可以自己操作。
//内部默认就是el-button名。
Vue.component(Button.name, Button);
Vue.component('itholmes-row', Row);


Vue.config.productionTip = false;

const vm = new Vue({
	el:'#app',
	render:h=>h(App),
})

8.4 总结


不管哪个组件库,其实过程都是一样的对于vue而言。

都是导入组件库样式和引用,部分引用等等

直接看对应的官方,一步步来就可以了。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

xupengboo

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

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

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

打赏作者

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

抵扣说明:

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

余额充值