西部数码网站管理助手4.0 破解版,可信网站认证不做,地铁网站建设特点,北京的网站制作公司前言
这篇笔记#xff0c;是根据B站尚硅谷的Vue2网课学习整理的#xff0c;用来学习的
如果有错误#xff0c;还请大佬指正
Vue核心
Vue简介
Vue (发音为 /vjuː/#xff0c;类似 view) 是一款用于构建用户界面的 JavaScript 框架。
它基于标准 HTML、CSS 和 JavaScr…前言
这篇笔记是根据B站尚硅谷的Vue2网课学习整理的用来学习的
如果有错误还请大佬指正
Vue核心
Vue简介
Vue (发音为 /vjuː/类似 view) 是一款用于构建用户界面的 JavaScript 框架。
它基于标准 HTML、CSS 和 JavaScript 构建
并提供了一套声明式的、组件化的编程模型帮助你高效地开发用户界面 官网:Vue.js - 渐进式 JavaScript 框架 | Vue.js (vuejs.org)
初识Vue
Vue进行工作,需要提供 Vue实例 和 模版通过 new Vue() 创建出Vue实例对象在Vue实例对象中,需要绑定模板 !--准备容器--div idtest01Hello {{word}}!!/divscript//创建Vue实例new Vue({el: #test01,//指定当前实例为那个模版服务data: {word: world}//提供数据,供指定模版使用})/script MVVM模型
Vue 仿照MVVM来进行设计
分为模型(Model),视图(View)和视图模型(ViewModel)三部分
M:模型(Model) - data中的数据V:视图(View) - 模版,即 DOMVM:视图模型(ViewModel) - Vue 实例对象 模版绑定 与 data 写法
模版绑定
方法一:
使用 el 来绑定
语法 : el : css选择器 new Vue({el: #test01,data: {word: world}})
方法二:
语法:实例对象 . $mount ( css选择器 ) const vm new Vue({data: {word: world!!!}})vm.$mount(.test01)
data写法
写法一对象式
语法data : { 数据对象 } data: {word: world!!!}
写法二函数式
必须返回一个数据对象
不要写箭头函数 data: function(){return{word:world!!!}}
模版语法
Vue 使用一种基于 HTML 的模板语法
使我们能够声明式地将其组件实例的数据绑定到呈现的 DOM 上
简单来说: 将Vue实例中的数据,呈现到 HTML 上
插值语法
可以分析标签体内容(标签包裹内容)
语法: {{JS表达式}}
示例: div idtest01Hello {{word}}!-- {{}} 中的内容会被替换为Vue实例中的数据--/divscriptnew Vue({el:#test01,data:{word:world!!!}})/script
{{ }} 中的内容会被替换为Vue实例中的数据 指令语法
可以解析标签(标签属性、标签体内容),并可以绑定事件
指令有很多,以 v- 为开头
例:v-bind: (可简写为 : ) v-bind : 标签属性 JS表达式 或 : 标签属性 JS表达式 div idtest02a v-bind:hrefProhibited未满18不要打开/a!-- 中的内容会被替换为Vue实例中的数据--/divscriptnew Vue({el: #test02,data: {Prohibited: https://store.steampowered.com/app/2358720/_/}})/script 数据绑定
单向数据绑定
语法:
v-bind : 标签属性 JS表达式 或简写为 : 标签属性 JS表达式
数据只能从data流向页面
即 修改data中的数据,同时改变页面数据
双向数据绑定
语法:
v-model:valueJS表达式 或简写为 v-modelJS表达式
用于有value的标签
数据不仅能从 data 流向页面还能从页面流向data
即 修改data中的数据,同时改变页面数据 ; 修改页面中的数据,同时改变data数据
数据代理
通过一个对象代理对另一个对象中的属性的操作读/写
Object . defineProperty
Object . defineProperty可以为对象添加属性
语法
Object . defineProperty ( 对象名 , 添加属性 , { get函数 , set函数
})
get函数需要有返回值作为添加属性的值
当读取所添加属性时get函数会被调用
当修改所添加属性时set函数会被调用 let num 18let Person {name: zhao,school: sn}Object.defineProperty(Person, age, {//读取age时调用get函数返回值为age的值get() {return num},//修改age时调用set函数修改值作为参数set(value) {num value//将参数也就是修改值传给num}}) 使用Object . defineProperty实现了Person对num的数据代理
修改Person的属性值就可以修改num
Vue中的数据代理
在Vue实例对象中data的数据存放在Vue._data中
为了更方便地操作data中的数据Vue通过Object . defineProperty
对data中数据进行了数据代理 事件处理
事件基本使用
使用指令 v-on 来进行事件绑定
语法v-on : 事件 函数名 简写事件 函数名 对应函数需要配置到Vue实例里methods对象中 divbutton v-on:clicktest01普通按钮01/button/divscriptconst vmnew Vue({el:div,methods:{test01(){console.log(11111) }}})/script
函数参数 divbutton v-on:clicktest02普通按钮02/buttonbutton v-on:clicktest03(3)普通按钮03/buttonbutton v-on:clicktest04($event,4,44)普通按钮04/button/divscriptconst vmnew Vue({el:div,methods:{test02(e){console.log(e)console.log(2222) },test03(a){console.log(a)console.log(3333) },test04(e,a,b){console.log(e,a,b)console.log(4444)}}})/script 以上代码为例
没有参数时传入事件对象test02有参数时没有事件对象test03可以用$enevt来配置事件对象test04 注
不要用箭头函数因为this将不再指向vm
事件修饰符
用于修饰事件
语法v-on : 事件 . 事件修饰符 函数名 简写事件 . 事件修饰符 函数名
事件修饰符作用prevent阻止事件的默认行为stop停止事件冒泡once事件仅触发一次capture使用事件捕获selfe.target为当前元素时触发passive默认行为立即执行再进行回调函数
示例 div classout clickworkoutdiv classin click.stopwork!--阻止事件冒泡--in/div/div
修饰符可以连写 div classin click.stop.preventwork
按键修饰符
Vue提供了一些触发键盘事件时使用的按键修饰符
用于在按下某个按键时,触发事件
语法v-on : 键盘事件 . 按键别名 函数名 简写键盘事件 . 按键别名 函数名
按键别名为Vue提供即 按键码的别名 !--在按下回车键时触发事件--input typetext keyup.enterwork
一些常用键盘别名
回车键 》enter删除键 》delete退出键 》esc空格键 》space换行键 》tab最好与keyup使用上键 》up下键 》down左键 》left右键 》right
未提供的键盘别名可以用按键Key值使用短横线命名法
系统修饰键
如ctrlaltshiftmetawin键有特殊用法
配合keyup使用 按下系统修饰键再按下并放开其他键时触发事件
配合keydown使用 按下系统修饰键即触发事件
定制按键别名
语法 Vue.config.keyCodes.自定义按键名 键码
计算属性
概念
属性Vue实例中data中的都认定为属性
计算属性所需要的属性不存在需要通过已有属性来计算获得
计算属性需要配置到Vue实例里computed对象中
语法 const vmnew Vue({el:.root,data:{属性},computed:{计算属性名:{get函数}}})
通过get函数来进行计算需要有return返回值作为计算属性的值
get调用时机
在初次读取计算属性时get调用计算属性所依赖属性数据发生变化时也会调用
备注
也可以调用set函数进行数据改动get和set函数的this均指向Vue实例计算属性会最终会出现在Vue实例上直接调用即可
案例 div classrootinput typetext v-model:valuexingbrinput typetext v-model:valuemingbrp全名{{quanming}}/p/divscriptconst vm new Vue({el: .root,data: {xing: 张,ming: 三},computed: {quanming: {get() {return this.xing this.ming}}}})/script
简写
在没有写set函数时可以使用简写
语法 computed: {计算属性名() {函数体}} computed: {quanming() {return this.xing this.ming}}
监视属性
概念与语法
可以设置被监视的属性当被监视属性发生改变时会自行调用函数
写法1 const vm new Vue({el: div,watch: {监视属性名: {immediate: 布尔值,//默认为false是否初始化时调用deep: 布尔值,//默认为false是否开启深度监视handler(newValue, oldValue) {//newValue为新值oldValue为旧值函数体}}}})
写法2 vm.$watch(监视属性名, {immediate: 布尔值,//默认为false是否初始化时调用deep: 布尔值,//默认为false是否开启深度监视handler(newValue, oldValue) {//newValue为新值oldValue为旧值函数体}})
在监视属性改变时会调用handler函数
深度监视
配置deep: true时开启深度监视
Vue中watch默认不检测对象内部值的改变
开启深度监视可以检测对象内部值的改变
简写
当deep和immediate均没有配置时可以简写
简写1 const vm new Vue({el: div,watch: {监视属性名(newValue, oldValue): {//newValue为新值oldValue为旧值函数体}}})
简写2 vm.$watch(监视属性名, function(newValue, oldValue){//newValue为新值oldValue为旧值函数体})
计算属性与监听属性区别
computed相当于watch更加简单computed能完成的watch均能完成watch能完成的computed不一定能完成watch可进行异步操作
绑定样式
绑定class
1.字符串写法
直接使用v-bind来绑定样式
可以绑定事件来动态改变类名 div classmain :classmood{{text}}/div
headstyle.main {width: 100px;height: 100px;border: 1px solid black;}.test01 {background-color: aqua;}/stylescript src../vue.js/script
/headbodydiv idrootdiv classmain :classmood{{text}}/div/divscriptconst vm new Vue({el: #root,data: {text: 111,mood: test01,}})/script
/body
2.数组写法
用于绑定多个样式
可以通过动态操作数组来控制类
headstyle.work01 {font-size: 20px;}.work02 {color: aqua;}.work03 {font-style: italic;}/stylescript src../vue.js/script
/headbodydiv idrootdiv classmain :classclassArr{{text}}/div/divscriptconst vm new Vue({el: #root,data: {text: 111,classArr: [work01, work02, work03]}})/script
/body
3.对象写法
用于绑定多个样式并动态决定用与不用
控制对象中的布尔值动态决定类的用与不用
headstyle.work01 {font-size: 20px;}.work02 {color: aqua;}.work03 {font-style: italic;}/stylescript src../vue.js/script
/headbodydiv idrootdiv classmain :classclassObj{{text}}/div/divscriptconst vm new Vue({el: #root,data: {text: 111,classObj: {work01: true,work02: true,work03: true,}}})/script
/body
绑定style
1.直接绑定
直接使用v-bind来绑定样式
语法 : style { 属性(驼峰命名法) : xxx } xxx为Vue示例中的data数据 div idrootdiv classmain :style{fontSize:fs}{{text}}/div/divscriptconst vm new Vue({el: #root,data: {text: 1111,fs:20px}})/script
2.对象写法 div idrootdiv classmain :stylestyleObj{{text}}/div/divscriptconst vm new Vue({el: #root,data: {text: 1111,styleObj: {fontSize: 40px,backgroundColor: aqua}}})/script
3.数组写法
需要在数组中配置对象 div idrootdiv classmain :stylestyleArr{{text}}/div/divscriptconst vm new Vue({el: #root,data: {text: 1111,styleArr: [{fontSize: 40px,backgroundColor: aqua},{color: blue}]}})/script
条件渲染
v-show
语法 v-show “ 表达式 ” 表达式值为布尔值
表达式值为false元素被隐藏display值为none
v-if
语法 v-if “ 表达式 ” 后可接v-else-if和v-else 表达式值为布尔值
表达式值为false时元素直接被删除替换为空注释 div idrootdiv v-showfalse{{test01}}/divdiv v-showtrue{{test01}}/divbrdiv v-iffalse{{test02}}/divdiv v-iftrue{{test02}}/div/divscriptconst vmnew Vue({el:#root,data:{test01:111,test02:222}})/script 列表渲染
v-for遍历
遍历对象
语法 v-for ( value , key) in 对象名 或 v-for value in 对象名 value获取属性值key获取属性名 div idrootli v-for(value,key) in Person{{value}}----{{key}}/li/divscriptconst vmnew Vue({el:#root,data:{Person:{name:Tom,age:18,shool:sdau}}})/script 遍历数组
语法 v-for ( value , item) in 数组名 或 v-for value in 对象名 value获取值item获取索引 div idrootli v-for(value,item) in Arr{{value}}----{{item}}/li/divscriptconst vm new Vue({el: #root,data: {Arr: [A,B,C]}})/script key的使用与作用
key的使用
在 v-for遍历 中要添加一个 key属性
key值的选择最好使用每条数据的唯一标识
例如ID身份证学号等等
如果不添加 key属性 则key值默认为数组或对象的序列号 div idrootli v-for(p,item) in Person :keyp.id{{p.name}}---{{p.age}}/li/divscriptconst vmnew Vue({el:#root,data:{Person:[{id:001,name:wu,age:18},{id:002,name:liu,age:20},{id:003,name:zhao,age:19},]}})/script
key的作用和虚拟DOM
虚拟DOM是Vue根据数据生成的
key是虚拟DOM对象的标识可以理解成虚拟DOM对象的唯一ID
当数据发生改变时Vue会根据新数据生成新虚拟DOM
新旧DOM会进行对比
1.若有相同的key值
若虚拟DOM内容没有变直接使用真实DOM生成页面若虚拟DOM内容变化生成新真实DOM替换之前的
2.若没有相同的key值
直接建立真实DOM生成页面
Vue监视数据原理
基本
Vue会监视data中所有有层次的数据
被监视的对象会添加get和set函数以实现响应式
( get和set函数用自Object . defineProperty)
示例 data: {Person: {name: Tom,age: 18,shool: sdau},Arr: [A,B,C]} 注数组中的数据没有进行监视但数组本身被监视
如上图Arr数组有get和set函数
如下图Arr[0]以及其他数据没有get和set函数 关于对象
对象中的数据通过 get和set函数 监视
对象中后追加的属性Vue不会进行监视即不会有get和set函数
如果需要监视追加的属性则需要用到 特定API
语法 Vue.set(对象名,属性名,属性值) 另一种写法this.$set(对象名,属性名,属性值)
对象名指被添加属性的对象注意
示例给Person对象添加sex属性属性值为 男 addSex() {//Vue.set(this.Person,sex,男) 另一种写法this.$set(this.Person, sex, 男)}
用此API添加的属性拥有get和set函数会被监视
注 该API不能给vm或vm的根数据对象data等添加属性
关于数组 因为Vue中数组没有get和set函数
所有Vue通过其他方式来实现数组数据的响应式
在数组中修改数据必须使用以下方法
使用APIpush(),pop(),shift(),unshift(),splice(),sort(),reverse()使用Vue.set() 或 vm.$set(). Vue.set(数组名,序列,修改值) 另一种写法this.$set(数组名,序列,修改值)
只有使用以上方法数组数据才可以实现响应式
当然也可以直接修改数组本身因为数组本身有get和set函数
过滤器
定义 对要显示的数据进行特定格式化后再显示用于一些简单的逻辑处理
注册过滤器两种方式: Vue.filters(过滤器名称,function(){函数体})//全局过滤器或new Vue({filters:{过滤器名称(){函数体}}})//局部过滤器
使用过滤器
过滤器可以用于插值语法 和 v-bind指令
{{ xxx | 过滤器名称 }}v-bind:属性 xxx | 过滤器名称
常见内置指令
之前接触过的指令
指令作用简写v-bind单向绑定解析表达式:xxv-model双向数据绑定v-modelxxv-for遍历数组/对象/字符串无v-on绑定事件监听v-if / v-else条件渲染控制节点是否存在无v-show条件渲染控制节点是否展示无
v-text指令
作用 向所在节点渲染文本 div idrootp{{name}}/pp v-textname/pp v-textname1111/p/divscriptnew Vue({el:#root,data:{name:zhao}})/script 注 v-text会替换掉节点中的内容
v-html指令
作用 向指定节点中渲染包含html结构的内容 可以识别html结构 div idrootdiv v-htmltest/div/divscriptnew Vue({el:#root,data:{test:p123456/p}})/script 注v-html有安全性问题 在网站上动态渲染任意HTML非常危险容易导致xss攻击在可信内容上使用v-html不用用在用户提交内容上
v-cloak指令
在网速非常慢的时候可能会展示未经过Vue渲染的页面
因为网速慢Vue会加载不出来
可以使用v-cloak指令配合CSS来解决
v-cloak没有值v-cloak本质是一个属性v-cloak在Vue加载完成后删除 style[v-cloak]{display: none;}/stylediv idrootdiv v-cloak111/div/divv-once指令
v-once没有值v-once所在节点只进行初次动态渲染初次动态渲染完成后变为静态内容以后数据变化不会引起所在结构改变
v-pre指令
用于跳过其所在节点的编译过程 p v-pre{{name}}/p 自定义指令
函数式
自定义指令可以通过配置到Vue实例里directives对象中来实现
语法 new Vue({directives:{指令名(element,binding){函数体}}})
其中传入的参数
element为绑定自定义指令标签的DOM对象
binding为DOM对象的相关属性
绑定自定义指令时要加v- div classrootp v-test011111/p/divscriptconst vmnew Vue({el:.root,directives:{test01(element,binding){console.log(element,binding)}}})/script 自定义指令中函数调用时机
指令与元素成功绑定时函数调用指令所在模板重新解析时函数调用
注命名如果有多个单词使用 - 链接
对象式
对象式自定义指令函数调用时机更加细致会比函数时多一次调用
语法 new Vue({directives:{指令名:{bind(element,binding){函数体},inserted(element,binding){函数体},update(element,binding){函数体}}}})
传入的参数同函数式
函数调用时机
bind函数指令与元素绑定成功时调用inserted函数指令所在元素被插入页面时调用update函数指令指令所在模板重新解析时调用
全局自定义指令
通过在Vue实例中配置directives对象所设置的为局部指令
全局自定义指令语法 Vue.directive(指令名,配置对象) Vue.directive(指令名,回调函数) div classrootdiv v-test0333/divdiv v-test0444/div/divscriptVue.directive(test03, {bind(element, binding) {console.log(element, binding)},inserted(element, binding) {console.log(element, binding)},update(element, binding) {console.log(element, binding)}})Vue.directive(test04,function(element, binding){console.log(element, binding)})/script
生命周期
概念
生命周期 又名生命周期回调函数生命周期函数生命周期钩子
生命周期本质上就是函数
Vue会在特殊时刻帮我们调用的一些特殊名称的函数
生命周期函数名字不可更改其配置在Vue实例中其中this指向Vue示例
示例以mounted为例 scriptconst vm new Vue({el: #root,mounted() {console.log(this)},})/script
“Vue的一生”
创建出生
Vue刚刚创建仅完成初始化此时数据监测和数据代理创建还未开始
初始化完成后进行数据监测和数据代理创建时会调用两个生命周期函数不是Vue创建时
此时 模板未解析
1.数据监测和数据代理之前初始化后
调用beforeCreate函数此时无法通过vm访问data中的数据methods中的方法因为数据监测和数据代理未完成
2.数据监测和数据代理之后解析模板之前
调用created函数此时可以通过vm访问data中的数据methods中的方法因为模板未解析页面不会显示解析内容
挂载生活
挂载即把初始的真实DOM元素放到页面
在Vue解析完模板生成虚拟DOM后进行虚拟DOM转真实DOM
此时调用两个生命周期函数
1.解析完模板后挂载完成前
调用beforeMount函数页面此时呈现未未经Vue编译的DOM所有对DOM的操作最终都不会奏效
2.挂载完成后
调用mounted函数对DOM的操作有效但尽量避免此时可以进行一些初始化操作比如开启定时器发送网络需求等
更新颠覆三观
在数据更新时会调用两个生命周期函数
1.新虚拟DOM生成前
调用beforeUpdate函数此时Data数据是新的但是页面没有进行更新
2.页面更新后
调用updated函数此时Data数据和页面都是新的
销毁逝世
Vue可以通过Vue.$destroy()来销毁
销毁时会调用两个生命周期函数
1.销毁前回光返照
调用beforeDestroy函数此时Vue的所有配置都还可以使用即将销毁一般在此阶段进行关闭定时器取消订阅的收尾操作
2.销毁后已寄
可以调用destroyed函数但Vue以及没有
注意事项
常用生命周期钩子
mounted:初始化操作beforeDestroy:收尾操作
关于销毁Vue
销毁后自定义事件失效但原生DOM事件依然有效一般不会使用beforeDestroy操作Data数据因为用不到了
Vue组件化编程
组件
实现应用中局部功能代码和资源的集合
扒一张官网的图下图
在一个大盒子中可以分三个中盒子灰色 中盒子又可以分成几个小盒子深灰色
这几个盒子中代码和资源的集合可以视为一个组件 作用组件可以复用编码简化项目编码
当应用中的功能都是多组件的方式来编写的那这个应用就是一个组件化的应用
非单文件组件
特点一个文件中包含多个组件
Vue使用组件有三步
定义组件创建组件注册组件使用组件
定义组件创建组件
定义组件需要使用Vue.extend()在全局中进行定义
其中()中传入的内容与 new Vue()需要传入的几乎一模一样
区别
不写el配置最终所有组件由vm中的el来决定服务于那个容器data必须写出函数式避免数据存在引用关系使用template配置组件结构
示例 //定义组件const Person Vue.extend({template: divp{{name}}--{{age}}/p/div,data() {return {name: zhao,age: 18}}})
注册组件
1.局部注册
在Vue实例中配置components对象 const vm new Vue({el: #Root,//注册局部组件components: {Person: Person//简写Person}})
2.全局注册
语法 Vue.component(组件名, 组件) //注册全局组件Vue.component(School, School)
使用组件
在HTML中编写组件标签即可 div idRoot!--使用组件--Person/PersonbrSchool/School/div
示例代码
bodydiv idRoot!--使用组件--Person/PersonbrSchool/School/divscript//定义组件const Person Vue.extend({template: divp{{name}}--{{age}}/p/div,data() {return {name: zhao,age: 18}}})const School Vue.extend({template: divp{{name}}--{{address}}/p/div,data() {return {name: sdau,address: 泰安}}})//注册全局组件Vue.component(School, School)const vm new Vue({el: #Root,//注册局部组件components: {Person: Person//简写Person}})/script
/body
注意事项
组件名
组件名如果由多个单词组成使用kebab-case命名法my-school也可以使用CamelCase命名MySchool但是需要Vue脚手架可以使用name配置指定组件在开发者工具中呈现的名字 const School Vue.extend({name:xxx,template: divp{{name}}--{{address}}/p/div,data() {return {name: sdau,address: 泰安}}}) 简写 const School Vue.extend(options)
简写为 const School options
组件其他事项
组件的嵌套
组件可以注册在组件中实现组件的嵌套
示例
bodydiv idRootApp/App/divscriptconst School Vue.extend({template: div{{name}}--{{address}}/div,data() {return {name: sdau,address: 泰安}}})const Person Vue.extend({template: div{{name}}--{{age}}/div,data() {return {name: zhao,age: 18}}})const App Vue.extend({template: divPerson/PersonSchool/School/div,components: {School,Person}})const vm new Vue({el: #Root,components: {App}})/script
/body VueComponent
组件的本质是一个名为VueComponent的构造函数由Vue.extend生成
在我们使用组件时Vue会解析并创建出组件的实例对象
即Vue会帮我们调用 new VueComponent(options)
另外每次调用Vue.extend返回值都是一个全新的VueComponent
关于this指向
组件配置中this指向均是【VueComponent实例对象】new Vue()配置中this指向均是【Vue实例对象】
一个内置关系
在Vue中组件原型对象 的 原型 为Vue示例的 原型对象
即VueComponent.prototype.__proto__Vue.prototype
可以让组件实例对象可以访问到Vue原型上的属性和方法
单文件组件
特点一个文件中只包含1个组件
将非单文件组件中的多个组件进行拆分写到多个文件中每个文件就是一个组件
每个组件文件的后缀为 .vue
通过ES6模块化语法进行导出和引入 导出
组件文件写法
其中使用 export default { } 来导出组件
templatediv模板/div
/templatescript//导出export default {Vue配置项};
/scriptstyle样式 /*可省略*/
/style
示例
templatediv classtesth2{{ name }}--{{ address }}/h2button clickshow123456/button/div
/templatescript
export default {name: SchoolName,data() {return {name: sdau,address: 山东泰安,};},methods: {show() {alert(123456);},},
};
/scriptstyle
.test {background-color: aqua;
}
/style
引入
引入可以使用 import···from··· 来引入
import 组件名 from 组件地址;
示例
templatedivPersonName/PersonNameSchoolName/SchoolName/div
/templatescript
import PersonName from ./components/PersonName.vue;
import SchoolName from ./components/SchoolName.vue;
export default {name: App,components: {PersonName,SchoolName,},
};
/script
ref属性
ref属性用来给元素或子组件注册引用信息id属性的替代者
语法
标记(示例)h1 refxxx···h1 或 组件名 refxxx···/组件名获取this.$refs.xxx
关于获取值
应用在html标签上获取真实DOM元素应用在组件标签上获取组件示例对象
templatediv idappimg refimg altVue logo src./assets/logo.png /HelloWorld refhello msgWelcome to Your Vue.js App /button clickshow按钮/button/div
/templatescript
import HelloWorld from ./components/HelloWorld.vue;export default {name: App,components: {HelloWorld,},methods: {show() {console.log(this.$refs);//返回对象console.log(this.$refs.img);//返回真实DOMconsole.log(this.$refs.hello);//返回组件示例对象},},
};
/script 配置项props
配置项props可以让组件接受外部传来的数据
当父组件引入其他组件父组件所需数据子组件没有时
可以使用配置项props通过父组件给子组件数据赋值
是一种组件间的通信方式将数据从父组件传递给子组件
传递与接收
1.传递方父组件 子组件名 数据名 值 /将传入的值传递给子组件
2.接收方子组件 props:[数据名]
接收到父组件传递来的数据 示例
App.vue(传递方部分代码):
templatediv idappMyPerson namezhao/!--传递--/div
/template
MyPerson(接收方部分代码):
templatedivh1{{ name }}--{{ age }}/h1/div
/templatescript
export default {name: MyPerson,data() {return {age: 18,};},props:[name]//接收
};
/script 接收的三种方法
接收数据共有三种方法
1.只接收 props:[name]
2.限制类型 props:{name:String//限制name为字符串}
3.限制类型与必要性指定默认值 props: {name: {type: String, //限制name为字符串required: true, //必要性default: zhao, //默认值},},
必要性父组件必须传值
必要性与默认值一般不在一起使用有矛盾
mixin混入
功能将多个组件共用的配置进行提取成为一个混入对象进行使用
定义混入
混入可以定义在另一个JS文件中
即多个组件都有的配置提取到一个JS文件中
export const test{methods:{show(){console.log(this.name);}}
}
通过导出以便于组件使用
使用混入
局部混入
在引入混入后可以通过mixins配置项来使用混入
templatedivh1{{name}}--{{age}}/h1button clickshow123/button/div
/templatescript
import {test} from ./mixin.jsexport default {name:MyPerson,data(){return{name:zhao,age:18}},mixins:[test]
}
/script
全局混入
可以直接在App组件中引入混入使用Vue.mixin(xxx)来进行全局混入
import {test} from ./components/mixin
Vue.mixin(test)
插件
功能用于增强Vue
本质插件本质上是一个对象其中含有一个install方法
install的第一个参数是Vue所有插件可以实现各种功能
定义插件
对象名.install function(Vue){函数体
}
使用插件
Vue.use(对象名)
scoped样式
在Vue组件化编程中每个组件的样式也会影响到其他的组件产生冲突
作用 可以让样式在局部生效防止冲突
写法 style scoped
组件自定义事件
组件自定义事件是一种组件间的通信方式将数据从子组件传递给父组件
绑定
绑定自定义事件都是在父组件中
方法一
直接在父组件中给子组件绑定事件 MyPerson gainPgetPersonName /
如上为子组件MyPerosn绑定名为gainP的事件
触发事件调用getPersonName回调函数
方法二
在生命周期钩子中绑定用到ref属性 MySchool refdome /......mounted() {this.$refs.dome.$on(gainS, this.getSchoolName);},如上为子组件MySchool绑定名为gainS的事件
触发事件调用getSchoolName回调函数
整体代码示例父组件
templatediv idappp{{ PersonName }}//{{ SchoolName }}/pMyPerson gainPgetPersonName /MySchool refdome //div
/templatescript
import MyPerson from ./components/MyPerson.vue;
import MySchool from ./components/MySchool.vue;
export default {name: App,components: {MyPerson,MySchool,},data() {return {PersonName: ,SchoolName: ,};},methods: {getPersonName(test) {this.PersonName test;},getSchoolName(test) {this.SchoolName test;},},mounted() {this.$refs.dome.$on(gainS, this.getSchoolName);},
};
/script
触发
触发自定义事件都是在子组件中
通过触发原生事件来触发自定义事件
语法 this.$emit(自定义事件名, 传入数据);
示例 button clickgivePerosnName触发事件/button......methods: {givePerosnName() {this.$emit(gainP, this.Name);},},如上触发按钮点击事件调用givePerosnName函数
在givePerosnName函数中触发gainP自定义事件
并且传入数据this.Name
解绑
解绑事件也是在子组件中
语法 this.$off(自定义事件名); 示例 button clickrelieve解绑事件/button......methods: {relieve() {this.$off(gainP);},},如上触发按钮点击事件调用relieve函数
在relieve函数中解绑gainP自定义事件
其他
组件可以绑定原生DOM事件但是需要 native 修饰符通过方法二来绑定事件时回调函数要配置在methods中或用箭头函数这样this指向正常为父组件。使用普通函数this指向子组件。
全局事件总线
全局事件总线是一种组件之间的通信方式可以用于任意组件间通信
其并非Vue所提供的方法而是一种思路所以写法不唯一
核心思想是找到一个各个组件均可进行通信的中介来进行任意组件间的通信
虽然写法不唯一但只记一种
安装全局事件总线
中介可以创建在Vue实例对象的原型上
通过生命周期钩子在Vue实例对象创建完成前安装
在main.js中
new Vue({render: h h(App),beforeCreate() {Vue.prototype.$bus this}
}).$mount(#app)
如上创建名为$bus的中介
使用全局事件总线
接收
接收数据要在接收方组件中给中介$bus绑定自定义事件
事件的回调配置在接收方组件中 methods: {getPersonName(test) {this.PersonName test;},},mounted() {this.$bus.$on(gainP,this.getPersonName)},
如上
为$bus绑定gainP的自定义事件函数回调在组件methods配置中
另外最好在beforeDestroy生命周期钩子中用$off解绑当前组件所用事件
提供
提供数据只需要在提供方触发$bus的自定义事件即可 this.$bus.$emit(gainP, this.Name);
消息订阅与发布
消息订阅与发布是一种组件之间的通信方式可以用于任意组件间通信
1.安装
需要安装pubsub npm i pubsub-js
2.引入
import pubsub from pubsub-js
3.接收数据 methods: {dome(){......}},mounted(){this.pidpubsub.subscribe(xxx,this.dome)//订阅消息}
4.提供数据 pubsub.publish(xxx,数据)
5.取消订阅 PubSub.unsubscribe(pid)
插槽
作用是一种组件间的通信方式可以让父组件向子组件指定位置插入HTML结构 是一种将数据从父组件传递给子组件的方式
默认插槽
父组件传递方
设置要传给子组件的HTML结构需要在使用组件时在组建标签内写入 MyTestdivHello World/div/MyTest!--MyTest为组件名--
子组件接收方
在子组件中需要进行定义插槽确定传入HTML的插入位置
HTML结构会插入在slot标签的位置
templatedivslot默认内容/slot!--如果没有传入HTML则渲染slot标签内的默认内容--/div
/template 具名插槽
当需要插入多个插槽时可以用具名插槽
子组件接收方
子组件定义多个插槽并配置name
templatedivslot namedome1默认内容/slotslot namedome2默认内容/slot/div
/template
父组件传递方
给传递的HTML结构配置solt值为插槽的name值 MyDomediv slotdome1Hello World/divdiv slotdome2Hello World/div/MyDome
作用域插槽
当需要使用的data数据不在传递方父组件自身而在子组件里时
子组件接收方
子组件在定义插槽时将数据传入插槽中
templatedivslot :wordword默认内容/slot/div
/templatescript
export default {name: TheDome,data() {return {word: Hello World,};},
};
/script 父组件传递方
必须使用template标签并在标签内配置scope TheDometemplate scopescopeData div{{ scopeData.word }}/div/template/TheDome
如上 子组件传递的数据以对象形式给了scopeData
nextTick
语法 this.$nextTick((){回调函数})
作用 在下一次DOM更新后执行回调 用于改变数据后基于更新后的新DOM进行操作时
Vue封装的过渡与动画 如图所示
Vue封装的过渡与动画分为进入enter和离开leave
进入和离开又分为起点过程中active和终点to
类名
元素进入
v-enter进入起点v-enter-active进入过程v-leave-to进入终点
元素离开
v-leave离开起点v-leave-active离开过程v-leave-to离开终点
在Vue中添加过渡与动画需要给Vue所配置的类添加样式
过渡/动画
过渡的添加需要六种样式全部配置
.v-enter,
.v-leave-to {transform: translateX(-100%);
}
.v-enter-to,
.v-leave {transform: translateX(0);
}
.v-enter-active,
.v-leave-active {transition: 1s;
}
使用 transition标签将要进行过度的元素进行包裹 transitiondiv classdome v-showxxx111/div/transition
被包裹的元素会自行执行样式中所写的过渡
动画的添加只需要配置v-enter-active和v-leave-active即可其他同过渡
.v-enter-active {animation: 1s test01;
}
.v-leave-active {animation: 1s test01 reverse;
}
keyframes test01 {from {transform: translateX(-100%);}to {transform: translateX(0);}
}
多个元素过渡
相同样式
多个元素共用一个过渡需要用 transition-group标签包裹
并且每个元素都要指定key值 transition-group div classdome v-showxxx key1111/divdiv classdome v-showxxx key2222/div/transition-group
不同样式
多个元素不共用一个过渡
要为transition标签配置name属性 transition nametest01div classdome v-showxxx111/div/transition
在写样式时类名中的v换成name值
例
.test01-enter,
.test01-leave-to {transform: translateX(-100%);
}
Vue中的Ajax
Vue脚手架配置代理
配置代理可以解决开发环境 Ajax 跨域问题
简
在vue.config.js中添加配置 devServer:{proxy:xxx//xxx为服务器基础路径}
优点
配置简单请求资源时直接发给前端
缺点
不能配置多个代理不能控制请求是否走代理
详
在vue.config.js中添加配置
devServer:{proxy:{/dome:{//匹配所有以/dome为开头的请求路径target:xxx,//代理目标的基础路径changeOrigin:true,pathRewrite:{^/dome:}}}
}
changeOrigin值为true时服务器收到请求头中host为服务器基础路径
changeOrigin值为flase时服务器收到请求头中host为本地基础路径
默认值为true
Vuex
Vuex简介
概念 专门在 Vue 中实现集中式状态数据管理的一个 Vue 插件对 vue 应用中多个组件的共享状态进行集中式的管理读/写也是一种组件间的通信方式且适用于任意组件间通信。 简而言之当多个组件共享数据时使用Vuex来管理这些共享数据
原理
如图在Vuex中封装有actionsmutationsstate三个对象由store统一管理图未显示
其中actions用于响应组件mutations用于修改数据state用于存储数据
当组件调用dispatch时会经过相当于门卫的actions进行一些逻辑处理
当然也可以绕过actions调用commit直接到mutations进行相应数据的修改
在action中调用commit会到mutations中进行相应数据的修改 搭建Vuex环境
安装Vuex
搭建Vuex环境首先需要在终端中安装Vuex npm i vuex创建store文件
创建路径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
})
传入store配置
在main.js中创建vm时传入store配置
import Vue from vue
import App from ./App.vue
//引入store
import store from ./store Vue.config.productionTip falsenew Vue({render: h h(App),store
}).$mount(#app)基本使用
组件
在组件中通过调用dispatch来触发action
语法 this.$store.dispatch(函数名, 数据);
示例 methods: {add() {this.$store.dispatch(add, this.number);//将会触发actions中的add函数并把this.number传给actions},},
也可以通过调用commit直接到 mutations中 methods: {add() {this.$store.commit(add, this.number);//将会触发mutations中的add函数并把this.number传给mutations},},
actions
在actions中可以进行一些逻辑处理如if判断等然后调用commit
//准备action对象————响应组件中用户动作
const actions {add(context, value) {context.commit(ADD, value)},
}
在组件中触发actions的add函数函数用两个参数
context封装有dispatch函数commit函数state对象等context中dispatch函数用于调用其他actions中的函数context中commit函数用于触发mutationscontext中state数据对象用于进行逻辑处理value则是组件传入的数据
关于commit函数 context.commit(ADD, value)
将会触发mutations中的ADD函数并把tvalue传给mutations
mutations
在mutations进行state的数据处理
//准备mutations对象————修改state中的数据
const mutations {ADD(state, value) {state.sum value},
}
其中的ADD函数传入两个参数state数据对象和actions传入的value
state
state用于存储数据
//准备state对象————存储数据
const state {sum: 0,
}
回到组件
在组件中使用 $store.state 即可使用Vuex中的数据 div和为{{ $store.state.sum }}/div
getters的使用
概念 当state中的数据需要经过加工后再使用时可以使用getters进行加工 类似于计算属性可以当作Vuex中的计算属性
使用
在index.js中追加getters配置
//准备getters对象————加工数据
const getters {multiple(state) {return state.sum * 10}
}
并暴露出去
//创建并暴露store
export default new Vuex.Store({actions,mutations,state,getters
})
在组件中使用 $store.getters 即可使用Vuex中加工后的数据 div10倍和为{{ $store.getters.multiple }}/div
map方法
mapState方法
用于映射state中的数据将其映射为组件中的计算属性
如下传统方法在组件中一直使用 $store.state获取数据显得十分麻烦 div和为{{ $store.state.sum }}/divdiv学校{{ $store.state.school }}/divdiv姓名{{ $store.state.name }}/div
可以直接借助mapState生成计算属性
语法两种写法 //对象写法mapState({ sum: sum, school: school, name: name }),//或//数组写法mapState([sum, school, name]),
内容 mounted(){console.log(mapState({sum:sum,school:school,name:name}));} 其输出为一个对象且都是函数故需要放在计算属性中
使用
import { mapState } from vuex; computed: {//对象写法...mapState({ sum: sum, school: school, name: name }),},computed: {//数组写法...mapState([sum, school, name]),}, div和为{{ sum }}/divdiv学校{{ school }}/divdiv姓名{{ name }}/div
mapGetters方法
用于映射getters中的数据将其映射为组件中的计算属性
用法与mapState方法无区别
import { mapGetters } from vuex; computed: {//对象写法...mapGetters({ multiple: multiple }),},computed: {//数组写法...mapGetters([multiple]),}, div10倍和为{{ multiple }}/div
mapActions方法
如下传统方法使用$store.dispatch与actions对话显得特**烦人 methods: {add() {this.$store.dispatch(add, this.number);},sub() {this.$store.dispatch(sub, this.number);},addOdd() {this.$store.dispatch(addOdd, this.number);},addWait() {this.$store.dispatch(addWait, this.number);},},
可以靠mapActions方法来解决省略$store.dispatc实现组件与actions对话
其语法与mapState无异
内容 mounted() {console.log(mapActions({ add: add, sub: sub }));}, 其输出也为一个对象且都是函数需要放在methods配置中
使用
注意需要手动在绑定事件时传参
import { mapActions } from vuex; methods: {//对象写法...mapActions({add: add,sub: sub,addOdd: addOdd,addWait: addWait,}),},methods: {//数组写法...mapActions([add, sub, addOdd, addWait]),}, button clickadd(number)/buttonbutton clicksub(number)-/buttonbutton clickaddOdd(number)为奇数时加/buttonbutton clickaddWait(number)一秒钟后加/button
mapMutations方法
省略$store.commit实现组件与actions对话
用法与mapActions方法无异
import { mapMutations } from vuex; methods: {//对象写法...mapMutations({add: add,sub: sub,addOdd: addOdd,addWait: addWait,}),},methods: {//数组写法...mapMutations([add, sub, addOdd, addWait]),},
模块化和命名空间
让代码更好维护让多种数据分类更加明确
修改store
//引入Vue核心库
import Vue from vue
//引入Vuex
import Vuex from vuex
//应用Vuex插件
Vue.use(Vuex)const Count01 {namespaced: true,//开启命名空间actions: {...},mutations: {...},state: {...},getters: {...}
}const Count02 {namespaced: true,//开启命名空间actions: {...},mutations: {...},state: {...},getters: {...}
}//创建并暴露store
export default new Vuex.Store({modules: {Count01,Count02},
})
不使用map方法
templatediv!--读取state数据--p数{{ $store.state.Count01.number }}/pbr /!--读取getters数据--p10倍为{{ $store.getters[Count01/multiple] }}/pbr /button clickadd(1)1/buttonbr /br /button clickaddIf(1)为奇数1/button/div
/templatescript
export default {name: TheCount01,methods: {add(value) {//调用committhis.$store.commit(Count01/ADD, value);},addIf(value) {//调用dispatchthis.$store.dispatch(Count01/addIf, value);},},
};
/script
使用map方法
script
import { mapState, mapGetters, mapActions, mapMutations } from vuex;
export default {name: TheCount02,computed: {//读取state数据...mapState(Count02, [number]),//读取getters数据...mapGetters(Count02, [multiple]),},methods: {//调用dispatch...mapActions(Count02, [addIf]),//调用commit...mapMutations(Count02, [ADD]),},
};
/script
路由
路由的理解
路由就是一组 key-value 的对应关系
多个路由由路由器进行管理
Vue中通过vue-router插件来实现路由
基本路由
创建router文件
创建路径src/router/index.js
示例
//引入VueRouter
import VueRouter from vue-router;
//引入组件
import TheTest01 from ../pages/TheTest01
import TheTest02 from ../pages/TheTest02//创建并暴露router实例对象
export default new VueRouter({routes: [{path: /test01,component: TheTest01},{path: /test02,component: TheTest02},]
})
创建的router示例对象中需要配置一个routers数组数组存储对象
path值为路由中的key值component值为组件
组件需要进行引入
安装与应用vue-router插件
搭建vue-router环境首先需要在终端中安装vue-router
npm i vue-router
另外需要在main.js中应用插件
import Vue from vue
import App from ./App.vue//引入VueRouter
import VueRouter from vue-router
//应用VueRouter
Vue.use(VueRouter)
//引入路由器
import router from ./router/indexVue.config.productionTip falsenew Vue({render: h h(App),router: router
}).$mount(#app)注意在main.js中引入路由器即router文件
实现组件切换 divdiv classarouter-link active-classactive to/test01test01/router-link/divdiv classarouter-link active-classactive to/test02test02/router-link/div/divdivrouter-view/router-view/div/div
使用router-link标签实现切换必需配置to以确定切换的页面
active-class可以配置类名
router-view标签用于指定切换页面的展示位置
router-view标签本质是a标签
注意点
路由组件一般存放在pages文件夹中一般组件存放在components文件夹中切换后未显示的组件默认被销毁展示时在进行挂载每个组件都有独属于自身的$router属性存储自己的路由信息整个应用只有一个routers可以通过组件的$router属性获取
多级路由
多级路由就是实现路由的嵌套
在router文件中使用children配置项 routes: [{path: /dome01,component: TheDome01},{path: /dome02,component: TheDome02,//通过children配置子级路由children:[{path:childdome01,//注意不要写/component:ChildDome01},{path:childdome02,//注意不要写/component:ChildDome02},]},]
在组件子组件中实现跳转要写完整路径 divrouter-link active-classactive to/dome02/childdome01child01/router-link/divdivrouter-link active-classactive to/dome02/childdome02child02/router-link/div
路由中的query参数
query参数是以路由为媒介给路由组件传递数据的
传递方 router-linkactive-classactive:to{//注意引号path: /test02,query: {words: test02,},}test02/router-link
在router-link标签中to配置项写成对象形式里面写有query对象
query对象中的参数既是传递的数据
另外也可以使用to的字符串写法无需配置query同样可以达到目的 router-link active-classactive to/test01?wordstest01test01/router-link router-link active-classactive :to/test01?words${test01}test01/router-link
接收方路由组件
使用$route.query.xxx来接收数据 divp{{$route.query.words}}/p/div
虽说是路由中的query参数但是路由只是一个媒介
传递方组件的数据通过路由传递给路由组件
在此过程中router文件不需要进行任何修改
命名路由
作用用于简化路由的跳转 主要在多级路由中展现其作用
在router文件中使用name配置项 children:[{path:childdome01,//注意不要写/component:ChildDome01,name:child1//命名},]
组件中在router-link标签中to配置项同添加query时一样需要写成对象形式 router-link active-classactive :to{name:child1}child01/router-link
可以配合query配置传递参数
路由中的params参数
params参数和query参数一样是以路由为媒介给路由组件传递数据的
路由器修改
在router文件中要事先使用占位符声明接收参数 children:[{path:childdome01/:words,//使用占位符什么接收params参数component:ChildDome01,name:child1},]
如上意为会传递一个名为words的参数
传递方
字符串写法
直接使用 / 进行拼接 router-link active-classactive :to/dome02/childdome02/text2child02/router-link
对象写法
配置params并且不可以用path而是用name router-link active-classactive :to{name:child1,params:{words:text1}}child01/router-link
接收方路由组件
使用$route.params.xxx来接收数据 div classdomep{{$route.params.words}}/p/div
路由中的props配置
作用配合query和params参数让路由组件更方便收到参数
在接收方路由组件中以$route.params.xxx或$route.query.xxx来接收数据显得特别麻烦
可以在router文件中配置props解决
方法一 {path:childdome01/:words,component:ChildDome01,name:child1,//值为对象对象中所有key-value组合通过props传给路由组件props:{name:test}},
方法二 {path:childdome01/:words,//使用占位符什么接收params参数component:ChildDome01,name:child1,//值为布尔值为true时把路由收到的所有params参数传给路由组件props:true},
方法三 {path:childdome01/:words,//使用占位符什么接收params参数component:ChildDome01,name:child1,//为函数返回值传给路由组件props(route){return{test:route.query.words}}},
replace属性
浏览器的历史记录有两种写入方式
push追加历史记录replace覆盖历史记录 追加上的历史记录可以通过点击上图 ← 返回
历史记录被覆盖后就无法返回
路由跳转默认为push即可以返回
在router-link标签中添加replace属性可以改为replace router-link active-classactive to/dome02 replacedome02/router-link
编程式路由
作用无需使用router-link标签即可实现路由的跳转 methods:{show01(){this.$router.push({path:/test01})},show02(){this.$router.replace({path:/test02})},}
通过this.$router.push和this.$router.replace两个API来实现
分别以追加历史记录和覆盖历史记录的方式进行跳转路由
其里面的配置同to的对象写法
另外如果配置name则name为路由组件的name
其他API
this.$router.forward() 前进this.$router.back() 后退this.$router.go() 传入一个整数正值则前进负值后退跳转数为传入数
缓存路由组件
路由组件在切走后会被销毁
缓存路由组件可以使路由组件在切走后保持挂载不被销毁
将router-view标签包裹在keep-alive标签中即可 keep-alive includetest01router-view/router-view/keep-alive
keep-alive标签中的include属性为保持挂载的路由组件
不配置默认全部保持挂载有多个时写成对象的形式
路由中特有的生命周期钩子
路由中有两个特有的生命周期钩子 activated() 路由组件激活时触发 deactivated() 路由组件切走后触发
注意只有在keep-alive标签包裹下有用
路由守卫
作用对路由进行权限控制
分类全局守卫独享守卫组件内守卫
全局守卫
全局守卫分为前置守卫和后置守卫
router文件更改
使用全局守卫需要用到router的API故不可用以下方式暴露
export default new VueRouter({......
}) 应改为如下代码
const router new VueRouter({......
})export default router
meta配置
每个路由可以配置meta这是一个可以让程序员自由传值的配置meta是一个对象
使用路由守卫需要判断路由是否需要进行权限控制
可以在meta中添加一个布尔值用于判断
const router new VueRouter({routes: [{path: /Person,component: ThePerson,meta: { isAuth: true }},]
})
全局守卫用法
1.全局前置守卫
初始化时执行以及每次路由切换前执行
router.beforeEach((to, from, next) {if (to.meta.isAuth) {//判断路由是否需要进行权限控制if (localStorage.getItem(test) xxx) {//判断权限权限控制的具体规则next()//放行} else {console.log(无权限);}} else {next()//放行}
})
全局前置守卫使用router.beforeEach()传值为一个函数
函数传三个参数to, from, next
to, from为对象分别存储着 切换到的路由组件信息 和 切换走的路由组件信息
next为一个函数调用时放行进行路由的切换
2.全局后置守卫
初始化时执行以及每次路由切换后执行
router.afterEach((to, from){console.log(to, from);
})
一般情况下不用只需要传递to和from两个参数
因为以及切换完无需使用next
独享守卫
独享守卫是单独配置在某个路由中的
用于判断某个路由是否需要权限控制
除使用的API外其他与前置守卫无区别
const router new VueRouter({routes: [{path: /Person,component: ThePerson,meta: { isAuth: true },beforeEnter(to, from, next) {if (to.meta.isAuth) {//判断路由是否需要进行权限控制if (localStorage.getItem(test) xxx) {//判断权限权限控制的具体规则next()//放行} else {console.log(无权限);}} else {next()//放行}}},]
})
组件内守卫
组件内守卫分为进入守卫和离开守卫
进入守卫在通过路由进入某个路由组件时调用
离开守卫在通过路由离开某个路由组件时调用
需要写在路由组件中用法同全局守卫 //进入守卫beforeRouteEnter(to, from, next){console.log(to, from, next);},//离开守卫beforeRouteLeave (to, from, next) {console.log(to, from, next);}
路由器两种工作模式
对于一个url来说#后面的内容就是其hash值
hash值不会包含着http请求中即hash值不会传递给服务器
路由器有两种工作模式
1.hash模式
地址中永远带着 #地址可能被第三方App标记为不合法兼容性高
2.history模式
地址中不带着 #兼容性比hash模式差部署后需要后端修404问题
路由默认为hash模式
修改为history模式如下代码
const router new VueRouter({mode:history,.......
})