Vue基础学习笔记
- 1.简单入门案例
- 2.数据绑定
- 3.MVVM模型
- 4.事件处理
- 5.计算属性与监视
- 6.监视属性-watch(被监视的属性必须存在才能监视)
- 7.计算属性和监视属性的比较
- 8.class 与 style 绑定
- 9.条件渲染
- 10.列表渲染
- 11.收集表单数据
- 12.内置指令与自定义指令
- 13.Vue的生命周期
- 14.Vue 组件化编程
- 15.Vue脚手架
- 16.ref属性
- 17.props配置项
- 18.mixin配置项
- 19.Vue中的插件
- 20.scoped属性(建议添加)
- 21.webStorage(扩展知识:浏览器的本地存储和会话存储)
- 22.组件的自定义事件
- 25.Vue 中的 ajax
- 26.slot插槽
- 27.Vuex
- 28.路由
- 29.Vue项目的打包
- Vue组件相关注意点
- 2.组件名的命名规则
1.简单入门案例
分析:
1.必须要创建实例才能使用Vue的功能
2.el即element该配置项用来指定当前Vue实例为哪个容器(页面元素)服务,值通常为css选择器字符串(比较传统的写法是用dom语句,比如这里可以替换为document.getElementById(‘root’))
3.data是用来存放需要在el所指定的容器中展示的数据的配置项,数据存放采用json格式 (后期会变为函数形式)
4.容器与实例必须一一对应,不能多个容器对应一个实例或者一个容器对应多个实例。
5.真实开发中只有一个Vue实例,并且会配合着组件一起使用
1.1插值语法
1.功能: 用于解析标签体内容,标签体即首尾标签之间的内容(文本节点)
2.语法: {{xxx}} ,xxxx 会作为 js 表达式解析。且xxx会自动读取到data中的所有属性
比如:上图中的根据主键取值,或者如下图:
页面输出:
1.2指令语法
1.功能:用于解析标签(包括:标签属性、标签体内容、绑定事件…) 。
2.举例:v-bind:href = ‘xxxx’ ,xxxx 会作为 js 表达式被解析
3.说明:Vue 中有有很多的指令,此处只是用 v-bind 举个例子,指令形式为v-xxxx
官网对指令的分类:
也就是说当使用了v-bind:后原来属性(比如这里的href)中的值会被当做js表达式来解析
v-bind官网API释义:
2.数据绑定
2.1单向数据绑定
1.语法:v-bind:href =“xxx” 或简写为 :href,这里是用v-bind举例子,因为v-bind指令是一种单向数据绑定
2.特点:数据只能从 data 流向页面
效果:
2.2双向数据绑定
1.语法:v-mode:value=“xxx” 或简写为 v-model=“xxx” ,这里是用v-mode举例子,因为v-mode指令是一种双向数据绑定
2.特点:数据不仅能从 data 流向页面,还能从页面流向 data
效果:
注意:v-model指令只能应用在表单类标签(准确来说是输入类标签)或者组件上
v-model默认应用在value上,所以有如下图所示的简写形式:
v-model官网API释义:
3.MVVM模型
1.M:模型(Model) :对应 data 中的数据
2.V:视图(View) :模板
3.VM:视图模型(ViewModel) : Vue 实例对象
简单来说,ViewModel就是View和Model之间的桥梁,Model通过这个桥梁来正确显示到View中的相应位置。
1.data中所有的属性,最后都出现在了vm身上。
如图,Vue实例vm上挂载了data中的这些数据
2.vm身上所有的属性及Vue原型上所有属性,在Vue模板中都可以直接使用。
输出一下图中Vue实例vm身上的属性:
4.事件处理
4.1事件绑定
指令:v-on
例子:
在这个函数中可以拿到事件对象:
v-on官网API释义:
4.1.1被触发函数的传参方式
例子:
输出:
如果需要event事件对象,就需要在参数中使用$event传入。因为如果存在需要传入的参数,那么默认传入的event对象会被覆盖,也就是说函数中无法接收到event对象。
4.2事件修饰符(注意事件修饰符是修饰符的子类)
比如之前使用的v-on指令,它就有多个事件修饰符(详情见4.1):
Vue中的事件修饰符:
1.prevent:阻止默认事件(常用);
2.stop:阻止事件冒泡(常用);
3.once:事件只触发一次(常用);
4.capture:使用事件的捕获模式。原来事件默认在冒泡阶段开始处理,这个修饰符就是让对应的事件在捕获阶段就开始处理;
5.self:只有event.target是当前操作的元素是才触发事件;
6.passive:事件的默认行为立即执行,无需等待事件回调执行完毕;
事件修饰符支持链式调用:
例子(阻止a标签的冒泡事件同时阻止其默认事件):
4.3键盘事件
1.Vue中常用的按键别名:
回车=> enter
删除=> delete(捕获“删除”和“退格”键)
退出=>esc
空格=> space
换行=> tab(特殊,一般配合keydown。因为如果配合keyup使用,那么当抬起tab键时,焦点就变了诸如获取 当前焦点处的值等功能就不好用了。)
上=>up
下 =>down
左=> left
右=>right
通过这些别名,我们就可以指定相应键盘按键的触发事件,如下:
2.系统修饰键(用法特殊): ctrl、alt、shift、 meta(在windows中即win键)
(1)配合keyup使用的步骤:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。
(2)配合keydown使用:正常触发事件。
系统修饰键后可以跟其它键形成组合键调用,注意只有系统修饰键才行
例子(按下ctrl+a后触发方法):
3.Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名)
例子(按下Capslk键触发事件):
首先获取到Capslk键的原始key值(用 事件对象.key 的方式获取):
这里可以看到叫CapsLock,那么它的限定名就是caps-lock(因为是两个单词所以中间用-连接):
4.Vue.config.keyCodes.自定义键名=键码,可以去定制按键别名
例子:
5.计算属性与监视
5.1计算属性(一种属性,由已有的属性计算得来)
虽然和data中的属性大同小异,但它不属于data配置项而属于computed配置项
1.配置项名:computed
2.其中的计算属性需要定义成一个对象,该对象必须包含一个get()方法,也可以包含一个set()方法:
get有什么作用?当有人读取计算属性时,get就会被调用,且返回值就作为该计算属性的值
get什么时候调用?1.初次读取计算属性时。2.所依赖的数据发生变化时。
set什么时候调用?当计算属性被修改时。
Vue已经对计算属性中get和set方法的this进行了调整,都指向它们属于的Vue实例
计算属性被直接挂载在Vue实例上,所以获取时直接用插值语法获取即可,如下
3.get()方法是当计算属性的值被获取时,该方法的处理结果就是被获取到的值。
所以可以在该方法中对计算属性的值进行设置,如下:
4.set()方法是当计算属性的值被修改时,该方法会获取到该计算属性被设置的值。然后可以利用该值进行操作。
如果计算属性要被修改,那必须写set函数去响应修改否则会报错,且set中要操作的一般是计算时依赖的数据(如下面例子中的firstName和lastName)
5.1.1计算属性的简便写法(前提条件是只需要get函数)
6.监视属性-watch(被监视的属性必须存在才能监视)
写法一:
写法二:
多级属性索引
监视的简写(当只有handler配置项时才可以简写)
方式一的简写:
方式二的简写:
被监视属性的配置项
1.handler方法:该方法会在被监视属性发生改变时调用
2.immediate:该属性是一个布尔值,默认为false。用于控制在被监视属性初始化时是否调用handler方法。
3.deep:该属性是一个布尔值,默认为false。用来配置是否可以监测对象内部值改变(多层)。这就是所谓的深度监视。如下例子:
7.计算属性和监视属性的比较
computed和watch之间的区别:
1.computed能完成的功能,watch都可以完成。
2.watch能完成的功能,computed不一定能完成,例如: watch可以进行异步操作。
两个重要的小原则:
1.所有被Vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例对象。
2.所有不被Vue所管理的函数(如定时器的回调函数、ajax的回调函数等),最好写成箭头函数( () => {}),这样this的指向才是vm或组件实例对象。
8.class 与 style 绑定
8.1class绑定
1.class样式
写法 :class="xxx"
xxx可以是字符串、对象、数组。
字符串写法适用于:类名不确定,要动态获取。
对象写法适用于:要绑定多个样式,个数不确定,名字也不确定。
数组写法适用于:要绑定多个样式,个数确定,名字也确定,但不确定用不用.
8.2style绑定
2. style样式
写法 :style="{fontsize:xxx}"
其中xxx是动态值,且对象的key不能自定义。
9.条件渲染
条件渲染指令
1.v-if 与 v-else
2.v-show
v-show
官网API:
例子:
v-if
官网API:
例子:
v-show和v-if在显示/隐藏内容上的比较
1.v-show不会删除节点,v-if会直接删除节点。如下图:
2.当切换频率高时建议使用v-show因为v-if会频繁的增删节点。
当需要隐藏节点内容时监视使用v-if,因为v-show不会删除节点,别人可以通过f12查看。
3.template标签(该标签可以理解为一种临时容器,在页面渲染时不会显示其结构但它能实现一个容器应有的功能)只能配合v-if使用,不能配合v-show使用。
总结
1.v-if
写法:
(1)v-if=“表达式”
(2)v-else-if=“表达式”
(3)v-else=“表达式”
适用于:切换频率较低的场景。
特点:不展示的DOM元素直接被移除。
注意:v-if可以和v-else-if、v-else一起使用,但要求结构不能被"打断”。
2.v-show
写法: v-show=“表达式”
适用于:切换频率较高的场景。
特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉
3.备注:使用v-if的时,元素可能无法获取到,而使用v-show一定可以获取到。
10.列表渲染
列表显示指令
遍历数组: v-for / index
遍历对象: v-for / key
例子
v-for指令:
1.用于展示列表数据
2.语法: v-for="(item,index) in xxx" :key="yyy"
3.可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)
4.当使用v-for时,遍历的容器需要绑定key值,用来作为遍历出来的每个容器的唯一标识。
5.遍历可以获得两个数据:
当遍历数组时:获得数组元素对象和下标
当遍历对象时:获得对象的值和键
当遍历字符串时:获得字符串中的每个字符和下标
当遍历指定次数时:获得1到指定次数的每个数值和下标
10.1key属性的作用与原理
key是Vue定义的特殊的标签属性,用来给Vue使用。所以即便设置了在页面中也不会显示出来。
当未给v-for遍历的容器绑定key值时,Vue会默认将index(遍历下标)作为key。
key属性的作用
1.虚拟DOM中key的作用:
key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规如下:
2.对比规则:
(1).旧虚拟DOM中找到了与新虚拟DOM相同的key:
1.若虚拟DOM中内容没变,直接使用之前的真实DOM !
2.若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM。
(2).旧虚拟DOM中未找到与新虚拟DOM相同的key
创建新的真实DOM,随后渲染到到页面。
3.用index作为key可能会引发的问题:
(1).若对数据进行:逆序添加、逆序删除等破坏顺序操作:
会产生没有必要的真实DOM更新==> 界面效果没问题,但效率低。
(2).如果结构中还包含输入类的DOM(如input):
会产生错误DOM更新 ==> 界面有问题。
4.开发中如何选择key?:
(1).最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值。
(2).如果不存在对数据的逆序添加、逆序删除等破坏顺序的操作,仅用于渲染列表用于展示,使用index作为key是没有问题的。
10.2列表过滤(由于是前端的列表过滤,所以适合少量数据)
watch方式:
computed方式:
10.3列表排序
直接上例子:
10.4给data添加数据代理后的新属性
关键API:
1.Vue.set()函数
2.Vue实例.$set()函数
这两个函数用法和作用都相同
官网API:
为什么要用?
因为直接给data添加新的属性,该属性无法被数据代理,如下:
上述API的使用方法
这两个函数的参数一致:
参数一:需要添加属性的对象
参数二:需要添加的属性的key
参数三:需要添加的属性的value
局限性
该API无法向vm实例或者vm._data直接追加属性,它只能给data中的某个对象追加属性。
10.5针对data中数组对象的修改
直接给数组对应下标的数据赋值所引发的问题
使用Vue数组相关的操作函数来实现修改等操作
通过上述方法来操作数组,Vue就能侦测到。这些方法在数组的原型上就已经存在,但Vue又重新包装了这些方法。
11.收集表单数据
收集表单数据:
若:<input type="text"/>
,则v-model收集的是value值,用户输入的就是value值。
若:<input type="radio"/>
,则v-model收集的是value值,且要给标签配置value值。
若:<input type="checkbox" />
1.没有配置input的value属性,那么收集的就是checked(勾选or未勾选,是布尔值)
2.配置了input的value属性:
(1)v-model的初始类型是非数组,那么收集的就是checked(勾选or未勾选,是布尔值)
(2)v-model的初始类型是数组,那么收集的就是value组成的数组。此时要给input添加value
v-model的三个修饰符:
lazy:失去焦点再收集数据
number:将输入字符串转为有效的数字
trim:将输入的首尾空格过滤
例子:
12.内置指令与自定义指令
12.1常用内置指令
1.v-text : 更新元素的 textContent,没有插值语法灵活,一般不使用
作用:向其所在的节点中渲染文本内容。
与插值语法的区别: v-text会替换掉节点中的内容,而插值语法则不会。
2.v-html : 更新元素的 innerHTML(有安全性问题,一般不用)
1.作用:向指定节点中渲染包含html结构的内容。
2.与插值语法的区别:
(1).v-html会替换掉节点中所有的内容,而插值语法则不会。
(2).v-htm来可以识别html结构(如标签等)。
3.严重注意:v-html有安全性问题!!!
(1)在网站上动态渲染任意HTML是非常危险的,容易导致XSS攻击。
(2)一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!
以下指令不作过多解释
3.v-if : 如果为 true, 当前标签才会输出到页面
4.v-else: 如果为 false, 当前标签才会输出到页面
5.v-show : 通过控制 display 样式来控制显示/隐藏
6.v-for : 遍历数组/对象
7.v-on : 绑定事件监听, 一般简写为@
8.v-bind : 绑定解析表达式, 可以省略 v-bind
9.v-model : 双向数据绑定
10.v-cloak : 防止页面闪现, 与 css 配合: [v-cloak] { display: none }
1.本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性。
2.使用css配合v-cloak可以解决网速慢时页面无法及时渲染的问题。
11.v-once,该指令没有值
1.v-once所在节点在初次动态渲染后,就视为静态内容了。
2.以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。
12.v-pre,该指令没有值
1.跳过其所在节点的编译过程。
2.可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译。
12.2自定义指令
关键配置项:directives
由于指令中基本都是直接对dom的操作,所以定义在该配置项中的函数的this一般都是window
函数式写法(有局限性但简洁)
例子(自定义一个v-big标签,功能是把指令中的表达式的值乘以10):
参数分析:
指令函数的调用时机
1.指令与元素成功绑定时
2.指令所在的模板被重新解析时
函数写法的全局形式(注意定义在Vue实例外部)
对象式写法(没有局限性但复杂)
对象中存在一些默认的函数,下面是常用的三个:
bind()函数:会在指令与元素成功绑定时调用
inserted()函数:指令所在的元素被插入页面时调用
update()函数:指令所在的模板被重新解析时调用
这些函数都有之前的两个参数(element和binding)
其实这三个函数就是在不同的时刻被调用。像元素获取焦点、获取元素的父元素等需要在元素被插入页面时就调用的动作就需要在inserted()函数中调用。
对象写法的全局形式(注意定义在Vue实例外部)
13.Vue的生命周期
简介
生命周期:
1.又名:生命周期回调函数、生命周期函数、生命周期钩子。
2.是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数。
3.生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的。
4.生命周期函数中的this指向是vm或组件实例对象。
13.1流程图
13.2生命周期函数
beforeCreate()函数
在该函数的执行时机,无法通过vm访问到data中的数据、methods中的方法。
使用方法与mounted()相同
created()函数 (常用)
在该函数的执行时机,可以通过vm访问到data中的数据、methods中的方法。
使用方法与mounted()相同
beforeMount()函数
在该函数的执行时机:
1.页面呈现的是未经Vue编译的DOM结构。
2.所有对DOM的操作,最终都不奏效。
使用方法与mounted()相同
mounted()函数(常用)
调用时机
Vue完成模板的解析并把初始的真实DOM元素放入页面后(挂载完毕)调用mounted(),也就是说每次只会在挂载完毕后调用一次,即使你之后的真实DOM发生了改变,也不会再次触发。
此时:
1.页面中呈现的是经过Vue编译的DOM
2.对DOM的操作均有效(尽可能避免)。至此初始化过程结束,一般在此进行:开启定时器、订阅消息、绑定自定义事件等初始化操作。
使用方法
该函数可以写在配置项中,然后在其中写入你希望在此时执行的代码:
beforeUpdate()函数
当页面状态更新时会先执行这个函数
在该函数的执行时机,数据是新的,但页面是旧的,即:页面尚未和数据保持同步。
update()函数(常用)
在该函数的执行时机,数据是新的。页面也是新的,即:页面和数据保持同步。
beforeDestory()函数(常用)
当调用vm.$destory()方法后会先执行这个函数
在该函数的执行时机,vm中所有的: data.methods、指令等等,都处于可用状态,马上要执行销毁过程,—般在此阶段:关闭定时器、取消订阅消息、解绑自定义事件等收尾操作
因为已经进入了销毁流程,所以在这里进行的针对数据的修改操作都不会更新,因为Vue不会调用update()函数。
destory()函数
14.Vue 组件化编程
14.1模块与组件
14.1.1模块(针对的是js)
理解:
向外提供特定功能的 js 程序, 一般就是一个 js 文件
为什么:
js 文件很多很复杂
作用:
复用 js, 简化 js 的编写, 提高 js 运行效率
14.1.2组件
理解:
用来实现局部(特定)功能效果的代码集合(html/css/js/image……)
为什么:
一个界面的功能很复杂
作用:
复用编码, 简化项目编码, 提高运行效率
14.2Vue中使用组件的三大步骤
一、定义组件(创建组件)
二、注册组件
三、使用组件(写组件标签)
一、如何定义一个组件?
使用Vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样,但也有点区别;区别如下:
1.el配置项不要写,为什么?因为最终所有的组件都要经过一个vm的管理,由vm中的el决定服务哪个容器。写了该组件就和一个容器绑定了,没有达到组件的效果。且写了会报错。
2.data必须写成函数形式,为什么?为了避免组件被复用时,数据存在引用关系。
备注:使用template配置项可以配置组件结构。
定义组件的一个简写方式:
例子(注意这里的school并不是组件名):
const school = Vue.extend(options)
可简写为:const school = options (这种是常用写法)
二、如何注册组件?
1.局部注册:靠new Vue的时候传入components选项
2.全局注册:靠Vue.component(‘组件名’,组件)
三、使用组件标签
在需要的位置引入组件标签:<组件名></组件名>
例子(注意例子中是非单文件组件的写法):
14.3组件的嵌套
例子(注意例子中是非单文件组件的写法):
注意:被嵌套的组件要写在嵌套它的组件的前面,上面例子中的顺序不对
14.4有关VueComponent的一些细节
1.school组件本质是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extend生成的。
2.我们只需要写<school/>
或<school></school>
,Vue解析时会帮我们创建school组件的实例对象,
即Vue帮我们执行的: new VueComponent(options)。
3.特别注意:每次调用Vue.extend,返回的都是一个全新的VueComponent实例对象!!!
4.关于this指向:
(1)组件配置中:
data函数、methods中的函数、watch中的函数、computed中的函数
它们的this均是【VueComponent实例对象】
(2)new Vue(options)也就是Vue实例的options配置中:
data函数、methods中的函数、watch中的函数、computed中的函数
它们的this均是【Vue实例对象】。
5.VueComponent的实例对象,以后简称vc(也可称之为:组件实例对象)
Vue的实例对象,以后简称vm。
14.5单文件组件(由于非单文件组件不常用所以不作过多赘述)
这种类型的组件都放在.vue结尾的文件中。
14.5.1 Vue脚手架下的开发
目录结构
这里面的App.vue和index.html以及main.js都是固定的。名称也是固定的。因为Vue脚手架要使用,当使用Vue脚手架时这些文件才能正常运行。
单文件组件中的内容
三种暴露(export)方式:
1.分别暴露:
2.统一暴露:
3.默认暴露:
默认暴露在引用时比前两种简单,只需import xxx from xxx而前两种需要import {xxx} from xxx。
App.vue中的内容
main.js中的内容(该文件是整个项目的入口文件)
index.html中的内容
15.Vue脚手架
1.Vue 脚手架是 Vue 官方提供的标准化开发工具(开发平台)。
2.目前最新的版本是 5.x。如果Devtools版本过低,在脚手架项目中可能无法正常使用。
3.文档
15.1安装步骤(以下命令均在命令行中执行)
第一步(仅第一次执行):全局安装@vue/cli
npm install -g @vue/cli
安装完毕后需要重启命令行
第二步:切换到你要创建项目的目录,然后使用命令创建项目(注意这里是项目名称没有后缀)
vue create xxxx
第三步:启动项目(需要进入到之前创建的项目目录中)
npm run serve
启动完毕后,会开启一个服务器,默认是8080端口:
使用ctrl+c可以关闭服务
备注:
1.如出现下载缓慢请配置 npm 淘宝镜像:
npm config set registry https://registry.npm.taobao.org
2. Vue 脚手架隐藏了所有 webpack 相关的配置,若想查看具体的 webpakc 配置,请执行:
vue inspect > output.js
15.2脚手架模板结构
15.3脚手架模板文件分析
index.html
15.4修改脚手架的默认配置
可修改的默认配置项(在官网查看)
以上就是所有配置项
常用配置项(首先需要创建vue.config.js文件,其中设置的配置项会覆盖默认配置项)
vue.config.js文件需要放在和package.json同级的目录下(新版脚手架会默认创建一个)
15.4.1常用配置项
关闭语法检查(配置项:lintOnSave)
16.ref属性
作用
1.被用来给元素或子组件注册引用信息 (id的替代者)
2.应用在html标签上获取的是真实DOM元素,应用在组件标签上是组件实例对象(vc)
3.使用方式:
打标识:<h1 ref="xxx">.....</h1>
或<组件名 ref=“xxx”></组件名>
获取: this.$refs.xxx
例子
输出:
因为ref属性都挂载在vc的$refs
对象上,所以可以通过$refs.xxx
来访问那个ref属性的内容(如例子中所示)
17.props配置项
功能:
让组件接收外部传过来的数据
传递数据的方式:
<组件名 数据的key=“数据的value”/>
接收数据的方式:
第一种方式(只接收):
props: ['数据的key']
第二种方式(限制类型、限制必要性、指定默认值):
props:{
数据的key:{
type:String,//类型
required:true,//必要性
default:'老王' //默认值
}
}
例子:
注意上图中age属性的传入方式
备注:
props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,
若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。
例子:
18.mixin配置项
功能:
可以把多个组件种相同的配置提取成一个混入对象
使用方式
首先定义一个新的js文件,并把需要提取的配置项写在里面,然后暴露(export出去)。最后在需要使用的组件中引入(import)并配置mixin配置项即可。
例子:
如果需要在组件中添加新的功能那么,再定义一个同名的配置项即可,混入的配置项会追加到组件中的配置项中。如果配置项里的key相同,那么以组件中的为准
例子:
19.Vue中的插件
功能:用于增强Vue
本质上是一个对象,但这个对象中必须包含install()方法。通过 install 方法给 Vue 或 Vue 实例添加方法, 定义全局指令等
install的第一个参数是Vue,第二个以后的参数是插件使用者传递的数据。
定义插件
新建一个plugins.js文件,然后在里面创建并暴露一个对象,该对象中写一个install()函数,在该函数中写插件的功能。
例子:
使用插件(这也是Vue中非自定义插件的应用方法)
完成上述步骤后,插件就被挂载到Vue实例上了,然后就可以在vm或者vc(组件上使用了),因为插件中定义的功能都是全局的所以可以直接使用。
20.scoped属性(建议添加)
作用:让样式在局部生效,防止冲突。因为Vue中所有组件的样式会在最后汇总到一起,所以会出现命名冲突的问题
写法: <style scoped></style>
例子:
20.1lang属性
作用:该属性可以指定style所使用的语言,默认为css,可以指定为less等
注意:首次使用less时需要安装less-loader,否则会报错
21.webStorage(扩展知识:浏览器的本地存储和会话存储)
22.组件的自定义事件
22.1绑定自定义事件
例子(通过给组件自定义事件的方式实现子组件往父组件传值):
上述例子中的扩展点
1.由于组件的自定义事件也是事件,所以可以使用事件修饰符,如下:
2.事件里的工作函数中如果要传多个参数,可以用封装成对象或者使用可变形参这两种方式来接收,如下:
Vue把组件上的事件都当成自定义事件,所以想使用原生的事件需要加.native修饰符(高版本已修复)
22.2解绑自定义事件(当组件的实例对象被销毁时,所有该组件身上的自定义事件也都被销毁了,之后的路由中会有坑)
例子:
23.消息的订阅与发布(实现组件间通信,需要借助外部库)
原则:需要数据的组件订阅消息,提供数据的组件发布消息
这里使用pubsub.js第三方库,一下是安装流程:
在命令行(在项目文件所在目录)输入命令:
npm i pubsub-js
引入pubsub.js库
命令:
import pubsub from 'pubsub-js'
哪个组件要用就在哪个组件中引用
使用
上面引入的是一个对象(pubsub),该对象中包含了相关的方法
例子(图中有很多注意点,建议仔细观看):
24.$nextTick
作用:
在下一次DOM更新结束后执行其指定的回调
使用(该方法挂载在组件实例对象(vc)上):
什么时候用?当改变数据后,要基于更新后的新DOM进行某些操作时,要在$nextTick所指定的回调函数中执行。
25.Vue 中的 ajax
建议使用 Axios而非JQuery
安装Axios库
命令:
npm i axios
在要使用的组件中引入Axios
命令:
import axios from 'axios'
26.slot插槽
26.1具名插槽
26.2作用域插槽(推荐使用,它扩展了具名插槽的功能)
作用:
通过子组件的插槽给父组件传值。类似于props,props是父组件给子组件传值
例子:
27.Vuex
概念:
专门在 Vue 中实现集中式状态(数据)管理的一个 Vue 插件,对 Vue 应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。
Github 地址: https://github.com/vuejs/vuex
什么时候使用 Vuex?
1.多个组件依赖于同一状态
2.来自不同组件的行为需要变更同一状态
简单来说就是需要多个组件共享同一状态(数据)时,使用Vuex
Vuex工作原理图
State:是一个对象,该对象中保存了你想共享的状态(数据)
Actions:会在Dispatch的值不确定,需要向后端异步请求或者有判断等业务逻辑的时候起作用。当不需要异步获取数据或没有判断等业务逻辑时,可以跳过Dispatch这一步,直接Commit。
Vuex的使用
1.安装Vuex插件
命令:
npm i vuex
注意:Vue2只能使用Vuex的3版本,所以安装命令需要指定版本,如下:
npm i vuex@3
2.创建store目录(在根目录src下)和index.js(在store目录中)
配置index.js文件
在main.js中注册store的配置文件(index.js)
在需要使用store的组件中引入:
例子(一个简单的加减法计算器):
分析:上图中,底部的按钮都可以操作求和的值,这里定为sum。那么这个sum就可以作为一个共享的状态(数据)
上下文对象:
getters配置项(index.js中的配置项):
作用:
用于将state中的数据进行加工且不改变原数据,可以理解为共享的计算属性
通过$store.getters.key取值
例子:
27.1Vuex中的映射方法
作用:简化代码
mapState与mapGetters
作用:用于精简获取state和getters中的值的代码
例子:
state的中的名称也要对应:
mapActions与mapMutations(个人感觉没必要,不够清晰)
作用:用于精简调用dispatch和commit函数的代码
例子:
27.2Vuex模块化开发和nameSpace(很有用)
作用:解决index.js中各个配置项过于臃肿的问题
27.3 模块化步骤
在store目录下创建一个新的目录(名字自定义),然后将各个模块分别创建到对应.js文件中
别忘了暴露(export)出去和设置命名空间
在index.js里注册模块
在组件中的使用方式
1.使用映射函数时
2.不使用映射函数时
27.4模块的嵌套
28.路由
什么是路由?
1.一个路由就是一组映射关系(key - value)
2.key 为路径, value 可能是 function 或 component
实现路由需要借助vue-router插件
路由是为了实现SPA 应用
对 SPA 应用的理解
1.单页 Web 应用(single page web application,SPA)。
2.整个应用只有一个完整的页面。
3.点击页面中的导航链接不会刷新页面,只会做页面的局部更新。
4.数据需要通过 ajax 请求获取。
路由分类
1.后端路由:
- 理解:value 是 function, 用于处理客户端提交的请求。
- 工作过程:服务器接收到一个请求时, 根据请求路径找到匹配的函数来处理请求, 返回响应数据。
2.前端路由:
- 理解:value 是 component,用于展示页面内容。
- 工作过程:当浏览器的路径改变时, 对应的组件就会显示。
安装vue-router
命令:
npm i vue-router
注意:Vue2只能使用vue-router的3版本,所以安装命令需要指定版本,如下:
npm i vue-router@3
28.1路由的使用小例子
新建目录和js文件
路由的配置文件(即这里的index.js)
在main.js中注册
component值的另一种定义方式:
组件中的使用
效果演示:
路由使用例子
28.2一些注意点
1.我们一般将路由组件放在名为pages或views的目录中,把一般组件放在名为components的目录中。以示区分
2.当从一个路由组件切换到另一个路由组件时,前一个组件默认是会被销毁。也就是说会触发销毁相关的生命周期钩子函数
针对这里的默认销毁,之后可以配置不让其默认销毁
3.每个路由组件都有自己的
$route
属性,里面存储着自己的路由信息。
但是整个应用只有一个router(管理者),可以通过路由组件的$router
属性获取到
28.3嵌套(多级)路由
嵌套也会体现在路由映射的路径上
关键配置项children
组件中的使用
28.3.1给路由命名(来优化较长的路径)
关键配置项name
注意:要使用这种方式简化路径,那么to必须写成对象形式
28.4路由传参
1.query参数(即用?拼接的参数,一般称为查询参数)
例子(通过路由传递两个参数,一个key为id,一个key为title):
接收参数
先来看下$route上有什么:
所以获取的方式就是this.$route.query.key
2.params参数
注意如果使用params参数,则不能用path属性,只能用name属性
使用方式与query大同小异,如下例子:
在上述第二张图中,如果你不在index.js中配置path,则传递的值不会出现在地址栏(安全性高),但是会有页面初始化问题需要解决
接收参数
先来看下$route上有什么:
所以获取的方式就是this.$route.params.key
28.5路由的props配置项(谁接收参数就在谁身上配置)
作用:简化路由组件中的代码
例子:
28.6router-link标签的replace属性
作用:
控制路由跳转时操作浏览器历史记录的模式
浏览器的历史记录有两种写入方式:分别为push和replace
push是追加历史记录,replace是替换当前记录。路由跳转时候默认为push
用栈的形式理解:repalce模式会把栈底的历史记录替换为当前路由地址
使用方式(直接设置即可):
28.7编程式路由(关注)
原来我们一直使用router-link标签实现路由,这种方式在编译时会把router-link标签转换成a标签。那如果我们想在非a标签(如button,image等)上实现路由或者在函数中实现路由(当然还有很多情况),那么就需要用到编程式的路由。
核心:$router
例子:
$router中的back()、forward()、go()
28.8缓存路由组件(组止切换路由组件时默认销毁之前的路由组件)
作用:
让不展示的路由组件保持挂载,不被销毁
例子:
keep-alive标签的两个属性
1.include属性: 值为字符串或者正则表达式匹配的组件name不会被销毁。
2.exclude属性: 值为字符串或正则表达式匹配的组件name会被销毁。
注意:使用include,exclude 属性需要给router-view中所展示的所有路由组件赋name值,否则 include,exclude将不生效
28.9路由组件特有的两个生命周期钩子
activated() 当路由组件被激活时的钩子
简单来说当某个路由组件展示在你面前时,就会触发该钩子
deactivated() 当路由组件被取消激活时的钩子
简单来说当某个路由组件从你面前消失时,就会触发该钩子
28.10路由守卫(重要,相当于过滤器)
全局前置-路由守卫
关键:beforeEach()
作用:在路由规则(index.js)初始化和每一次路由切换前,调用beforeEach()中的函数(函数中进行权限校验等操作)
三个参数to、from、next
to对象,存放了去哪个路由的路由信息
from对象,存放了从哪个路由来的路由信息
next()函数:用于放行
例子:
全局后置-路由守卫
关键:afterEach()
作用:在路由规则(index.js)初始化和每一次路由切换后,调用afterEach()中的函数
两个参数to、from
to对象,存放了去哪个路由的路由信息
from对象,存放了从哪个路由来的路由信息
不需要next,因为已经切换完了
使用上和beforeEach()一致,这里就不过多赘述了
独享路由守卫
关键:beforeEnter()
独享路由守卫只有前置守卫
例子:
组件内路由守卫
关键:beforeRouteEnter()和beforeRouteLeave()
调用时机(在这方面类似于那两个路由组件特有的生命周期钩子):
beforeRouteEnter():通过路由规则(一定要是按照路由的映射路径进入而不能是直接进入才会触发),进入该组件时被调用
beforeRouteLeave():通过路由规则(一定要是按照路由的映射路径进入而不能是直接进入才会触发),离开该组件时被调用
三个参数to、from、next
在beforeRouteEnter中to是调用的该函数的组件自身
在beforeRouteLeave中from是调用的该函数的组件自身
使用上和其它守卫一致,这里就不过多赘述了
28.10.1meta配置项
作用:该配置项允许我们在其中自定义一些数据以供使用。这些数据会挂载在相应路由身上
例子(通过自定义数据简化代码):
原写法:
简化写法:
28.11history模式与hash模式
默认开启的是hash模式
如何配置工作模式?
hash模式的特点:
1.地址栏有#
2.兼容性好(较老的浏览器也能正常切换路由)
3.若以后将地址通过第三方手机app分享,若app校验严格则地址会被标记为不合法。
history模式的特点:
1.地址栏没有#,就是正常的路径
2.兼容性较差(较老的浏览器可能无法正常切换路由)
3.应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题。
29.Vue项目的打包
命令:
npm run build
打包完成后会在项目目录下生成一个dist文件夹:
这个文件夹就是你整个Vue项目解析成最纯粹的HTML+CSS+JS后的结果
注意:这个文件只有部署到服务器上才能正常使用
Vue组件相关注意点
1.el与data的两种写法
1.1el的两种写法
传统写法:
在data的配置项中指定Vue实例所需绑定的容器
更灵活的写法:
将Vue实例对象抽取出来,并使用$mount()来指定所需绑定的容器
为何灵活?因为这个实例对象被抽取出来了,我们可以仅仅在我们需要时再让它执行相应的动作。
比如这个需求:页面加载完毕1s后将data中name的值显示到页面中:
1.2data的两种写法(Vue3中已经摒弃了对象式写法)
对象式写法:
函数式写法:
或者简单点:
这种写法一般都会有个返回值return,而且一般return的是要使用的数据对象。
在组件中必须使用函数式写法
这里函数的调用者(this)是Vue实例对象,如果写成下图的形式则调用者是window(冒泡):
所以一个注意点:由Vue管理的函数,一定不要写箭头函数,一旦写了箭头函数,this就不再是Vue实例了
2.组件名的命名规则
由一个单词组成:
第一种写法(首字母小写),如:school
第二种写法(首字母大写),如:School
多个单词组成:
第一种写法(kebab-case命名,不同单词之间用短杠连接):my-school
第二种写法(CamelCase命名,不同单词的首字母都大写):MySchool(需要Vue脚手架支持)
备注:
(1)组件名尽可能回避HTML中已有的元素名称,例如: h2、H2都不行。
(2)可以使用name配置项指定组件在开发者工具中呈现的名字。
关于组件标签:
第一种写法:<组件名></组件名>
第二种写法:<组件名/>
备注:不用使用脚手架时,<组件名/>会导致后续组件不能渲染