(zichao)VUE2基础_2(仅作简单整理,未深入探究)

目录

一、使用Vue脚手架

(一)说明

  1. Vue 脚手架是 Vue 官方提供的标准化开发工具(开发平台)。
  2. 最新的版本是 4.x。
  3. 文档: https://cli.vuejs.org/zh/。

(二)具体步骤

  1. (仅第一次执行):全局安装@vue/cli。
npm install -g @vue/cli
  1. 切换到你要创建项目的目录,然后使用命令创建项目
vue create xxxx
  1. 启动项目
npm run ***.js

(三)模板项目的结构

── node_modules
├── public
│ ├── favicon.ico: 页签图标
│ └── index.html: 主页面
├── src
│ ├── assets: 存放静态资源
│ │ └── logo.png
│ │── component: 存放组件
│ │ └── HelloWorld.vue
│ │── App.vue: 汇总所有组件
│ │── main.js: 入口文件
├──.gitignore: git 版本管制忽略的配置
├── babel.config.js: babel 的配置文件
├── package.json: 应用包配置文件
├── README.md: 应用描述文件
├── package-lock.json:包版本控制文件

(四)main.js和以前的不同之处

1、引入Vue

import Vue from 'vue'
//vue.js是完整版的Vue,包含:核心功能+模板解析器。
//vue.runtime.xxx.js是运行版的Vue,只包含:核心功能,没有模板解析器。
//因为vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,需要使用render函数接收到的createElement函数去指定具体内容。

2、render函数

//render函数完成了这个功能:将App组件放入容器中,替代了之前的components
new Vue({
	el:'#app',
	//render函数完成了这个功能:将App组件放入容器中
	render: h => h(App),
	// components:{App},
})

二、ref属性

在节点上可以设置ref属性,这样就可以获取dom节点

<button ref="btn" @click="showDOM">点我输出上方的DOM元素</button>

通过this.$refs调用

console.log(this.$refs.btn) //真实DOM元素

三、props配置

(一)作用

用来父组件给子组件传值

(二)用法

//在父元素上传入值,key=value
<Student name="李四" sex="女" :age="18"/>
//在子元素接收
//简单声明接收
props:['name','age','sex']
//接收的同时对数据进行类型限制
props:{
	name:String,
	age:Number,
	sex:String
}
//接收的同时对数据:进行类型限制+默认值的指定+必要性的限制
props:{
	name:{
		type:String, //name的类型是字符串
		required:true, //name是必要的
	},
	age:{
		type:Number,
		default:99 //默认值
	},
	sex:{
		type:String,
		required:true
	}
}
//使用
<h2>学生姓名:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
<h2>学生年龄:{{myAge+1}}</h2>

四、混合

(一)定义一个混合

创建一个mixin.js文件

export const hunhe = {
	methods: {
		showName(){
			alert(this.name)
		}
	},
	mounted() {
		console.log('你好啊!')
	},
}
export const hunhe2 = {
	data() {
		return {
			x:100,
			y:200
		}
	},
}
//向外暴露两个对象

(二)局部引用

引入一个hunhe
import {hunhe,hunhe2} from '../mixin'

export default {
	name:'School',
	data() {
		return {
				
		}
	},
	mixins:[hunhe,hunhe2],
}

(三)全局引用

在main.js中引入

//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//引入混合
import {hunhe,hunhe2} from './mixin'
//关闭Vue的生产提示
Vue.config.productionTip = false
//注册混合
Vue.mixin(hunhe)
Vue.mixin(hunhe2)

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

五、插件

  1. Vue 插件是一个包含 install 方法的对象
  2. 通过 install 方法给 Vue 或 Vue 实例添加方法, 定义全局指令
//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//引入插件
import plugins from './plugins'
//关闭Vue的生产提示
Vue.config.productionTip = false
//应用(使用)插件
Vue.use(plugins,1,2,3)
//创建vm
new Vue({
	el:'#app',
	render: h => h(App)
})


//设置一个插件,实现的一些方法
export default {
	install(Vue,x,y,z){
		console.log(x,y,z)
		//全局过滤器
		Vue.filter('mySlice',function(value){
			return value.slice(0,4)
		})

		//定义全局指令
		Vue.directive('fbind',{
			//指令与元素成功绑定时(一上来)
			bind(element,binding){
				element.value = binding.value
			},
			//指令所在元素被插入页面时
			inserted(element,binding){
				element.focus()
			},
			//指令所在的模板被重新解析时
			update(element,binding){
				element.value = binding.value
			}
		})

		//定义混入
		Vue.mixin({
			data() {
				return {
					x:100,
					y:200
				}
			},
		})

		//给Vue原型上添加一个方法(vm和vc就都能用了)
		Vue.prototype.hello = ()=>{alert('你好啊')}
	}
}

六、scoped

scoped专门加在组建的css样式上,用来防止脚手架整合时反生css样式冲突问题

<style scoped>
	.demo{
		background-color: skyblue;
	}
</style>

同时,也可以指定语言

<style lang="less(css)" scoped>
	.demo{
		background-color: pink;
		.atguigu{
			font-size: 40px;
		}
	}
</style>

七、本地存储

(一)localStorage

localStorage指在计算机本地存储,即使浏览器关闭了,数据依旧保存

//添加 key-value
localStorage.setItem('msg','hello!!!')
//读取
localStorage.getItem('msg')
//删除
localStorage.removeItem('msg2')
//清除全部
localStorage.clear()

(二)sessionStorage

sessionStorage指在浏览器存储,浏览器关闭了,数据丢失

//添加 key-value
sessionStorage.setItem('msg','hello!!!')
//读取
sessionStorage.getItem('msg')
//删除
sessionStorage.removeItem('msg2')
//清除全部
sessionStorage.clear()

八、自定义事件

需求:父组件给子组件传值

(一)props实现

//父组件使用子组件时传入父组件方法
<School :getSchoolName="getSchoolName"/>
getSchoolName(name){
	console.log('App收到了学校名:',name)
}
//子组件接收并使用
props:['getSchoolName']
sendSchoolName(){
	this.getSchoolName(this.name)
}
//实现父传子

(二)子给父传递数据(使用@或v-on)

//父组件设置绑定事件,
<Student @zichao="getStudentName"/>
getStudentName(name,...params){
	console.log('App收到了学生名:',name,params)
}
//子组件
sendStudentlName(){
	//触发Student组件实例身上的zichao事件.并传值
	this.$emit('zichao',this.name,666,888,900)
	// this.$emit('demo')
	// this.$emit('click')
},

(三)给父传递数据(使用ref)

//父组件设置ref,并绑定事件
<Student ref="student" />
mounted() {
	this.$refs.student.$on('zichao',this.getStudentName) 
	//绑定自定义事件
	this.$refs.student.$once('zichao',this.getStudentName) 
	//绑定自定义事件(一次性)
},
//子组件触发一致

九、全局事件总线

全局事件总线可以实现各个组件间传值

(一)创建事件总线

//main.js创建vm时
new Vue({
	el:'#app',
	render: h => h(App),
	beforeCreate() {
		Vue.prototype.$bus = this //安装全局事件总线
	},
})

(二)接收数据

使用$on方法

mounted() {
	this.$bus.$on('hello',(data)=>{
		console.log('我是School组件,收到了数据',data)
	})
}

(三)发送数据

使用$emit方法

methods: {
	sendStudentName(){
		this.$bus.$emit('hello',this.name)
	}
}

(四)解绑事件

使用$off方法

beforeDestroy() {
	this.$bus.$off('hello')
}

十、$nextTick

$nextTick是一个生命周期函数,当页面已经渲染过后将会调用该方法里的回调函数

什么时候用:当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行

//和之前的生命函数不同,他可以写在方法内
this.$nextTick(function(){
	//执行方法
})

十一、过度和动画

(一)原理

  1. 操作 css 的 trasition 或 animation
  2. vue 会给目标元素添加/移除特定的 clas
//定义一个动画
@keyframes zichao {
	from{
		transform: translateX(-100%);
	}
	to{
		transform: translateX(0px);
	}
}

(二)过渡的相关类名

  1. xxx-enter-active: 指定显示的 transition
  2. xxx-leave-active: 指定隐藏的 transition
  3. xxx-enter/xxx-leave-to: 指定隐藏时的样式
//必须在实现动画的元素外包裹transition,并指定name
<transition name="hello" appear>
	<h1 v-show="isShow">你好啊!</h1>
</transition>
//使用
.hello-enter-active{
	animation: zichao 0.5s linear;
}

.hello-leave-active{
	animation: zichao 0.5s linear reverse;
}
//其他类名
/* 进入的起点、离开的终点 */
.hello-enter,.hello-leave-to{
	transform: translateX(-100%);
}
.hello-enter-active,.hello-leave-active{
	transition: 0.5s linear;
}
/* 进入的终点、离开的起点 */
.hello-enter-to,.hello-leave{
	transform: translateX(0);
}

(三)引入外部动画

https://animate.style/

//引入
import 'animate.css'
//使用
<transition-group 
	appear
	name="animate__animated animate__bounce" 
	enter-active-class="animate__swing"
	leave-active-class="animate__backOutUp"
>
	<h1 v-show="!isShow" key="1">你好啊!</h1>
</transition-group>

需要用transition-group包裹需要动画元素,并设置开始和结束动画

十二、插槽

(一)默认插槽

使用slot

//在子组件使用slot定义一个插槽(挖个坑,等着组件的使用者进行填充)
<slot>我是一些默认值,当使用者没有传递具体结构时,我会出现</slot>

//在父组件中使用双标签,中间添加想在插槽中设置的元素,元素将会发在子组件设置插槽的位置
<Category title="美食" >
	<img src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="">
</Category>

(二)具名插槽

使用slot时使用name属性取名

//子组件定义一个插槽(挖个坑,等着组件的使用者进行填充)
<slot name="center">我是一些默认值,当使用者没有传递具体结构时,我会出现1</slot>
<slot name="footer">我是一些默认值,当使用者没有传递具体结构时,我会出现2</slot>

//父组件,使用slot根据名字插入
<img slot="center" src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt="">
<a slot="footer">更多美食</a>

(三)作用域插槽

数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定。

//父组件
<Category>
    <template scope="scopeData">
    <!-- 生成的是ul列表 -->
    <ul>
         <li v-for="g in scopeData.games" :key="g">{{g}}</li>
    </ul>
   	</template>
</Category>
//子组件
<template>
    <div>
        <slot :games="games"></slot>
    </div>
</template>
         		
<script>
    export default {
         name:'Category',
         props:['title'],
         //数据在子组件自身
         data() {
             return {
                games:['红色警戒','穿越火线','劲舞团','超级玛丽']
              }
         },
     }
</script>

十三、Vuex

(一)概念

在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。

(二)搭建vuex环境

1、创建文件:

src/store/index.js

 //引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//应用Vuex插件
Vue.use(Vuex)
   
//准备actions对象——响应组件中用户的动作
const actions = {}
//准备mutations对象——修改state中的数据
const mutations = {}
//准备state对象——保存具体的数据
const state = {}
   
//创建并暴露store
export default new Vuex.Store({
  actions,
  mutations,
  state
})

2、引入

main.js中创建vm时传入store配置项

//引入store
import store from './store'
......
   
//创建vm
new Vue({
   	el:'#app',
	render: h => h(App),
   	store
})

(三)基本使用

1、 初始化数据

配置actions、配置mutations,操作文件store.js

//引入Vue核心库
import Vue from 'vue'
//引入Vuex
import Vuex from 'vuex'
//引用Vuex
Vue.use(Vuex)
   
const actions = {
   	//响应组件中加的动作
   	jia(context,value){
   		context.commit('JIA',value)
   	},
}
   
const mutations = {
    //执行加
   	JIA(state,value){
   		state.sum += value
   	}
}
   
//初始化数据
const state = {
    sum:0
}
   
//创建并暴露store
export default new Vuex.Store({
   	actions,
   	mutations,
   	state,
})

2、组件中读取vuex中的数据

$store.state.sum

<h1>当前求和为:{{$store.state.sum}}</h1>

3. 组件中修改vuex中的数据

若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写dispatch,直接编写commit

$store.dispatch('action中的方法名',数据)

incrementOdd(){
	this.$store.dispatch('jia',this.n)
}

$store.commit('mutations中的方法名',数据)

increment(){
	this.$store.commit('JIA',this.n)
}

(四)getters的使用

1、概念

当state中的数据需要经过加工后再使用时,可以使用getters加工。

2、配置

store.js中追加getters配置

const getters = {
   	bigSum(state){
   		return state.sum * 10
   	}
}
   
//创建并暴露store
export default new Vuex.Store({
   	......
   	getters
})

3、读取

组件中读取数据:$store.getters.bigSum

<h3>当前求和放大10倍为:{{$store.getters.bigSum}}</h3>

(五)简洁获取state数据

1、mapState方法

用于帮助我们映射state中的数据为计算属性

computed: {
	//借助mapState生成计算属性:sum、school、subject(对象写法)
	
    ...mapState({sum:'sum',school:'school',subject:'subject'}),
            
    //借助mapState生成计算属性:sum、school、subject(数组写法)
    
    ...mapState(['sum','school','subject']),
   }

2、mapGetters方法

用于帮助我们映射getters中的数据为计算属性

computed: {
	//借助mapGetters生成计算属性:bigSum(对象写法)
    ...mapGetters({bigSum:'bigSum'}),
   
    //借助mapGetters生成计算属性:bigSum(数组写法)
    ...mapGetters(['bigSum'])
   }

(六)简洁设置方法

1、mapActions

用于帮助我们生成与actions对话的方法,即:包含$store.dispatch(xxx)的函数

methods:{
	//靠mapActions生成:incrementOdd、incrementWait(对象形式)
   	...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
   
    //靠mapActions生成:incrementOdd、incrementWait(数组形式)
    ...mapActions(['jiaOdd','jiaWait'])
   }

2、mapMutations方法

用于帮助我们生成与mutations对话的方法,即:包含$store.commit(xxx)的函数

methods:{
	//靠mapActions生成:increment、decrement(对象形式)
    ...mapMutations({increment:'JIA',decrement:'JIAN'}),
       
    //靠mapMutations生成:JIA、JIAN(对象形式)
    ...mapMutations(['JIA','JIAN']),
   }

(七)模块化+命名空间

1、修改store.js

//向外暴露两个Vuex实例
const countAbout = {
     namespaced:true,//开启命名空间
     state:{x:1},
     mutations: { ... },
     actions: { ... },
     getters: {
       bigSum(state){
          return state.sum * 10
       }
     }
}
   
const personAbout = {
     namespaced:true,//开启命名空间
     state:{ ... },
     mutations: { ... },
     actions: { ... }
}
   
const store = new Vuex.Store({
     modules: {
       countAbout,
       personAbout
     }
})
//也可以设置多个文件,统一的在index里做引入

2、开启命名空间后,组件中读取state数据

//方式一:自己直接读取
this.$store.state.personAbout.list
//方式二:借助mapState读取:
...mapState('countAbout',['sum','school','subject']),

3、开启命名空间后,组件中读取getters数据

//方式一:自己直接读取
this.$store.getters['personAbout/firstPersonName']
//方式二:借助mapGetters读取:
...mapGetters('countAbout',['bigSum'])

4、开启命名空间后,组件中调用dispatch

//方式一:自己直接dispatch
this.$store.dispatch('personAbout/addPersonWang',person)
//方式二:借助mapActions:
...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})

5、开启命名空间后,组件中调用commit

//方式一:自己直接commit
this.$store.commit('personAbout/ADD_PERSON',person)
//方式二:借助mapMutations:
...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),

十四、路由

(一)理解

理解: 一个路由(route)就是一组映射关系(key - value),多个路由需要路由器(router)进行管理。

前端路由:key是路径,value是组件。

(二)基本使用

1、安装vue-router

命令:npm i vue-router

注意版本

2. 应用插件:

Vue.use(VueRouter)

//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//引入VueRouter
import VueRouter from 'vue-router'
//引入路由器
import router from './router'

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

//创建vm
new Vue({
	el:'#app',
	render: h => h(App),
	router:router
})

3、编写router配置项

src创建router文件夹编写index.js文件

//引入VueRouter
import VueRouter from 'vue-router'
//引入Luyou 组件
import About from '../components/About'
import Home from '../components/Home'
   
//创建router实例对象,去管理一组一组的路由规则
const router = new VueRouter({
   	routes:[
   		{
   			path:'/about',
   			component:About
   		},
   		{
   			path:'/home',
   			component:Home
   		}
   	]
})
   
//暴露router
export default router

4、实现切换和指定展示位置

//router-link其实就是a标签,to属性就是要展示的组件的path
<router-link active-class="active" to="/about">About</router-link>
//指定展示位置
<router-view></router-view>

5、注意

  1. 路由组件通常存放在pages文件夹,一般组件通常存放在components文件夹。
  2. 通过切换,“隐藏”了的路由组件,默认是被销毁掉的,需要的时候再去挂载。
  3. 每个组件都有自己的$route属性,里面存储着自己的路由信息。
  4. 整个应用只有一个router,可以通过组件的$router属性获取到。

(三)多级路由

1、配置路由规则

使用children配置项

 routes:[
   	{
   		path:'/about',
   		component:About,
   	},
   	{
   		path:'/home',
   		component:Home,
   		children:[ //通过children配置子级路由
   			{
   				path:'news', //此处一定不要写:/news
   				component:News
   			},
   			{
   				path:'message',//此处一定不要写:/message
   				component:Message
   			}
   		]
   	}
]

2、跳转

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

(四)路由的query参数

1、传递参数

<!-- 跳转并携带query参数,to的字符串写法 -->
<router-link :to="/home/message/detail?id=666&title=你好">跳转</router-link>
   				
<!-- 跳转并携带query参数,to的对象写法 -->
<router-link 
   	:to="{
   		path:'/home/message/detail',
   		query:{
   		   id:666,
           title:'你好'
   		}
}"
   >跳转</router-link>

2、接收参数

//$route.query.id
//$route.query.title
<li>消息编号:{{$route.query.id}}</li>
<li>消息标题:{{$route.query.title}}</li>

(五)命名路由

1、 作用

可以简化路由的跳转。

2、 使用

{
	path:'/demo',
    component:Demo,
    children:[
    	{
      		path:'test',
      		component:Test,
      		children:
      		[
      			{
                	name:'hello' //给路由命名
      				path:'welcome',
      				component:Hello,
      			}
      		]
     	}
    ]
}

3、简化跳转

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

(六)路由的params参数

1、 配置路由

声明接收params参数

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

2、传递参数

<!-- 跳转并携带params参数,to的字符串写法 -->
//666,你好将作为参数发过去
<router-link :to="/home/message/detail/666/你好">跳转</router-link>
   				
<!-- 跳转并携带params参数,to的对象写法 -->
<router-link 
	:to="{
   		name:'xiangqing',//特别注意:路由携带params参数时,若使用to的对象写法,则不能使用path配置项,必须使用name配置!
   		params:{
			id:666,
			title:'你好'
   		}
}"
>跳转</router-link>

3、接收参数:

$route.params.id
$route.params.title
<li>消息编号:{{$route.params.id}}</li>
<li>消息标题:{{$route.params.title}}</li>

(七)路由的props配置

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

{
	name:'xiangqing',
	path:'detail/:id',
	component:Detail,

	//第一种写法:props值为对象,该对象中所有的key-value的组合最终都会通过props传给Detail组件
	props:{a:900}

	//第二种写法:props值为布尔值,布尔值为true,则把路由收到的所有params参数通过props传给Detail组件
	props:true
	
	//第三种写法:props值为函数,该函数返回的对象中每一组key-value都会通过props传给Detail组件
	props(route){
		return {
			id:route.query.id,
			title:route.query.title
		}
	}
}
//Detail组件
<li>消息编号:{{id}}</li>
<li>消息标题:{{title}}</li>

(八)<router-link>的replace属性

  1. 作用:控制路由跳转时操作浏览器历史记录的模式
  2. 浏览器的历史记录有两种写入方式:分别为pushreplacepush是追加历史记录,replace是替换当前记录。路由跳转时候默认为push
  3. 如何开启replace模式:<router-link replace .......>News</router-link>
//代码控制
this.$router.forward() //前进到
this.$router.back() //后退
this.$router.go() //可前进也可后退

(九)编程式路由导航

1、作用

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

2、具体编码

//$router的两个API
this.$router.push({
   	name:'xiangqing',
   		params:{
   			id:xxx,
   			title:xxx
   		}
})
   
this.$router.replace({
   	name:'xiangqing',
   		params:{
   			id:xxx,
   			title:xxx
   		}
})
this.$router.push()//通过push方式跳转到指定name的组件
this.$router.replace()//通过replace方式跳转到指定name的组件

(十)缓存路由组件

1、 作用

让不展示的路由组件保持挂载,不被销毁。

2、具体编码:

//添加include属性
<keep-alive include="News"> 
	<router-view></router-view>
</keep-alive>

<!-- 缓存多个路由组件 -->
<keep-alive :include="['News','Message']">
	<router-view></router-view>	
</keep-alive>

(十一)两个新的生命周期钩子

1、 activated

路由组件被激活时触发。

activated() {
	console.log('News组件被激活了')			
}

2、deactivated

路由组件失活时触发。

deactivated() {
	console.log('News组件失活了')
}

(十二)路由守卫

1、 作用:对路由进行权限控制

2、分类:全局守卫、独享守卫、组件内守卫

3、全局守卫:

//创建并暴露一个路由器
const router =  new VueRouter({
	routes:[
		{
			name:'guanyu',
			path:'/about',
			component:About,
			meta:{title:'关于'}
		},
		{
			name:'zhuye',
			path:'/home',
			component:Home,
			meta:{title:'主页'},
			children:[
				{
					name:'xinwen',
					path:'news',
					component:News,
					meta:{isAuth:true,title:'新闻'}
				},
				{
					name:'xiaoxi',
					path:'message',
					component:Message,
					meta:{isAuth:true,title:'消息'},
					children:[
						{
							name:'xiangqing',
							path:'detail',
							component:Detail,
							meta:{isAuth:true,title:'详情'},
							props($route){
								return {
									id:$route.query.id,
									title:$route.query.title,
									a:1,
									b:'hello'
								}
							}

						}
					]
				}
			]
		}
	]
})

//全局前置路由守卫————初始化的时候被调用、每次路由切换之前被调用
router.beforeEach((to,from,next)=>{
	if(to.meta.isAuth){ //判断是否需要鉴权
		if(localStorage.getItem('school')==='zichao'){
			next()
		}else{
			alert('无权限查看')
		}
	}else{
		next()
	}
})
//全局后置路由守卫————初始化的时候被调用、每次路由切换之后被调用
router.afterEach((to,from)=>{
	document.title = to.meta.title || 'zichao'
})

export default router

4、独享守卫

const router =  new VueRouter({
	routes:[
		{
			name:'guanyu',
			path:'/about',
			component:About,
			meta:{title:'关于'}
		},
		{
			name:'zhuye',
			path:'/home',
			component:Home,
			meta:{title:'主页'},
			children:[
				{
					name:'xinwen',
					path:'news',
					component:News,
					meta:{isAuth:true,title:'新闻'},
					//组件内
					beforeEnter: (to, from, next) => {
						if(to.meta.isAuth){ //判断是否需要鉴权
							if(localStorage.getItem('school')==='atguigu'){
								next()
							}else{
								alert('学校名不对,无权限查看!')
							}
						}else{
							next()
						}
					}
				}

5、组件内

//每个组件
<script>
	export default {
		name:'About',
		//通过路由规则,进入该组件时被调用
		beforeRouteEnter (to, from, next) {
			console.log('About--beforeRouteEnter',to,from)
			if(to.meta.isAuth){ //判断是否需要鉴权
				if(localStorage.getItem('school')==='atguigu'){
					next()
				}else{
					alert('学校名不对,无权限查看!')
				}
			}else{
				next()
			}
		},

		//通过路由规则,离开该组件时被调用
		beforeRouteLeave (to, from, next) {
			console.log('About--beforeRouteLeave',to,from)
			next()
		}
	}
</script>

(十三)路由器的两种工作模式

  1. 对于一个url来说,什么是hash值?—— #及其后面的内容就是hash值。
  2. hash值不会包含在 HTTP 请求中,即:hash值不会带给服务器。
  3. hash模式:
    ①地址中永远带着#号,不美观 。
    ② 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法。
    ③兼容性较好。
  4. history模式:
    ①地址干净,美观 。
    ②兼容性和hash模式相比略差。
    ③应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题。
//设置路由为history模式
const router =  new VueRouter({
	mode:'history',