Vue2-基础
VUE基础
VUE核心
1. 简介
vue是动态构建用户界面的渐进式JavaScript框架
2. 官网
3. 特点
- 遵循MVVM模式
- 编码简洁,体积小,运行效率高,适合移动/PC端开发
- 它本身只关注UI,可引入其他第三方开发项目
4. 使用
- 创建Vue实例,且要传入一个配置对象
- root容器里的代码符合HTML规范,数据引入Vue语法进行赋值
- root容器里的代码被称为【Vue模板】
- 容器与Vue实例的关系是一一对应的
- 实际开发中只有一个Vue实例,并且会配合组件一起使用
- {{xxx}}中的xxx要写js表达式,且xxx会自动读取到data中的所有数学,一旦data中的数据发生改变,模板中用到该数据的地方也会自动更新
区分js表达式和js代码
- 表达式:一个表达式会生成一个值,可以放在任何一个需要值的地方
- js代码(语句):if(){} for(){}
容器与实例绑定方式
el的两种写法
- new Vue时配置el属性
- 写法:new Vue({el:’#root’});
- 简单
- 先创建Vue实例,再通过vm.$mount()指定el的值
- 写法:const v = new Vue({}); v.$mount(’#root’);
- 灵活,可以异步进行绑定
data的两种写法
- 对象式: data:{}
- 函数式: data:function(){return{}},可简写为 data(){return{}}
两种方式皆可,但使用组件时,data必须使用函数式写法
由Vue管理的函数,不能使用箭头函数,使用箭头函数,this就不是指向Vue实例了,而是指向全局的window
模板语法
插值语法
功能:解析标签体内的内容
用法:{{}}
指令语法
功能:解析标签(包括标签属性、标签体内容、绑定事件…)
数据绑定
-
v-bind
- 功能: 单向动态绑定值,数据从data流向页面
- 语法糖 :
-
v-model
- **功能:**双向动态绑定值,数据不仅能从data流向页面,还能从页面流向data
- **应用:**表单类元素
- 语法糖 v-model
MVVM模型
- M:模型(Model),对应data中的数据
- V:视图(View),模板
- VM:视图模型(ViewModel),Vue实例对象
- data中所有的属性,都会在vm上
- vm上所有的属性及Vue原型上所有属性,在Vue模板中都可直接使用
数据代理
通过Object.defindProperty给对象obj添加属性p
- value 设置属性的值
- enumerable 控制属性是否可枚举,默认值是false
- writable 控制属性是否可修改,默认值是false
- configurable 控制属性是否可删除,默认值是false
- 读取obj的p属性时,调用getter,返回值即p的值
- 修改obj的p属性时,调用setter,可得到修改后的值
数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)
Vue中的数据代理
- 通过vm对象代理data对象中属性的操作(读/写)
- 好处:更加方便地操作data中的数据
- 基本原理:
- 通过Object.defindProperty()吧data对象中的属性添加到vm对象上
- 为每一个添加到vm上的属性,都指定一个getter/setter
- 在getter/setter内部去操作(读/写)data中对应的属性
事件处理
1. 基本使用
- v-on
- 功能: 绑定事件
- 语法糖 @
- 用法:
- @xxx=“fun”(无参)
- @xxx=“fun($event,a,…,n)”(传参)
- 事件的回调需要配置在methods对象中,最终挂载在vm上
- methods中配置的函数,不用箭头函数,否则this指向window而不是Vue
- methods中配置的函数,都是被Vue所管理的函数,this指向vm或组件实例对象
2. 事件修饰符
- prevent:阻止默认事件
- stop:阻止事件冒泡
- once:事件只触发一次
- capture:使用事件的捕获模式,默认是冒泡处理事件,由内而外地响应事件,使用capture,可以使事件由外及内地响应事件
- self:只有event.target是当前操作的元素时才触发事件
- passive:事件的默认行为立即执行,无需等待事件回调执行完毕
事件修饰符可以连写,效果与顺序无关
3. 键盘事件
- 常用的按键别名
- enter 回车
- delete 删除(捕获“删除”和“退格”键)
- tab 换行(必须配合keydown使用)
- up 上
- down 下
- left 左
- right 右
- Vue未提供别名的按键,可以使用按键原始的key值进行绑定,但要转为kebab-case(短横线命名)
- 系统修饰键(用法特殊:ctrl alt shift meta)
- 配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发
- 配合keydown使用:正常触发事件
- 可使用keyCode指定具体的按键(不推荐)
- Vue.config.keyCodes.自定义键名=键码,可以定制按键别名
别名必须小写
系统修饰符也可以连写,触发时,必须先按下系统修饰符
计算属性与监视
计算属性
- 定义: 要用的属性不存在,需要通过已有属性进行计算得到
- 原理: 底层借助了Object.defineproperty方法提供的getter和setter
- getter:初次读取该属性时会执行一次,返回该属性值;当依赖的属性发生改变时会被再次调用
- setter:当该属性被修改时会被调用,并返回修改后的值
- 优势:需要通过已有属性进行计算得到所需属性,methods也能实现同样的效果,但使用computed的好处是,计算属性有缓存机制,效率更高,调试也方便。
注:
- 计算属性最终会出现在vm上,可直接读取
- 如果计算属性要被修改,需写set函数去响应修改,且set中要引起计算时依赖的数据发生相应改变
监视
- 当被监视的属性变化时,回调函数自动调用,进行相关操作
- 监视的属性必须存在,才能进行监视
- 监视的两种写法:
- new Vue时传入watch配置
- 通过vm.$watch监视
深度监视
- Vue中的watch默认不检测对象内部值的改变
- 配置deep:true可以检测对象内部值改变
- Vue自身可以检测对象内部值的改变,但Vue提供的watch默认不可以
- 使用watch时,需根据数据的具体结构,决定是否采用深度监视
计算属性与监视之间的区别
- computed能完成的功能,watch也能实现
- watch能实现的功能,computed不一定能完成,如:watch可以进行异步操作
重要原则:
- 所有被Vue所管理的函数,最好使用普通函数声明,这样this指向的就是vm或组件实例对象
- 所有不被Vue所管理的函数(定时器的回调函数,Ajax的回调函数,Promise的回调函数等),最好使用箭头函数进行声明,箭头函数是没有this的,会往上一级寻找全局对象,这样this指向的就是vm或组件实例对象
class与style绑定
class样式
- 写法: :class=“xxx”,xxx可以是字符串、对象、数组
- 字符串写法:适用于类名不确定,需要动态获取
- 对象写法:需绑定多个样式,个数不确定,名字也不确定
- 数组写法:需绑定多个样式,个数和名字都确定,但不确定用不用
style样式
- :style="{key:value}",key需是style中存在的属性名,使用小驼峰命名,value是动态值
- :style="[a, b]",a、b是样式对象
条件渲染
v-if
- 写法:
- v-if=“表达式”
- v-else-if=“表达式”
- v-else=“表达式”
- 适用:切换频率较低的场景
- 不展示的DOM元素直接被移除
- v-if和v-else-if、v-else一起使用,结构不能穿插其他元素
- v-if可以和template联用
v-show
- 写法: v-show=“表达式”
- 适用:切换频率较高的场景
- 特点:不展示的DOM元素,仅仅是样式隐藏,未被移除
使用v-if时,元素可能无法获取到,但使用v-show一定能获取到
列表渲染
v-for
- 用于展示列表数据
- 语法: v-for="(value, key, index) in/of xxx" :key=“index”
- 可遍历:数组、对象、字符串、数字
key值作用
- 作用:key是虚拟DOM对象的标识,当数据发生变化时,Vue回根据【新数据】生成【新的虚拟DOM】,随后Vue进行【新的虚拟DOM】和【原始虚拟DOM】的差异比较,即diff算法,决定使用哪个
- 对比规则:
- 若在【原始虚拟DOM】中找到与【新的虚拟DOM】相同的key,则进一步比较内容:
- 若虚拟DOM中内容没变,则使用【原始虚拟DOM】
- 若虚拟DOM中内容变了,则使用【新的虚拟DOM】,生成新的真实DOM,替换页面原来的真实DOM
- 若在【原始虚拟DOM】中未找到与【新的虚拟DOM】相同的key,则创建新的真实DOM,并渲染到页面
- 若在【原始虚拟DOM】中找到与【新的虚拟DOM】相同的key,则进一步比较内容:
key值的选取
使用index作为key值
- 一般情况(单纯显示等),不会有影响
- 若对数据进行:逆序添加、逆序删除等破坏数据顺序的操作,会产生没有必要的真实DOM更新,影响效率
- 若结构中包含输入类的DOM,会产生错误的DOM更新,引起数据错乱
指定唯一标识作为key值
- 数据对应正确,对数据进行操作时,复用性高,效率也高
列表过滤
可通过watch或computed实现,最好使用computed,结构简单,当涉及的变量发生改变时,就会触发计算属性的重新计算,没有改变则不会调用
Vue监视数据原理
-
Vue会监视data中所有层次的数据
-
监测对象中的数据:通过setter实现,且在new Vue时就传入要监测的数据
- 对象中后追加的属性,Vue默认不做响应式处理
- 若需给后追加的属性做响应式,可使用两种方式
- Vue.set(target, propertyName/index, value)
- vm.$set(target, propertyName/index, value)
-
监测数组中的数据:通过包裹数组更新元素的方式实现。
- 实现步骤:
- 调用原生对应的方法对数组进行更新
- 重新解析模板,进而更新页面
- 修改数组中的某个元素:
- 使用API:push() pop() shift() unshift() splice sort() reverse()
- Vue.set() 或 vm.$set()
- 实现步骤:
注:Vue.set() 或 vm.$set()不能给vm或vm的根数据对象添加属性
收集表单数据
- <input type=“text”>,v-model收集的是value值,用户输入的即为value值
- <input type=“radio”>,v-model收集的是value值,且需给标签配置value值
- <input type=“checkbox”>
- 若未配置value属性,则收集的是checked,为Boolean值
- 若配置了value属性,则根据v-model的初始值判定,若为数组,则收集的是value值组成的数组,若为非数组,则收集的是checked,为Boolean值
- v-model的修饰符
- lazy 失去焦点后再收集数据
- number 输入字符串转为有效的数字
- trim 过滤掉输入的首尾空格
过滤器
- 定义: 对要显示的数据进行特定格式化后再显示,适用于一些简单逻辑的处理
- 语法:
- 注册过滤器:Vue.filter(name, callback) 或 new Vue(filters:{})
- 适用过滤器:{{xxx | 过滤器名}} 或 v-bind:属性 = “xxx | 过滤器名”
过滤器可以接收额外的参数,多个过滤器也可以串联使用
原本的数据并未发生改变,是产生了新的对应的数据
内置指令与自定义指令
内置指令
-
v-bind 单向数据绑定,语法糖 :
-
v-model 双向数据绑定
-
v-for 遍历数组/对象/字符串
-
v-on 绑定事件监听,语法糖 @
-
v-if 条件渲染,动态控制节点是否存在
-
v-else 条件渲染,动态控制节点是否存在
-
v-show 条件渲染,动态控制节点是否展示
-
v-text 向其所在的节点中渲染文本内容,与插值语法的区别在于v-text会替换掉节点中的内容
-
v-html
- 作用:向指定节点中渲染包含html结构的内容
- 与插值语法的区别:
- v-html会替换节点中所有的内容
- v-html可以识别html结构
- 注意:v-html有安全性问题,在网站上动态渲染任意HTML容易导致XSS攻击,一定要在可信的内容上使用v-html,不要在用户提交的内容上使用v-html
-
v-cloak指令
- 本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删除v-cloak属性
- 使用css配合v-cloak可以解决网速慢时页面展示出未被渲染的模板语句
-
v-once:所在节点初次渲染后,就视为静态内容,之后数据的改变不会引起v-once所在结构的更新,可用于优化性能
-
v-pre:跳过其所在节点的编译过程,对于没有使用指令语法、插值语法的节点,使用v-pre,可以加快编译过程
自定义指令
语法
- 局部指令
- new Vue({directives:{指令名:配置对象}})
- new Vue({directives{指令名:回调函数}})
- 全局指令
- Vue.directive(指令名,配置对象)
- Vue.directive(指令名,回调函数)
配置对象中常用的回调函数
- bind 指令与元素成功绑定时调用
- inserted 指令所在元素被插入页面时调用
- update 指令所在模板结构被重新解构时调用
注:
- 指令定义时不加v-,使用时需加上v-
- 指令名为多个单词时,使用kebab-case命名,不能使用camelCase命名
Vue实例生命周期
生命周期
- 又名:生命周期回调函数、生命周期函数、生命周期钩子
- 生命周期函数的名字不可变更,函数体是由程序员根据需求进行编写的
- 生命周期函数中的this执行vm或组件实例对象
常用的生命周期钩子
- mounted:发送Ajax请求、启动定时器、绑定自定义事件、订阅消息等初始化操作
- beforeDestroy:清除定时器、解绑自定义事件、取消订阅消息等收尾工作
销毁Vue实例
- 销毁后借助Vue开发者工具看不到任何信息
- 销毁后自定义事件会失效,但原生DOM事件依然有效
- 一般不会在beforeDestroy操作数据,即使操作数据,也不会触发更新流程
更多前端学习笔记