Vue2
0、前言
- 首先说明:要直接上手简单得很,看官网熟悉大概有哪些东西、怎么用的,然后简单练一下就可以做出程序来了,最多两天,无论Vue2还是Vue3,就都完全可以了,Vue3就是比Vue2多了一些东西而已,所以:要快速上手的,滤过本篇博客,自行查看Vue官网即可
1、基础篇
1.1、初识Vue
- 下载Vue.js,链接:https://cn.vuejs.org/v2/guide/installation.html
- 开发版和生产版就字面意思
- Vue开发工具:vscode(IDEA也可以写Vue程序,用IDEA写之前最好安装一个Vue.js插件,然后就可以写Vue程序了),vscode编辑器百度下载
- vscode中的插件和设置自行百度进行配置( 搜索vscode初始配置即可,然后后续的需要时百度进行配置即可 ),如:浏览器打开方式、Vue快捷模板.........
- 给浏览器安装vuejs devtool工具,阿里云盘链接:https://www.aliyundrive.com/s/JtHVq5SX3po
- 把文件夹下载了,拖到拓展程序中即可
01-初识vue.html
第一个vue程序,并使用插值表达式取得值为:{{name}}
初识Vue小结
- Vue容器中的代码一样符合html规范,只不过是混入了一些Vue的特殊用法而已,这个容器中的代码被称为:Vue模板
- Vue实例( new Vue处 )和 Vue容器是一 一对应的( 即:一个Vue实例只能对应一个Vue容器 )
- 当然:真实开发中只有一个Vue实例,后续会见到
- {{xxx}}中的xxx要写js表达式( {{xxx}}即为插值表达式,就是取data中的东西而已 ),且xxx可以自动读取到data中的所有属性
- js表达式 和 js代码的区分
- 1、表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方,如:
- a
- a + b
- test( 2 )
- x === y ? 'a' : 'b'
- 2、js代码:
- if(){}
- for(){}
- .........
- 1、表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方,如:
- js表达式 和 js代码的区分
- 一旦data中的数据发生改变,那么页面中使用该数据的地方一样发生改变
1.2、认识v-bind
02-vue之v-bind
1.3、认识Vue的数据绑定
- 这里需要了解mvvm模式,要理解,可以参照java中的mvc模式( MVVM本来就是借鉴的MVC模式而整出来的 )
03-v-model
单向绑定:
双向绑定:
双向绑定:
1.4、el和data的两种写法
04-vue的el和data的两种写法
小结:el和data的两种写法
- 1、el
- (1)、new Vue时配置el选项
- (2)、先创建Vue实例,然后再通过vm.this.$mount( '#app' ) 来指定el的值
- 2、data
- (1)、对象式
- (2)、函数式
- 如何选择哪种用法:目前都可以,但是后续会玩组件,则:必须用函数式,而且不可以用兰姆达表达式( 即:上面的data:()=>{},否则:会出错 )
- 3、一个原则:
- 由Vue管理的函数,一定不要写箭头函数,就上面的兰姆达表达式,否则就会导致this不再是Vue实例了( 这个this有大用处,在"new Vue中"用了this就是指的当前的Vue实例,后续可以通过这个this玩很多东西 )
1.5、理解MVVM模型
理解MVVM
姓名:{{name}}
性别:{{sex}}
智商:{{1+1}}
小结:MVVM模型
- 1、M:Model( 模型 ) ————> data中的数据
- 2、V:View( 视图 ) —————> 模板代码
- 3、ViewModel:视图模型( ViewModel ) ————> Vue实例
观察效果发现
- 1、data中所有的属性最后都在vm身上( 即:ViewModel )
- 2、vm身上所有的属性 及 Vue原型上的所有属性,在Vue模板中都可以直接使用
1.6、回顾Object.defineProperty()函数
05-了解object.defineProperty()
- 注意:去找temp或者值是调用了get()方法进行获取的,相应的set()方法也知道是怎么回事了
1.7、简单理解数据代理原理
06-简单理解数据代理
- 注意:上面这个是简单了解,深入了解在后面玩Vue监视数据原理时会再次见到defineProperty()和这个数据代理
1.8、事件绑定及其修饰符
07-事件绑定及其修饰符
1.9、计算属性
10-计算属性conputed
姓名:
性别:
信息: {{info}}
计算属性小结
- 定义:要用的属性不存在,要通过已有属性计算得来
- 原理:借助了object.defineproperty()的getter和setter
- get()什么时候执行
- 1、初次读取时会执行一次
- 2、当依赖的数据发生改变时会再次被调用
- 优势:与methods相比,内部有缓存机制( 复用 ),效率更高、调试方便
- 注意:
- 1、计算属性最终都会在vm( Vue实例 )上,直接读取即可
- 2、若计算属性要被修改,那必须写set()去响应修改,且set()中要引起计算时依赖的数据发生改变( 例子中没有做这一步,在控制台输出后面再执行一步让依赖数据发生改变就可以了【 使用value.split('-')进行拆分嘛,然后把得到的数据对应元素赋给name和sex即可 】 )
- 另外:计算属性是可以简写的
- 就是把set()去掉,因为:更多时候是读取,并不修改,同时修改还要去控制台( 刷新就又没了 ),因此:把set()去掉就是计算属性的简写
- 多提一嘴:react的核心思想就是虚拟DOM,而它的原理我个人认为就是计算属性
1.9.1、结合computed、methods、v-on做一个小Demo
11 - 使用计算属性做一个Demo
你是:{{result}}
- 我们主要做的是图中的这一步,因此:简化 ———— 衍生出v-on的另外一个玩法
12 - 使用计算属性做一个Demo 简化
你是:{{result}}
1.10、监视属性
13 - 监视属性 watch
你是:{{result}}
监视属性 watch小结
- 1、当被监视的属性变化时,回调函数自动调用,进行相关操作
- 回调函数:指的是:handler() ,第一种写法也是可以用handler,只是把watch换成了$watch而已,后面步骤其实是一样的,只是我把第一种给简写了而已
- 2、监视的属性必须存在,才能进行监视
- 3、监视有两种写法
- (1)、new Vue时传入watch配置
- (2)、通过vm.$watch内置函数进行监视
1.10.1、深度监视 - 需要掌握的一种
14 - 深度监视
你是:{{result}}
深度监视小结
- 1、Vue中的watch默认不监视对象内部值得改变( 监视的是一层 )
- 2、配置deep:true可以监视对象内部值得改变( 监视多层 )
- 注意:
- 1、Vue自身可以监视对象内部值得改变,但Vue提供的watch默认不可以
- 这个可以验证的,最后是绑定在vm上的,那么在控制台使用vm去改变那么页面上也可以改变,这里是为了解释Vue不是不可以监视多层的改变,只是:watch默认不支持
- 2、使用watch时根据数据的具体结构,决定是否采用深度监视
- 1、Vue自身可以监视对象内部值得改变,但Vue提供的watch默认不可以
1.11、computed和watch的坑
使用watch做个例子
15 - computed和watch的坑
姓:
名:
信息: {{fullname}}
用computed实现
02 - computed实现
姓:
名:
信息: {{fullname}}
最后运行的效果都是一样的,而官网中对这二者有着这样的实例演示
但是:虽然看起来没区别,可是computed和watch还是有区别的,假如:现在我需要让姓改了之后,隔1s之后再显示到信息那里。那么:computed无法做到,但是watch就可以
03 - 用watch实现异步操作
姓:
名:
信息: {{fullname}}
- 而利用computed就不可以做到上面的这种异步操作
computed和watch的区别
- 1、computed能完成的功能,watch绝对都可以做到
- 2、watch能完成的功能,computed不一定可以做到,如:上面举的例子进行异步操作
- 原则:
- 1、凡是被Vue所管理的函数,最好都写成函数式( 即:普通函数 ),这是为了能够让this指向Vue实例 或 组件实例对象( 后续会见到 ),这样就可以通过this拿到它们对应的东西
- 2、凡是不被Vue所管理的函数( 如:定时器里面的回调函数、ajax中的回调函数.... ),最好都写成兰姆达表达式( 即:箭头函数 ),这样做也是为了能够让this指向Vue实例 或 组件实例对象
1.12、样式绑定
1.12.1、class样式绑定
假如有如下的一个页面
01 - class样式绑定
©紫邪情 · 用Java改变未来
©紫邪情 · 登录
- 现在需求1、中间的登录页样式,不要这种,想要换一种:假如是如下这种
.login1 {
background: #ffffffd6;
border-radius: 2px;
}
- 可是,看了效果还是不行,又想要另外一种效果,此时:增加一种样式
.login2 {
background: rgba(0,0,0,.8);
box-sizing : border-box;
box-shadow: 0 15px 25px rgba(0,0,0,.5);
border-radius: 10px;
}
©紫邪情 · 用Java改变未来
©紫邪情 · 登录
2 - 数组写法
©紫邪情 · 用Java改变未来
©紫邪情 · 登录
需求3、要绑定的class名字确定,但是:个数不确定,也需要动态绑定
class样式绑定小结
- 1、字符串写法,适用于:class名字不确定时使用
- 2、数组写法,适用于:class名字、个数都不确定时使用
- 3、对象写法,适用于:class名字确定、但个数不确定( 如:例子中的login1可能用,可能不用,而login2也是一样,所以这就是各种组合 )
1.12.2、style行内样式绑定 - 了解即可
class和style样式绑定小结
- 1、class样式绑定
- 写法 :class = "xxxx",其中xxxx可以使字符串、数组、对象
- 字符串写法适用于:类名不确定、要动态获取( 交由Vue管理,随时调试 )
- 数组写法:要绑定多个样式、class名字和个数都不确定
- 对象写法:要绑定多个样式、class名字确定而个数不确定( 个数不确定是因为不知道某个样式用不用 )
- 2、style样式绑定
- 写法 :style = “xxx",其中xxx可以是对象、数组
- 对象写法是推荐用的一种
- 3、原则
- 在Vue中静态不变的东西,就放在Vue模板中即可( 即:那个div容器中 ),而动态改变的东西就放在Vue实例身上
1.13、条件渲染
1.13.1、v-if
1 - v-if
- 注意:v-if、v-else-if、v-else组合用时,需要留意代码是紧挨着的即可,这就好比:java的Mybatis框架的pageHelper分页插件,用startPage和pageInfo联合使用一样( 数据查询完了之后放到pageInfo<>()中,这二者中间就不可以夹杂另外的语句,否则报错 )
1.13.2、v-if配套工具template
1.13.3、v-show
v-if和v-show小结
- 1、v-if
- 2、v-show
- 写法:v-show = “表达式”
- 适用于:切换频率较高的场景
- 特点:不展示的DOM元素未被移除,仅仅是使用display:none样式给隐藏掉了而已
- 3、注意:使用v-if时,元素可能无法获取到,而使用v-show,则:一定可以获取到
- 因为:v-show是做了样式修改,但是DOM节点还在,所以是可以操作这个DOM节点的,但是:v-if是直接把DOM元素给移除掉了( 万一是误操作而导致把v-if的值弄为false了,那后续万一其他地方用到了v-if移除的节点呢?不就裂开了吗 )
1.14、列表渲染
1.14.1、认识v-for
1 - 认识v-for
人员信息
-
{{p.name}} ----- {{p.age}}
-
{{val.name}} ----- {{val.age}} ------ {{index}}
神奇之地
-
{{val}} ------ {{index}}
v-for小结
- 语法:v-for = “ ( intem,index ) in xxx ” :key = “yyy”
- 可遍历:数组、对象、字符串( 用得少 )、指定次数( 用得更少 )
- 可用于:展示列表数据
1.14.2、key值的坑( 作用与原理 )
- 在前面v-for中key值使用index时有一些坑的,正确的做法是:最好使用数据的id作为key值,但不是说index作为key值就是错的,前面演示过了,是正常效果,可是:在特定的场景下使用 :key = "index"就会出问题
实例
2 - key值的坑
人员信息
-
{{p.name}} ----- {{p.age}}
-
其中:图中的对比算法就是所谓的“diff算法”
-
而不写key的话,Vue做了一件默认的操作,就是把遍历的index作为了key值,也就是和前面使用index作为key值是一样的效果了
把以上的内容,换成文字小结一波
-
Vue中的key有什么作用( 原理是什么? )【 不止Vue啊,React中的key也是同样的原理,前面说过React核心就是虚拟DOM 】
-
1、虚拟DOM中key的作用
- key是虚拟DOM对象的标识,当状态中的数据发生改变时,Vue会根据【 新数据 】生成【 新的虚拟DOM 】
- 随后Vue进行【 新虚拟DOM 】 与【 旧虚拟DOM 】的差异比较( 对比算法 / diff算法 )
-
2、对比算法的规则
- (1)、旧虚拟DOM中找到了与新虚拟DOM相同的key
- 若虚拟DOM中内容没变,则:直接使用之前的真实DOM
- 若虚拟DOM中内容变了,则:生成新的真实DOM,随后替换掉页面中之前的真实DOM
- (2)、旧虚拟DOM中未找到与新虚拟DOM相同的key
- 直接创建新的真实DOM,虽然渲染到页面
- (1)、旧虚拟DOM中找到了与新虚拟DOM相同的key
-
3、用index作为key值可能会引发的问题
-
4、开发中如何选择key?
- (1)、最好使用数据自己的唯一标识作为key值,比如:手机号、身份证号.....( 直接利用数据库中的主键id也行 )
- (2)、如果不存在对数据逆序添加、逆序删除等破坏数据顺序的操作,只用来渲染列表页面,则:使用index作为key是莫问题的
-
1.1.4.3、列表过滤(查询功能 )
1、使用watch实现
3 - 列表过滤( 查询功能 )
人员信息列表
搜索:
-
{{p.name}} -------- {{p.age}}
2、使用computed实现
3 - 列表过滤( 查询功能 )
人员信息列表
搜索:
-
{{p.name}} -------- {{p.age}}
1.14.4、列表排序
4 - 列表排序
人员信息
搜索:
-
{{p.name}} ----- {{p.age}}
1.15、Vue监视数据的原理
1.15.1、监视数据失效实例
先来看看Vue检测属性失效的问题,从而引申处Vue监视数据的原理
先来玩正常版
1 - 监视数据失效实例
Vue监视数据失效问题
-
{{p.name}} ---- {{p.age}}
- 上面的问题是怎么回事?要知道这个的原因就需要了解一下Vue监视数据的原理了,可是装数据的类型有什么?对象 { } 和 数组 [ ] ,所以:这里又得去了解这两种类型的原理,当然:像什么data中还可以放字符串这就不用说明了,了解了对象和数组,字符串也就可以反应过来了
1.15.2、Vue监视对象的原理
-
前面就说过,这个数据代理,只是简单了解而已,上面的流程其实不算对,因为少了一个步骤,整个流程应该是:自己写的data ————> 对data进行加工 —————> 把data中的数据给_data ————> 再把_data的内容给页面需要的data中( 即:这一步相当于执行了 vm._data = data , 这个data就是页面上的data嘛,所以就成功地让页面中的数据跟着自己的修改而改变了,但是底层不是用 vm._data = data,方法名不一样,而且还要更复杂一点
-
来回顾一下例子
3 - 回顾数据代理
姓名: {{person.name}}
性别: {{person.sex}}
根据上面的原理,简单模拟一个vue的数据监视
4 - 模拟Vue数据监视
- 当然:上面只是简单流程,甚至多层对象的data加工( 一个对象中又有另一个对象 / 数组,这样递归下去,所以Vue做得完善一点就是再对对象进行了递归,直到不是对象了为止 ),同时:这个例子也没有弄“数据修改再次解析模板、生成虚拟DOM、响应数据的事 ,研究得明明白白,全整得出来的话,我还坐起,早飘了!!! )
1.15.3、了解Vue.set( target ,key , val )
实例
5 - 了解Vue.set( target, key, val )
姓名: {{person.name}}
性别: {{person.sex}}
6 - target参数的坑
姓名: {{name}}
性别: {{sex}}
年龄: {{age}}
- 这就是target这个参数的坑:target不可以直接指向vm这个实例对象,更不可以把要操作的对象指向data这个根数据对象上
1.15.4、Vue监视数组数据的原理
写个正常例子,去控制台看数组的结构
1 - 正常实例 - 控制台查看结构
爱好
-
{{h}}
-
这二者都是使用的"索引"来找的数组的具体某个值,而这:恰恰就是一个坑,想一下在Vue中我们操作数组是怎么做的?是通过数组调了对应的API,如:arr.push()、arr.shift()........,那Vue怎么知道我调的是哪个API( 换句话说:它怎么知道这个API是做什么的 / 这个API是数组中的 ),要搞这个问题,就要看看在js中是怎么去调数组的API的?
所以:Vue中要监视到数组的变化,调用下面的7个API中的一个就可以
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
一定是上面的7个API中的一个才可以吗?
- 答案也肯定不是,前面玩了Vue.set( target, key, val )和vm.$set( target, key, val )也可以做到啊,只需要把target转成对应的对象即可( 只要找他数组中要监视到的对象就行嘛
1.15.5、Vue监视数据原理总结
Vue监视数据的原理
- 1、vue会监视data中所有层级的数据
- 2、Vue如何监视对象中的数据?
- 通过setter实现监视,且要在new Vue时就传入要监视的数据
- (1)、对象中后追加的属性,Vue默认不做响应式处理
- (2)、如果需要对后添加的属性做响应式,则:通过如下API就可做到
- vue.set( target, key, val ) 说明一下:其中的key可以是属性名,也可以是数组的下标值
- vm.$set( target, key, val ) key和上面一样
- 3、Vue如何监视数组中的数据?
- 通过封装 / 包裹数组更新元素的方法来实现,这个封装的方法做了两件事
- (1)、调用数组原生的同名API,对数组进行更新
- (2)、重新解析数据、生成新的虚拟DOM、进行对比算法、响应页面
- 通过封装 / 包裹数组更新元素的方法来实现,这个封装的方法做了两件事
- 4、在Vue中要修改数组中的某个元素时,只能使用如下的方法
- (1)、push()、pop()、shift()、unshift()、splice()、sort()、reverse()
- (2)、vue.set( target, key, val ) 或 vm.$set( target, key, val )
- 注意:vue.set( target, key, val ) 和 vm.$set( target, key, val ) 不能给vm( 即:vue实例 ) 或 根数据对象data 进行添加属性操作
- 5、前面分析对象的原理时说过一个流程:
- 数据发生改变,是通过setter来获取改变的数据,从而重新解析模板、生成新的虚拟DOM、进行对比算法、响应页面。在这里面有一个重要的流程:就是1、数据改变、setter获取到改变后的值、2、setter重新解析模板,这里1 ——> 2这一步有个专业的词叫做:数据劫持,劫持劫持嘛,半路把东西拿走了呗( 就是setter把数据劫走了,它去做后续的操作 )
1.16、input输入框中v-model的使用技巧
- 原因:
6、checkBox的另一种类型:做协议勾选的
8、v-model的修饰符
-
前面说过事件的修饰符,
- prevent 表示:阻止默认事件的触发
- stop 表示:阻止事件冒泡
- once 表示:只执行一次事件
-
而v-model也有修饰符,就3个而已:number、lazy、trim,看名字大概就知道是干嘛的
(1)、number修饰符,这个修饰符一般都是和input的number类型一起使用的,如:增加一个年龄
(2)、lazy修饰符,这个修饰符就光标离开之后再收集数据,拿textarea来举例
(3)、trim修饰符,这个在java的String中见过,再熟悉不过了,就是去除前后的空格,不演示了
9、使用v-model收集表单数据小结
- 若: < input type = "text" /> ,则:v-model收集的是value值,而用户输入的就是value值
- 若:< input type = "radio" /> ,则:v-model收集的是value值,且要给标签配置value属性
- 若:< input type = "checkBox" />
- 1、没有配置input的value属性,那么收集的就是checked( true / false,是否勾选 )
- 2、配置input的value属性:
- (1)、v-model的初始值是非数组,那么收集的就是checked
- (2)、v-model的初始值是数组,那么收集的就是value组成的数组
- v-model的3个修饰符
- number 将输入的字符串转为 有效的数字
- lazy 失去光标焦点才收集数据
- trim 去掉首尾的空格
1.18、Vue内置指令
回顾一下:已经学了Vue的哪些内置指令
- v-on
- v-bind
- v-model
- v-if 、v-else-if、v-else
- v-show
另外还有哪些内置指令?
- v-text
- v-html
- v-cloak
- v-once
- v-pre
- 以及可以自定义指令
接下来就对上面还未见到的内置指令做一下演示和说明
1.18.1、v-text指令
1 - v-text指令
{{name}}
- 效果如下
- 但是:v-text和插值表达式有区别
-
这就是插值表达式和v-text指令的最大区别,v-text是将v-text的值去找寻之后,把内容回填到对应的标签里面,是内容全覆盖,所以:例子中就算写了“信息*两个字,但是:也会被v-text值的返回内容给全覆盖了
-
当然:还有一个注意点
- v-text和插值表达式都不可以解析html标签
v-text内置指令小结
- 作用:向其所在的节点中渲染“文本”内容
- 与插值表达式的区别:v-text会替换掉节点中的所有内容,而{{xxx}}插值表达式则不会
1.18.2、v-html内置指令 - 根据需要慎用
先说用法,其实和v-text差不多,但是内在区别很大
- 用法简单,但是:谨慎用就体现在可以解析html标签上,不安全
-
这里涉及到cookie的机制( 后端理解就对照玩大系统、分布式时的jwt单点登录流程原理 )
-
去访问一个需要输入信息的网站时( 如:要输入用户名、密码之类的重要信息 ),信息在你要登录的网站的服务器上核对成功之后,服务器返回的除了会把用户名、密码这些后续需要的东西返回回来之外,还会返回一些服务器响应的特殊json字符串,从而凭借服务器返回的这些信息,你才可以进入到相应的页面,而这些信息就保存在浏览器的cookie中,如下图:
-
而服务器返回的json信息有大用处,你的重要信息就保存在cookie中,比如:成功登录之后,操作其他的功能就不会要求再次输入用户名、密码之类的( 个别除外,那是另外设计机制 ),这里聪明点的就会想到另一个东西:跨浏览器不会出现无账号密码就可以访问涩,比如:我在google浏览器登录之后,再用Edge浏览器打开,那Edge是不会登录的涩,但是:利用v-html就可以做到窃取你在google浏览器中登录之后服务器给你返回的json信息,然后把这些json信息放到Edge浏览器中,那么Edge浏览器就不需要做登录操作,一样可以登录进去
-
而使用v-html能够获取到cookie是因为:可以在用v-html获取的内容中夹杂一些获取你当前服务器的cookie,然后拼接到窃取人的服务器地址的后面( 比如:网页中的恶意广告,那广告词中的词条是通过v-html渲染上去的,那么一点击就会把你电脑上的cookie获取到然后转发到他自己的服务器上去 )
-
当然:现在好一点的浏览器都为了防止xss攻击( 模拟用户之手 ),所以:对浏览器做了一些安全限定,最典型的就是google浏览器,默认是不可以携带cookie转发的,但是有些做的不好的浏览器( 网站 )就可能没弄这些,一点然后跳过去就遭殃了
-
v-html小结
- 作用:向指定节点中渲染包含html结构的内容
- 与插值表达式的区别
- 1、v-html会替换掉节点中所有的内容,而插值表达式{{xx}}则不会
- 2、v-html可以识别html结构
- 特别注意:v-html有安全性问题
- 1、在网站上动态渲染任意html是非常危险的,容易导致XSS攻击
- 2、一定要在可信的内容上使用v-html,此指令永远不要用在用户提交的内容上!!!!!!
1.19.3、v-cloak指令
- 这是专门用来处理页面渲染时因网络或其他原因导致页面无法及时刷新出来,把页面加载过程给显露出来了( 等到后续懂了Vue的生命周期时,此命令会更容易懂 ,当然:现在也很容易懂)
实例
-
然后重新刷新页面,会发现页面的name会有一个稍微慢一点的页面加载过程,是从 {{name}} ——————> 紫邪情,这里不方便演示,就不弄了
v-cloak指令小结
- 本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性
- 使用CSS配合v-cloak指令可以解决网速慢时页面展示出{{xxx}}插值表达式 / axios交互延迟的问题
- axios就是另类的ajax,甚至和ajax差不多一模一样,而Vue本身并不支持交互,所以才需要借助axios插件来进行交互,这也是玩了Vue之后必须掌握的一个知识点,对于学java的人来说太简单了,上手的话,看一眼就懂了,那就是一个链式调用罢了,就和StringBuilder一样链式调,只是需要传一些东西进去而已,而传的东西在ajax中都见过,而如果链式调起来看着不舒服,那就封装一下就OK了( 当然:只学了Vue,然后使用ajax一样可以进行数据发送,只是axios更轻小而已 )
1.19.4、v-once指令
- 因此:使用v-once实现效果
v-once指令小结
- v-once所在节点在初次动态渲染后,就视为静态内容了
- 以后数据的改变不会引起v-once所在结构的更新,可以用来做性能优化
- 注意:和事件修饰符中的once区别开
- 事件中的once修饰符是说的事件( 函数 / js表达式)只执行一次
- 而v-once指令是说的对div容器中的模板只动态渲染一次
1.19.5、v-pre指令
v-pre小结
- v-pre是跳过其所在节点的编译过程,也就是:原本是什么样子,那么Vue就拿到的是什么样子,不会再去解析它
- 可利用它跳过:没有使用指令语法、没有使用插值表达式的节点,从而加快编译,优化性能
1.19.6、自定义指令
1.19.6.1、函数式定义
1 - 函数式定义
原来的数值为: {{number}}
扩大10倍之后的数值:
注意点:上面自定义的指令什么时候会被调用?
- 1、毫无疑问,HTML元素和自定义指令成功绑定时,自定义指令就会被调用,注意:这句话有坑,待会儿下一种自定义方式就会弄到这句话
- 看到的效果就是初始化页面一上来就调用了一次,但是里面的门道不是这样的,成功绑定是什么意思,下一种自定义指令再说明
- 2、自定义指令所在的模板( Div容器 )被重新解析时会被调用
- 别混淆了此种说法:自定义指令所依赖的数据发生改变时就会调用自定义指令,此种说法是错的
1.19.6.2、对象式定义
2 - 对象式定义
计数: {{count}}
-
现在再加一点要求:就是页面一初始化时,焦点就在input框中,此时发现貌似做不到( 用js可以做到啊,只是现在是用Vue ),为什么Vue不行?因为这要考虑到Vue的加载顺序问题( 重点咯,开始衍生出Vue的生命周期和钩子函数咯,也就可以很容器理解前面使用v-cloak解决页面闪烁的问题了)
-
所以:应该把focus()获取焦点,放到页面渲染时再做,不然:无法聚焦
1.19.3、自定义指令的两大坑和补充
1、命名的坑
-
这个坑在前面玩对象式时已经说过了,多个单词的名字别采用驼峰命名,但是:只说了这一点,并没有说正确形式应该怎么命名
-
现在采用驼峰命名看一下这个坑
-
为什么自定义指令中的this是window对象?
- 这是因为:自定义指令已经不是Vue自己本身的东西了,而是根据需要自行设计,因此:此时你要操作的是HTML的DOM节点,因此:为了方便,Vue就把this还回来了,重新给了window
3、补充:自定义全局指令
4 - 全局指令配置
计数: {{count}}
- 创建了全局指令之后,就可以摆脱只能在一个div容器中使用前面那种局部指令的缺陷了,也就是:现在可以再开一个div容器,然后在这个新开的div容器中一样可以使用全局配置中的东西
- 全局配置东西基本上都是这么玩的,后续玩组件会用到
1.19.4、指令总结
-
1、定义语法
-
(1)、局部指令
-
对象式 new Vue({ directives: { 指令名: { 配置 } } }) 函数式 new Vue({ directives: { 指令名(){ 配置 } } })
-
(2)、全局配置
-
对象式 Vue.directive( '指令名',{ 配置 }) 函数式 Vue.directive('指令名', function(){ 配置 })
-
-
配置中常用的3个回调
- (1)、bind( element, binding ) 指令与元素成功绑定时调用
- (2)、inserted( element, binding ) 指令所在元素被解析完、插入到页面时调用
- (3)、update( element, binding ) 指令所在模板被重新解析时调用
-
注意项:
- (1)、指令定义时不加 v- ,但使用时必须加 v-
- (2)、指令名如果是多个单词,要使用 - 短横线分隔开,切忌使用驼峰命名( 包括大驼峰和小驼峰 )
-
-
1.20、Vue生命周期
1.20.1、了解Vue生命周期的概念
做这么一个效果 —— 文本动态透明
- 先用不对的方式来做一下
1 - 认识Vue生命周期概念
玩动态改变文本透明度
{{ change() }}
- 这就是前面说mounted()为什么是:Vue解析完了模板之后,准备把“初始的真实DOM”渲染到页面时会调用的一个函数,初始的真实DOM,是初次转成真实DOM时执行的,后面数值改变那是更新,对于模板来说,它不叫改变,别忘了前面玩diff算法时说过的流程 ———— 新的虚拟DOM会和初始虚拟DOM进行对比
Vue生命周期总结
- 定义:Vue在关键时刻帮我们调用的一些特殊名称的函数
- 别名:生命周期回调函数 / 生命周期函数 / 生命周期钩子
- 注意:
- 生命周期函数的名字不可更改,但是:函数中的执行体是可以自己根据需求编写的
- 生命周期函数中的this指向是Vue实例 或 组件实例对象
生命周期过程
- 首先这个知识点的原理图在官网中有
- 但是:我对上图中的内容做了补充( 蓝色的东西就是新加的 )
- 上面这个图是为了先了解大概,接下来会简单说明一下图中的内容
1.20.2、Vue的挂载流程
- 所谓的挂载在前面引入生命周期概念时说过了,就是Vue在调mounted()时,换言之:就是前面图中直到mounted()时的步骤就是挂载流程,只是需要解读一下
先来看一下这部分
- 说在beforeCreate时还不可以使用vm访问data中的数据、methods中的方法,在这之前只开始初始化生命周期、事件,那就来测试一下
2 - Vue的挂载
{{name}}
- 要出现下面的页面,记得运行程序之后,先调出控制台,然后刷新页面才会进入debug断点
接着来看这一部分
- 说的是:已经开始了数据监测、数据代理,可以使用vm访问data和methods了,那久测试一下
接着看这一部分
- 先看下面部分,说:页面呈现的是未经编译的DOM结果且对DOM的操作,“最终”都不奏效,测试一下
- 同时还说:所有对DOM结构的操作都不奏效,那就试一下
- 现在接着回去看那个逻辑判断里面的内容
- 外层和内层就是下面这个
- 而所谓的template模板更简单
- 截图中有个地方容易产生歧义:template中应该还需要使用一个div给套起来,template中只能有一个根节点,而例子中有h2 和 button两个节点,会报错的,所以需要使用div( 或其他标签 )把要写的代码给套起来,可以对照Vue实例和容器的对应关系( 一 一对应 )
最后来看这一部分
- 但是:这里有一个点需要注意
- 这里是将真实DOM使用”vm.$el“把真实DOM中的内容给复制了一份保存起来了,这一步很关键,为的就是后续 新的虚拟DOM 和 初始的虚拟DOM进行对比算法时,有相同的数据内容,那么新的虚拟DOM就会直接用初始虚拟DOM的数据( 前面玩v-for中key的原理时,key值为index和数据id的区别 ),而要用初始DOM就需要找到初始DOM呗,它保存起来之后就方便找到了嘛
以上就是Vue的挂载过程
1.20.3、Vue的更新流程
- 内容就一丢丢,下图中红色框起来的内容
来看beforeUpdate()
接着来看Updated
1.20.4、Vue的销毁流程
- 内容就是图中的最后一点东西,但是:这里面坑也是有点多的
- 图中提到了"vm.$destroy()" 和 销毁哪些东西,所以先看官网对销毁的介绍
- 现在就用代码去验证一下图中的内容,需要改造一下代码
- 执行效果如下
- 开始踩另一个坑
- vm确实是销毁了,但是这个坑是前面说的销毁事件监听,它销毁的是:自定义事件( 后续接触 ),所以Vue自身的事件还在,也执行了
- 那又有问题:页面为什么没 +1 ?
- 是因为beforeDestroy ()是一个贼尴尬的阶段,这里面确实可以拿到data、methods、指令这些,但是:当一点击销毁( 调用了"vm.$destroy()" ),程序就会执行beforeDestroy (),这里面的调用methods也会去执行,可是:关键点就是它不会再去调用beforeUpdate ()和updated () ———— 正常流程是数据发生改变就会调这两个,但是:deforeDestroy()就不会调用,所以:才在前面说 此阶段一般干的事情是:关闭定时器、解除自定义事件绑定等操作
以上的这些流程也是React的生命周期流程,当然:有些名字改了一下啊,而Vue就多了一个destroyed(),但是此阶段也是个极度忽略的阶段,因为没什么事做
1.20.5、Vue生命周期总结
-
Vue生命周期共有8个( 4对 ),另外其实还有3个周期( 但是:这三个需要到router路由中玩切换时才能整 )
-
beforeCreate() created() beforeMount() mounted() beforeUpdate() Updated() beforeDestroy() Destroyed()
-
其中:常用的钩子函数就两个
- mounted() 用来发送ajax请求、启动定时器、绑定自定义事件、订阅消息( 后续说明 )等 即:完成的是"初始化操作"
- beforeDestroy() 用来清除定时器、解绑自定义事件、取消订阅消息等,即:做的是“收尾操作”
-
关于销毁vm的问题
- 销毁后借助Vue开发者工具是看不到任何信息的
- 销毁后自定义事件会失效,但是:Vue原生DOM事件依然有效
- 一般不会在beforeDestroy()中操作数据,因为就算操作了,那也不会触发beforeUpdate()和updated()
-
2、下一篇:组件化开发链接地址
- https://www.cnblogs.com/xiegongzi/p/15823605.html