project_vue
Project setup
npm install
Compiles and hot-reloads for development
npm run serve
Compiles and minifies for production
npm run build
Lints and fixes files
npm run lint
Customize configuration
笔记
一、 关于不同版本的Vue:
- 1、vue.js和vue.runtime.xxx.js的区别:
- (1)、vue.js是完整版的Vue 包含:核心功能+模板解析器
- (2)、vue.runtime.xxx.js 是运行版本地Vue 只包含:核心功能;没有模板解析器
- 2、因为vue.runtime.xxx.js没有模板解析器,所以不能使用template配置项,
需要使用render函数接收到createElement函数去指定具体内容
二、修改默认配置
-
使用vue inspect > output.js 可以查看到Vue手脚架的默认配置
-
使用Vue.config.js 可以对脚手架进行个性化定制,详情见:https://cli.vuejs.org/zh
-
在vue.config.js中修改:
- 关闭语法检查:lintOnSave:false
三、ref属性
- 被用来给元素或子组件注册引用信息(id的替代者)
- 应用在html标签上获取的真实DOM元素,应用在组件标签上是组件实例对象(vc)
- 使用方式:
- 打标识:
<h1 ref="xxx"></h1>
或<Person ref="xxx"></Person>
- 获取:this.$refs.xxx
- 打标识:
四、配置项props
功能:让组件接收外部传过来的数据
- 传递数据:
<Demo name="xxx"/>
- 接收数据:
- 只接收:
props:[‘name’]
- 限制类型:
props:{name:String}
- 限制类型、限制必要性、指定默认值:
props:{name:{type:String,required:true,default:‘xxx’}}
- 只接收:
3.备注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求要修改,则可以复制props的内容到data中一份,然后修改data中的数据
五、mixin(混入)
- 功能:可以把多个组件共用的配置提取成一个混入对象
- 使用方式:
- 第一步定义混入,例如:
{data(){…},methods:{…},… }
- 第二步使用混入,例如:
- 全局混入:Vue.mixin(xxx)
- 局部混入:mixins:[‘xxx’,‘xxxx’]
- 第一步定义混入,例如:
六、插件
-
功能:用于增强Vue
-
本质:包含install方法的一个对象,install的以一个参数是Vue,以后第二个参数是插件使用者传递的数据。
-
定义插件:
对象.install = function (Vue,options){ Vue.filter('函数名',function() { })//添加全局过滤器 Vue.directives('函数名',function() { })//添加全局指令 Vue.mixin('函数名',function() { })//配置全局混入 Vue.prototype.$myMethod = function (){ } Vue.prototype.$myPrototype = xxxx }
-
使用插件:
先引入:import plugins from "@/plugins"; 再使用:Vue.use(插件名,参数1,参数2,...)
七、scoped样式
- 作用:让样式在局部生效,防止冲突
- 写法:
<style scoped></style>
八、总结案例
- 组件化编码流程:
- 拆分静态组件:组件按照功能点拆分,命名不要与html元素冲突
- 实现动态组件:考虑好数据存放的位置,数据是一个组件在用,还是一些组件在用:
- 一个组件在用:放在组件自身即可。
- 一些组件在用:放在它们共同的父组件上(动态提升)
- 实现交互:从绑定事件开始。
- props适用于:
- 父组件 ===> 子组件 通信
- 子组件 ===> 父组件 通信 (要求父先给子一个函数,子再调用该函数)
- 使用v-model时要切记:v-model绑定的值不能是props传过来的值,因为props是只读不可修改,否则将违反原则!!!
- props传过来的若是对象类型的值,修改对象中的属性时Vue不会报错,但不推荐这种操作!!
九、webStorage (本地存储/session存储)
- 存储内容大小一般支持5MB左右(不同浏览器可能不同)
- 浏览器端通过Window.sessionStorage和Window.localStorage属性实现本地存储机制
- 相关API:
-
xxxStroage.setItem(‘key’,‘value’); 该方法接收一个键和值作为参数,会把键值对添加到存储中,如果键名存在,则更新其对应的值
-
xxxStroage.getItem(‘key’); 该方法接收一个键名作为参数,并返回键名所对应的值
-
xxxStroage.remove(‘key’); 该方法接收一个键名作为参数,并把该键名从存储中删去
-
xxxStroage.clear() 该方法会清空存储中所有的数据
-
- 备注:
- SessionStorage存储的内容会随着浏览器窗口的关闭而消失
- LocalStorage存储内容,需要手动清除才会消失
xxxStroage.getItem('key');
如果xxx对应的value获取不到,那么返回的值为nullJSON.parse(null)
的结果依然是null,读取json格式JSON.stringify(数据)
==>转换成json格式
十、组件自定义事件
- 一种组件间通信的方式,使用与:子组件 ===> 父组件
- 使用场景: A是父组件,B是子组件,B想给A传递数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)
- 绑定自定义事件:
-
第一种方式,在父组件中:
<Demo @linture="test"/>
或<Demo v-on:linture="test"/>
-
第二种方式:在父组件中:
<Demo ref="demo"/> ..... mounted(){ this.$refs.xxxx.$on('事件名',this.test(一个回调函数,写在父组件的methods中)) }
-
若想让自定义事件只能触发一次,可 使用once修饰符,或
$onec
方法
-
- 触发自定义事件:
this.$emit('linture',数据)
- 解绑自定义事件:
this.$off(事件名)
- 组件上也可以绑定原生DOM事件,需要使用
native
修饰符 - 注意:通过
this.$refs.组件名.$on('event',回调函数)
绑定自定义事件时,回调要么配置在methods中,要么使用箭头函数,否则this指向会出问题
十一、全局事件总线(GlobalEventBus)
-
一种组件间通信的方式,适用于任意组件间通信
-
安装全局事件总线:
new Vue({ .... beforeCreate(){ Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm })
-
使用事件总线:
-
接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件回调留在A组件自身
methods(){ demo(data){...} }, ....., mounted(){ this.$bus.$on('xxxx',this.demo) }
-
提供数据:
this.$bus.$emit('自定义事件名',数据)
-
-
最好在beforeDestroy钩子中,是用this. b u s . bus. bus.off(自定义事件名)去解绑当前组件所用到的事件。
十二、消息发布与订阅 (pubsub)
- 一种组件间通信的方式,适用于任意组件间通信。
- 使用步骤:
-
安装pubsub:
npm i pubsub-js
-
引入:
import pubsub from 'pubsub-js'
-
接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身
method(){ demo(消息名,数据){}, ..., mounted(){ this.pbId = pubsub.subscribe(事件名,this.demo) } } //订阅消息
-
地方提供数据:
pubsub.publish(消息名,数据)
-
最好在beforeDestroy钩子中,使用pubsub.unsubscribe(pbId)去**取消订阅**
-
十三、nextTick
- 语法:
this.$nextTick(回调函数)
- 作用:在下一次DOM更新结束后执行其指定的回调。
- 什么时候用:当改变数据后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行。
十四、Vue 封装的过渡与动画
-
作用:在插入、更新或移除DOM元素时,在合适的时候给元素添加样式类名
-
图示:
-
写法:
- 准备好样式:
- 元素进入的样式:
- v-enter:进入的起点
- v-enter-active:进入过程中
- v-enter-to:进入的终点
- 元素离开时的样式:
- v-leave:离开的起点
- v-leave-active:离开过程中
- v-leave-to:离开的终点
- 元素进入的样式:
- 使用
<transition>
包裹要过渡的元素,并配置name属性:<transition name='lin'> <h1 v-show='isShow'>hello</h1> </transition>
- 备注:若有多个元素需要过渡,则需要使用:
<transition-group>
,且每个元素都要指定key
值 - 使用 animate 提供是动画样式 用法:参考官方文档
- 准备好样式:
十五、vue脚手架配置代理
devServer:{
proxy:"http://localhost:端口号1"
}
说明:
-
优点:配置简单,请求资源时直接发给前端(端口号,一般为8080)即可
-
缺点:不能配置多个代理,不能灵活的控制请求是否走代理
3 . 工作方式:若按照上述配置代理,当请求了前端不存在的资源时,那么该请求会转发给服务器(优先匹配前端资源) -
方法二
编写vue.config.js配置具体代理规则:
devServer:{ proxy:{ '/linture':{ target:'http://localhost:5000', pathRewrite:{ '^/linture':''}, ws:true, //用于支持webSocket changeOrigin:true // 用于控制请求头中的host值 }, '/lin':{ target:'http://localhost:5001', pathRewrite:{ '^/lin':''}, ws:true, //用于支持webSocket changeOrigin:true // 用于控制请求头中的host值 } } } /* changeOrigin设置为true时,服务器收到的请求头中的host为:localhost:5000 changeOrigin设置为false时,服务器收到的请求头中的host为:localhost:8080 changeOrigin默认为true */
说明:
- 优点:可以配置多个代理,且可以灵活地控制请求是否走代理
- 缺点:配置略微繁琐,请求资源必学加前缀
十六、插槽
- 作用:让父组件可以向子组件指定位置插入html结构,也是一种组件间的通信方式,适用于 父组件===>子组件
- 分类:默认插槽、具名插槽、作用域插槽
- 使用方式:
- 默认插槽:
父组件中: <子组件名1> <div>html结构</div> </子组件名1> 子组件中: <div> <slot>插槽的内容</slot> <!--定义插槽--> </div>
- 具名插槽:
父组件中: <子组件名1> <template slot="插槽名1"> <div>html结构</div> </template> <template v-slot:插槽名2> <div>html结构</div> </template> </子组件名1> 子组件中: <div> <slot name="插槽名1">插槽的内容</slot> <!--定义插槽--> <slot name="插槽名2">插槽的内容</slot> <!--定义插槽--> </div>
- 作用域插槽:
- 理解:—数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定。(games数据在Category组件中,但使用数据遍历出来的结构由App组件决定)
- 具体编码:
父组件中: <子组件名1> <template scope="scopeData"> <!--生成的是ul列表--> <ul> <li v-for="g in scopeData.games" :key="g">{ {g}}</li> </ul> </template> <template scope="scopeData"> <!--生成的是ol列表--> <ol> <li v-for="g in scopeData.games" :key="g">{ {g}}</li> </ol> </template> <template scope="scopeData"> <!--生成的是h4列表--> <h4 v-for="g in scopeData.games" :key="g">{ {g}}</h4> </template> </子组件名1> 子组件中: <div> <slot :games="games">插槽的内容</slot> <!--定义插槽--> </div> <script> export default { name: "Category", props:['title'], data(){ return{ games:['PUBG','csgo','英雄联盟'] } } } </script>
- 默认插槽:
十七、Vuex
1.概念
在Vue中实现集中式状态(数据)管理的一个Vue插件,对Vue应用中多个组件的共享状态进行集中式管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。
2.何时使用?
多个组件需要共享数据时
3.搭建vuex环境
- 创建文件:
src/store/index.js
// 该文件用于创建Vuex中最为核心的store //引入Vue import Vue from "vue"; Vue.use(Vuex); //引入Vuex import Vuex from "vuex"; //准备actions 用于响应组件中的动作 const actions = { }; //准备mutation,用于操作数据(state) const mutations = { }; //准备state 用于存储数据 const state = { }; //创建并暴露store export default new Vuex.Store({ actions, mutations, state });
- 在
main.js
中创建vm时传入store
配置项//引入Vue import Vue from "vue"; //引入App import App from "@/App"; //引入插件$http import vueResource from "vue-resource"; //引入vuex import Vuex from 'vuex' //引入store import store from '@/store'; //关闭Vue的生产提示 Vue.config.productionTip = false; //使用插件 Vue.use(vueResource) Vue.use(Vuex) const vm = new Vue({ el:'.wrap', render: h=>h(App), store, beforeCreate() { Vue.prototype.$bus = this; } });
4.基本使用
- 初始化数据、配置
actions,mutations
,操作文件store/index.js
// 该文件用于创建Vuex中最为核心的store //引入Vue import Vue from "vue"; Vue.use(Vuex); //引入Vuex import Vuex from "vuex"; //准备actions 用于响应组件中的动作 const actions = { jia(context,value){ console.log("action 的jia被调用"); context.commit('JIA',value); }, jian(context,value){ console.log("action 的jian被调用"); context.commit('JIAN',value); }, jiaOdd(context,value){ console.log("action 的jiaOdd被调用"); if (context.state.sum % 2){ context.commit('JIAODD',value); } }, jiaWait(context,value){ console.log("action 的jiaWait被调用"); setTimeout(()=>{ context.commit('JIAWAIT',value); },1000); } }; //准备mutation,用于操作数据(state) const mutations = { JIA(state,value){ console.log("mutations 的JIA被调用") state.sum += value; }, JIAN(state,value){ console.log("mutations 的JIAN被调用") state.sum -= value; }, JIAODD(state,value){ console.log("mutations 的JIAODD被调用") state.sum += value; }, JIAWAIT(state,value){ console.log("mutations JIAWAIT") state.sum += value; } }; //准备state 用于存储数据 const state = { sum:0 }; //创建并暴露store export default new Vuex.Store({ actions, mutations, state });
- 组件中读取vuex中的数据:
$store.state.sum(属性名)
- 组件中修改vuex中的数据:
$store.dispatch('actions中的方法名',数据)
或$store.commit('mutations中的方法名',数据)
- 备注:若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写
dispatch
直接写commit
。
5.getters的使用
- 概念:当state中的数据需要经过加工后再使用,可以使用getters加工。
- 在
store/index.js
文件中追加getters
配置//准备getters 用于将state中的数据进行加工 const getters = { bigSum(state){ return state.sum*10; } } //创建并暴露store export default new Vuex.Store({ actions, mutations, state, getters });
- 组件中读取数据:
$store.getters.(getters中的方法名)bigSum
6.四个map方法使用
- mapState方法使用:用于帮我们映射
state
中的数据为计算属性computed:{ //借助mapState自动生成计算属性的代码,从state中读取数据。(对象写法) ...mapState({sum: 'sum', myName: 'myName', mySubject: 'mySubject'}), //借助mapState自动生成计算属性的代码,从state中读取数据。(数组写法) ...mapState(['sum','myName','mySubject']) }
- mapGetters方法:用于帮我们映射
getters
中的数据为计算属性computed:{ //借助mapGetters自动生成计算属性的代码,从getters中读取数据。(对象写法) ...mapGetters({bigSum:'bigSum'}), //借助mapGetters自动生成计算属性的代码,从getters中读取数据。(数组写法) ...mapGetters(['bigSum']) }
- mapActions方法:用于帮助我们生成与
actions
对话的方法,即包含$store.dispatch(xxx)
的函数methods:{ //借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(对象写法) ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'}), //借助mapActions生成对应的方法,方法中会调用dispatch去联系actions(数组写法) ...mapActions(['jiaOdd','jiaWait']) }
- mapMutations方法:用于帮助我们生成与
mutations
对话的方法,即:包含$store.commit(xxx)
的函数methods:{ //借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(对象写法) ...mapMutations({increment:'JIA',decrement:'JIAN'}), //借助mapMutations生成对应的方法,方法中会调用commit去联系mutations(数组写法) ...mapMutations(['JIA','JIAN']) }
- **备注:**mapActions与mapMutations使用时,若需要传递参数,需在模板中绑定事件时传递好参数,否则参数是事件对象
7.模块化+命名空间
- 目的:
让代码更好维护
,让多种数据分类更加明确。 - 修改
store/index.js
文件const CountOption = { namespaced:true,//开启命名空间 actions:{ jia(context,value){ console.log("action 的jia被调用"); context.commit('JIA',value); }, jian(context,value){ console.log("action 的jian被调用"); context.commit('JIAN',value); }, jiaOdd(context,value){ console.log("action 的jiaOdd被调用"); if (context.state.sum % 2){ context.commit('JIAODD',value); } }, jiaWait(context,value){ console.log("action 的jiaWait被调用"); setTimeout(()=>{ context.commit('JIAWAIT',value); },1000); } }, mutations:{ JIA(state,value){ console.log("mutations 的JIA被调用") state.sum += value; }, JIAN(state,value){ console.log("mutations 的JIAN被调用") state.sum -= value; }, JIAODD(state,value){ console.log("mutations 的JIAODD被调用") state.sum += value; }, JIAWAIT(state,value){ console.log("mutations JIAWAIT") state.sum += value; } }, state:{ sum:0,//当前和 myName:'linture', mySubject:'vue' }, getters:{ bigSum(state){ return state.sum*10; } } } const PersonOption = { namespaced:true, //开启命名空间 actions:{ addPerson(context,value){ console.log('@@',context.state.personList,value); axios.get("https://api.uixsj.cn/hitokoto/get").then( response => { let newPId = 1; let motto = '>_<'; if (context.state.personList.length>0){ newPId = context.state.personList[0].id + 1; } motto = response.data; console.log("找到啦!",response.data); const per = { id:newPId,name:value,motto:motto}; context.commit("ADD_PERSON",per); }, error => { console.log('没有找到。。。',error.message); } ) } }, mutations:{ ADD_PERSON(state,value){ state.personList.unshift(value); localStorage.setItem("personList",JSON.stringify(state.personList)); } }, state:{ personList:JSON.parse(localStorage.getItem('personList')) || [{ id:2,name:'linture',motto:'加倍爱你'},{ id:1,name:'小林',motto:'爱你'}] }, getters:{ topPerson(state){ return state.personList[0].name; } } } //创建并暴露store export default new Vuex.Store({ modules:{ CA:CountOption, PA:PersonOption } });
- 开启命名空间后,组件中读取state数据:
this.$store.state.PA.personList;//方式一:自己直接读取 ...mapState('PA',['personList']) //方式二:借助mapState读取
- 开启命名空间后,组件中读取getters数据:
this.$store.getters['PA/topPerson'];//方式一:自己直接读取 ...mapGetters('CA',['bigSum']) //方式二:借助mapGetters读取
- 开启命名空间后,组件中调用dispatch:
this.$store.dispatch('PA/addPerson',this.name);方式一:自己直接调用 ...mapActions('CA',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'}) //方式二:借助mapActions调用
- 开启命名空间后,组件中调用commit:
this.$store.commit('PA/addPerson',this.name);方式一:自己直接调用 ...mapMutations('CA',{increment:'JIA',decrement:'JIAN'}) //方式二:借助mapMutation调用
十八、路由
- 理解:一个路由(route)就是由一组映射关系(key-value),多个路由需要路由器(router)进行管理。
- 前端路由:key是路径,value是组件
- 后端路由:key是路径,value是function
1.基本使用
- 安装vue-router,命令:
npm i vue-router@3
(安装3版本,适用于vue2,默认为4版本,只能用于vue3) - 应用插件:
Vue.use(router)
- 编写router配置项:
// 该文件专门用于创建整个应用的路由器 //引入VueRouter import VueRouter from "vue-router"; import About from "@/components/About"; import Home from "@/components/Home"; //创建一个路由器,并暴露 export default new VueRouter({ routes:[ { path:'/about', component:About }, { path:'/home', component:Home } ] });
- 实现切换(active-class可以配置高亮激活样式)
<router-link class="list-group-item" active-class="active" to="/about">About</router-link> <router-link class="list-group-item" active-class="active" to="/home">Home</router-link>
- 指定展示位置:
<router-view></router-view>
2.几个注意点
- 路由组件通常存放在
pages
文件夹中,一般组件通常存放在components
文件夹中。 - 通过切换,“隐藏”了路由组件,默认是被销毁掉的,需要是再重新挂载
- 每个组件都有自己的
$route
属性,里面存储着自己的路由信息 - 整个应用只有一个router,可以通过组件的
$router
属性获取到
3.多级路由
- 配置路由规则,使用children配置项:
routes:[ { path:'/home', component:Home, children:[ //通过children配置子路由 { path: 'news', //此处一定不要写 /news component: News, }, { path: 'message', //此处一定不要写 /message component: Message, } ] }]
- 跳转(要写完整的路径)
<router-link class="list-group-item" active-class="active" to="/home/news">News</router-link> <router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link>
4.路由的query参数
- 传递参数
<!-- 跳转路由并携带query参数,to的字符串写法--> <!-- <router-link :to="`/home/message/detail?${m.id}&${m.title}`">{ {m.title}}</router-link>--> <router-link :to="{ path:'/home/message/detail', query:{ id:m.id, title:m.title } }">{ {m.title}}</router-link>
- 接收参数:
$route.query.id $route.query.title
5.路由的命名
- 作用:可以简化路由的跳转
- 如何使用
-
给路由命名:
routes:[ { path: 'message', //此处一定不要写 /message component: Message, children:[ { name:"msg", //给路由命名 path:'detail', component:Detail } ] } ]
-
简化跳转:
<router-link :to="{ name:'msg', //简化写法 // path:'/home/message/detail', //简化前 query:{ id:m.id, title:m.title } }">{ {m.title}}</router-link>
-
6. 路由的params参数
- 配置路由,声明接收params参数
routes:[ { path: 'message', //此处一定不要写 /message component: Message, children:[ { name:"msg", //给路由命名 path:'detail/:id/:msg', //必须使用占位符声明接收params参数 component:Detail } ] } ]
- 传递参数
<li v-for="m in messageList" :key="m.id"> <!-- 跳转路由并携带query参数,to的字符串写法--> <!-- <router-link :to="`/home/message/detail/${m.id}/${m.msg}`">{ {m.title}}</router-link>--> <router-link :to="{ name:'msg', //使用params必须使用name // path:'/home/message/detail', params:{ id:m.id, msg:m.msg } }">{ {m.title}}</router-link>
- 接收参数:
$route.params.id $route.params.msg
7.路由的props配置
作用:让路由组件更加方便地收到参数
const router = new VueRouter({
routes: [
{
name: "msg",
path: 'detail/:id/:msg',// ()
component: Detail,
/*
props的第一种写法:值为对象,
该对象中的所有key-value都会以props的形式传给Detail组件
*/
// props:{
// a:1,
// b:'hello'
// }
/*
* props的第二种写法:值为布尔值,
* 若布尔值为真,就会把该路由组件收到的所有params参数,以props的形式传给Detail组件
* */
props: true
/*
* props的第三种写法:值为函数
* */
// props($router){
// return{
// id:$router.query.id,
// msg:$router.query.msg
// }
// }
}]
})
8.路由对浏览器历史记录的影响
**<router-link>
**的replace属性
- 作用:控制路由跳转时操作浏览器历史记录的模式
- 浏览器的历史记录有两种写入方式:分别为
push
和replace
,push
是追加历史记录,replace
是替换当前记录。路由跳转时默认是push
- 如何开启
replace
模式:<router-link replace ...>News</router-link>
9.编程式路由导航
- 作用:不用借助
<router-link>
实现路由跳转,让路由跳转更加灵活 - 具体编码:
pushShow(m){ this.$router.push({ name:'msg', //使用params必须使用name params:{ id:m.id, msg:m.msg } }); }, replaceShow(m){ this.$router.replace({ name:'msg', //使用params必须使用name params:{ id:m.id, msg:m.msg } }); } this.$router.forward();//前进 this.$router.back();//后退 this.$router.go(2)//正数为几,则前进几步;负数为几,则后退几步
10.缓存路由组件
- 作用:让不展示的路由组件保持挂载状态,不被销毁
- 具体编码:
<!--缓存一个--> <keep-alive include="News"> <!--这里的News是组件名--> <router-view></router-view> </keep-alive> <!--缓存多个--> <keep-alive :include="['News','Message']"> <router-view></router-view> </keep-alive>
11.两个新的生命周期钩子
- 作用:路由组件所独有的两个钩子用于捕获路由组件的激活状态。
- 具体名字:
actived
路由组件被激活时触发deactived
路由组件失活时触发
12.路由守卫
- 作用:对路由进行权限控制
- 分类:全局守卫、独享守卫、组件内守卫
- 全局守卫:
//全局前置路由守卫--初始化的时候、每次路由切换之前被调用 router.beforeEach((to,from,next)=>{ // if (to.path === '/home/news' || to.path === '/home/message'){ if (to.meta.isAuth){ if (localStorage.getItem("user")==="linture"){ next(); }else{ alert("暂无权限!"); } }else { next(); } }); //全局前置路由守卫--初始化的时候、每次路由切换之后被调用 router.afterEach((to, from)=>{ document.title = to.meta.title || 'linTureStudio' ; //修改网页页签上的标题 });
- 独享路由守卫:
//在需要单独路由守卫的路由中配置beforeEnter()函数 const router = new VueRouter({ routes:[ { beforeEnter(to,from,next){ } } ] })
- 组件内守卫:
//进入守卫,通过路由规则进入组件时调用 beforeRouteEnter(to,from,next){ if (to.meta.isAuth){ if (localStorage.getItem("user")==="linture"){ next(); }else{ alert("暂无权限!"); } }else{ next(); } }, //离开守卫,通过路由规则离开组件时调用 beforeRouteLeave(to,from,next){ next(); //不写会无法离开组件 }
13.路由器的两种工作模式
- 对于一个url来说,什么是hash值?— #及其后面的内容就是hash值
- hash值不会包含在HTTP请求中,即:hash值不会带给服务器
- hash模式:
- 地址中永远带着#号,不过美观
- 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法
- 兼容性较好
- history模式:
- 地址干净,美观
- 兼容性和hash模式相比略差
- 应用部署上线是需要后端人员支持,解决刷新页面服务器端404问题
十九、Vue项目打包
npm run build 将vue文件,转换为html、css、js
生成dist目录
二十、Element-ui 的使用
参考官方文档
按需引入时需修改相应文件,官方文档中所述的.babelrc
文件不存在或找不到,应修改babel.config.js
文件,修改如下:
修改babel.config.js文件
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset',["@babel/preset-env", {
"modules": false }]
],
plugins: [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}
写在最后
个人学习尚硅谷vue2所记录的笔记,会不全,尽请指正。