目录
注意
js表达式和js代码
初始Vue
模板语法(插值和指令)
数据绑定(v-bind和v-model)
el和data的两种写法
MVVM模型
Object.defineProperty
数据代理
事件处理
事件的基本使用
事件修饰符
键盘事件
计算属性(computed)
监视属性(watch)
computed和watch之间的区别
绑定class样式(bind)
绑定style样式(bind)
条件渲染(指令)
列表渲染
列表过滤
列表排序
数组中响应式的方法
key的作用和原理
Vue监视数据的原理 (响应式)
收集表单数据( v-model )
过滤器
高阶函数( filter / map / reduce )
内置指令
v-bind(涉及到上面的绑定class样式和style样式)
v-on(事件监听)
v-model
自定义指令
生命周期
生命周期总结
组件
组件化思想
组件注意点
模板的分离写法
组件数据的存放
组件中的data为什么是个函数
VueComponent
Vue和VueComponent的关系
关于不同版本的Vue
ref属性
props配置(父子组件之间的通信)
父传子
子传父
父子组件的访问方式
mixin(混入)
插件
scoped样式
webStorage
组件的自定义事件
查看版本的命令
js表达式和js代码
* 表达式
* 一个表达式会产成一个值,可以放在任何一个需要值的地方
* js代码(语句)
* if(){}
* for(){}
初始Vue
* 想让Vue工作,就必须创建一个Vue实例,且要传入一个配置对象
* root容器里的代码依然符合html规范,只不过混入了一些特殊的语法
* root容器里的代码被称为[Vue模块]
* Vue实例和容器是一一对应的
* /真实开发中只有一个Vue实例,并且会配合着组件一起使用
* {{xxx}}中的xxx要写js表达式,/*且xxx可以自动读取到data中的所有属性*/
* #一旦data中的数据发生变化,那么页面中用到该数据的地方也会自动更新
模板语法(插值和指令)
* 插值语法
* 功能: /用于解析标签体内容
* 写法: {{xxx}},xxx是js表达式,且可以直接读取到data中的所有属性
//Mustache(胡子/胡须)语法表示大括号
* #指令语法
* 功能: /用于解析标签(包括:标签属性,标签体内容,绑定事件...)
* 举例: v-bind:href="xxx"或简写为 :href="xxx",
xxx同样要写js表达式,且可以直接读取到data中的所有属性
// (会将xxx当成js表达式去执行)
数据绑定(v-bind和v-model)
* 单向
* v-bind(数据只能从data流向页面,/*单向流动*/)
* 双向
* v-model
* 数据不仅能从data流向页面,也可以从页面流向data
* /*只能应用在表单类元素(输入类元素)上*/
* 注意
* #双向绑定一般都应用在表单类元素上
* /v-model: value --> 简写为v-model
//(因为v-model默认收集的就是value的值)
el和data的两种写法
* el有2种写法
* new Vue时候配置el属性
* /先创建Vue实例,随后再通过vm.$mount('#root')指定el的值
* data有2种写法
* 对象式
* 函数式
* 如何选择
* 目前哪种写法都可以,/*以后学习到组件时,data必须使用函数式,否则会报错*/
* 一个重要原则
* /由Vue管理的函数,一定不要写箭头函数,一旦写了箭头函数,this就不再时Vue实例了
MVVM模型
* M: 模型(model): data中的数据
* V: 视图(View): 模型代码
* VM: 视图模型(ViewModel): Vue实例
发现
* /data中所有的属性,最后都出现在了vm身上(数据代理)
* /vm身上所有的属性及Vue原型上所有属性,在Vue模板中都可以直接使用
Object.defineProperty
回顾方法
数据代理
* 含义: 通过一个对象代理对另一个对象中属性的 *** 作(读/写)
* Vue中的数据代理
* 通过vm(_data)对象代理data对象中属性的 *** 作(读/写)
* /vm._data是数据劫持不是数据代理
* Vue中数据代理的好处
* 更加方便的 *** 作data中的数据
* #基本原理
* 通过Object.defineProperty()把data对象中所有属性添加到vm上
* 为每一个添加到vm上的属性,都指定一个getter/setter
* 在getter/setter内部去 *** 作(读/写)data中对应的属性
事件处理
事件的基本使用
* 使用v-on:xxx 或 @xxx 绑定事件,其中xxx是事件名
* 事件的回调需要配置在methods对象中,最终会在vm上
* /methods中配置的函数,不能再用箭头函数!否则this就不是vm了
* /被vue管理的函数不要使用箭头函数
*/ methods中配置的函数, 都是被Vue所管理的函数,this的指向是vm或组件实例对象
* @click="demo"和@click="demo($event)"效果一致,//但后者可以传参
事件修饰符
* prevent: 阻止默认事件(常用)
* stop: 阻止事件冒泡(常用)
* once: 事件只触发一次(常用)
//扩展知识
* capture: 使用事件的捕获模式
* self: 只有event.target是当前 *** 作的元素时才触发事件
* passive: 事件的默认行为立即执行,无需等待事件回调执行完毕
键盘事件
* Vue中常用的按键别名:
* 回车 => enter / 删除 => delete (捕获"删除"和"退格"键)
* 退出 => esc
* 自己常用的快捷方式
* 换行 => tab (特殊,必须配合keydown去使用)
* Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名)
* 系统修饰键(用法特殊): ctrl alt shift meta
* 配合keyup使用: 按下修饰键的同时,再按下其他键,随后释放其他键,事件才会被触发
* 配合keydown使用: 正常触发事件
* 也可以使用keyCode去指定具体的按键
* #Vue.config.keyCodes.自定义键名 = 键码,可以去定制按键别名
计算属性(computed)
* 定义
* /*要用的属性不存在,要通过已有的属性计算得来*/
* #原理
* 底层借助了Object.defineproperty方法提供的getter和setter
* #get函数什么时候执行?
* 初次读取时会执行一次
* 当依赖的数据发生改变时会被再次调用
* 优势
* /*与methods实现相比,内部有缓存机制(复用),效率更高,调试更方便*/
* 计算属性会进行缓存,如果多次使用时,计算属性只会调用一次
* #备注
* 计算属性最终会出现在vm上,直接读取使用即可
* 如果计算属性要被修改,那必须写set函数去响应修改,
且set中要引起计算时依赖的数据发生改变
* #计算属性简写
* /只考虑读取不考虑修改的时候,只用简写的形式
监视属性(watch)
* 监视属性watch
* 当被监视的属性变化时,回调函数自动调用,进行相关 *** 作
* #监视的属性必须存在,才能进行监视!!
* 监视的两种写法
* new Vue时传入watch配置
* #通过vm.$watch('',{})监视
* immediate //初始化时让handler调用一下
* deep //属性值是布尔值,表示开启深度监视
* #深度监视
* //Vue中的watch默认不监测对象内部值的改变(一层)
* /配置deep: true可以监测对象内部值改变(多层),监视多级结构中某个属性的变化
* //注意
* Vue自身可以监测对象内部值的改变,但Vue提供的watch默认不可以
* 使用watch时根据数据的具体结构,决定是否采用深度监测
computed和watch之间的区别
* //computed能完成的功能,watch都可以完成,watch能完成的功能,computed不一定能完成
* 例如: watch可以进行异步 *** 作
* /两个重要的原则
* 所被Vue管理的函数,最好写成普通函数,这样this的指向才是vm
* 所有不被Vue所管理的函数(定时器的回调函数,Ajax的回调函数等),
最好写成箭头函数,这样this的指向才是vm
绑定class样式(bind)
* 字符串写法
* 适用于:
样式的类名不确定,/*需要动态指定*/
* 数组写法
* 适用于:
要绑定的样式个数不确定,名字也不确定
* 对象写法
* 适用于:
要绑定的样式个数确定,名字确定,但动态决定用不用
绑定style样式(bind)
* 对象写法
* :style = "{key(属性名):value(属性值)}" //对于数值的属性值需要加上单引号
* :,其中xxx是动态值
* 数组写法
* :style = "[baseStyle,baseStyle1]"
* :,其中a,b是样式对象 //key值是存在的属性名
条件渲染(指令)
* v-show
* 写法: v-show="表达式"
* /适用于: 切换频率较高的场景
* 特点: 不展示的DOM元素未被移除,仅仅是使用样式隐藏掉
* 三者之间连用不可间断
* v-if //(可以和template(模板)一起使用)
* 写法
* v-if="表达式"
* v-else-if="表达式"
* v-else
* /适用于: 切换频率较低的场景
* 特点: 不展示的DOM元素直接被移除
* #注意: v-if可以和v-else-if,v-else一起使用,但要求结构不能被"打断"
* 原理
* 后面的条件为false时,对应的元素以及其子元素不会渲染
* 就是根本没有不会有对应的标签出现在DOM中
* v-else-if
* v-else
* 区别
* 使用v-if时,元素可能无法获取到,而使用v-show一定可以获取到
* v-if的条件为false时,包含v-if指令的元素,根本不会存在dom中
* v-show条件为false时,v-show只是给我们的元素添加一个行内样式: display: none
列表渲染
* v-for指令
* 用于展示列表数据
* 语法: v-for="(item, index) in/of xxx" :key="yyy"
* /可遍历: 数组,对象,字符串(用的很少),指定次数(用的很少)
列表过滤
* 通过计算属性
* 通过监视属性 (immedicate: true)
数组中响应式的方法
* push() //在数组最后面添加元素,可以添加多个参数
* pop() //删除数组中最后一个元素
* shift() //删除数组中第一个元素
* unshift() //在数组最前面添加元素,可以添加多个参数
* splice()
* 作用: 删除元素/插入元素/替换元素
* sort() //排序
* reverse() //翻转
# 注意vue中通过索引值无法修改数组中的元素
# Vue.set (要修改的对象,索引值,修改后的值) //这个方法也可以使用
key的作用和原理
* 虚拟DOM中key的作用:
key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据[新数据]生成[新的虚拟DOM],随后Vue进行[新虚拟DOM]与[旧虚拟DOM]的差异比较,比较规则如下:
* 对比规则:
* 旧虚拟DOM中找到了与新虚拟DOM相同的key:
* 若虚拟DOM中内容没变, 直接使用之前的真实DOM!
* 若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM。
* 旧虚拟DOM中未找到与新虚拟DOM相同的key
* 创建新的真实DOM,随后渲染到到页面。
* 用index作为key可能会引发的问题:
* 若对数据进行:逆序添加、逆序删除等破坏顺序 *** 作:
* 会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。
* 如果结构中还包含输入类的DOM:
* 会产生错误DOM更新 ==> 界面有问题
* 开发中如何选择key?
* 最好使用每条数据的唯一标识作为key,比如id、手机号、身份z号、学号等 唯一值。
* 如果不存在对数据的逆序添加、逆序删除等破坏顺序 *** 作,仅用于渲染列表用 于展示,使用index作为key是没有问题的
Vue监视数据的原理 (响应式)
* vue会监视data中所有层次的数据
* #监测对象中的数据 ( Vue.$set )
* 通过setter实现监视,且要在new Vue时就传入要监测的数据
* 对象中后追加的属性,Vue默认不做响应式处理
* 如需给后添加的属性做响应式,请使用如下API:
* Vue.set(target,propertyName/index, value)
* Vue.$set(target, propertyName/index, value)
* #监测数组中的数据
* 通过/*包裹数组*/更新元素的方法实现,本质就是
* 调用原生对应的方法对数组进行更新
* 重新解析模块,进而更新页面
* #在Vue修改数组中的某个元素一定要用如下方法
* 使用这些API: push(),pop(),shift(),unshift(),splice(),sort(),reverse()
* Vue.set() 或 vm.$set()
* /特别注意: Vue.set()和vm.$set()
# 不能给vm或vm的根数据对象添加属性!!!
# Avoid adding reactive properties to a Vue instance or its root $data at runtime (不能给data追加属性,可以给data里面的对象追加属性)
收集表单数据( v-model )
* 若:,
则v-model收集的是value值,用户输入的就是value值
* 若:,
则v-model收集的就是value值,且要给标签配置value值
* 若:
/ 复选框:单个勾选复选框和多个勾选复选框
# 单选框使用布尔值,多选框使用数组
* 没有配置input的value属性,那么收集的就是checked
//(勾选 or 未勾选,是布尔值)
* 配置input的value属性
* v-model的初始值是非数组,那么收集的就是checked
//(勾选or未勾选,是布尔值)
* v-model的初始值是数组,那么收集的就是value组成的数组
* v-model结合select类型
* 单选: 只能选中一个值
* v-model绑定的是一个值
* 当我们选中option中的一个时,会将它对应的value赋值到mySelect中
* 多选: 可以选中多个值
* v-model绑定的是一个数组
* 当选中多个值时,就会将选中的option对应的value添加到数组mySelect中
* 备注:
* /v-model的三个修饰符
* lazy: 失去焦点再收集数据
* number: 输入字符串转为有效的数字
* trim: 输入首尾空格过滤
过滤器
* 定义
# 对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)
* 语法
* 注册过滤器: Vue.filter(name,callback) 或 new Vue{filters:{}}
* 使用过滤器: {{xxx | 过滤器名}} 或 v-bind:属性 = "xxx | 过滤器名"
* 备注:
* 过滤器可以接收额外参数,多个过滤器也可以串联
* /并没有改变原本的数据,是产生新的对应的数据
高阶函数( filter / map / reduce )
* filter()
* 它其中的参数: 回调函数有一个要求: 必须返回一个布尔值
* true: 当返回true时,函数内部会自动将这次回调的n加入 //到新的数组中
* false: 当返回false时,函数内部都会过滤这次的n
* map() //映射
* 对数组中所有的元素进行变化时
* reduce()
* 作用
* 对数组中所有的内容进行汇总
内置指令
v-bind(涉及到上面的绑定class样式和style样式)
* 作用: 单向绑定解析表达
* 简写为: xxx
* #作用: 动态的绑定标签里面的属性
* 对象语法
* v-bind:class = "{类名: Boolean,类名2: Boolean }"
* 数组语法
* v-bind:class = "[active,line]"
v-on(事件监听)
* #作用: 绑定事件监听
* 简写为 @
* 参数: event
* //在调用方式,如何手动的获取到浏览器参数的event对象: $event
* 注意
* #如果方法不需要额外参数,那么方法后的()可以不添加
* 如果方法本身中有一个参数,那么会默认将原生事件event参数传递进去
* #如果需要同时传入某个参数,同时需要event时,可以通过$event传入事件
* v-on修饰符
* .stop //调用event.stopPropagation()
* .prevent //调用event.preventDefault()
* .{keyCode | keyAlias}
//只当事件是从特定键触发时才触发回调
* .native //监听组件根元素的原生事件
* .once //只触发一次回调
v-model
* 作用: 双向数据绑定
* 原理
* 它的背后本质上是包含两个 *** 作
* v-bind绑定一个value属性
* v-on指令给当前元素绑定input事件
* v-for: #遍历数组,对象,字符串
* v-if: 条件渲染(动态控制节点是否存在)
* v-else: 条件渲染(动态控制节点是否存在)
* v-show: 条件渲染(动态控制节点是否展示)
* v-text
* 作用: 向其所在的节点中渲染文本内容
* #与插值语法的区别: v-text会替换节点中的内容,{{xxx}}(插值语法)则不会
* v-html
* 后面往往跟上一个string类型
* 会将string的html解析出来并进行渲染
* 作用
* 向指定节点中渲染包含html结构的内容
* #与插值语法的区别
* v-html会替换掉节点中的所有的内容,{{xx}}则不会
* v-html可以识别html结构
* /严重注意: v-html存在安全问题
* 在网站上动态渲染任意HTML是非常危险的,容易导致XSS(冒充用户之手)攻击
* 一定要在可信的内容上使用v-html,永不要用在用户提交的内容上!
* v-cloak(没有值)
* #本质是一个特殊属性,Vue实例创建完毕并接管容器后,会删掉v-cloak属性
* 使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题
* 在Vue解析之前,div中有一个属性v-cloak
* 在Vue解析之后,div中没有一个属性v-cloak
* v-once
* 表示元素和组件只渲染一次,不会随着数据的改变而改变
* 后面不需要跟任何表达式
* v-once所在节点在初次动态渲染后,就视为静态内容了
* 以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能
* v-pre
* 跳过其所在节点的编译过程
* 可利用它跳过:没有使用指令语法,没有使用插值语法的节点,会加快编译
自定义指令
* 定义语法
* 局部指令
* 第一种
new Vue({
directives:(指令名:配置对象)
})
* 第二种
new Vue({
directives{指令名:回调函数}
})
* 全局指令
* Vue.directive(指令名,配置对象)
* Vue.directive(指令名,回调函数)
* /配置对象中常用的3个回调
* bind: 指令与元素成功绑定时调用
* inserted: 指令所在元素被插入页面时调用
* update: 指令所在模板结构被重新解析时调用
* /备注
* 指令定义时不加v-,但使用时要加v-
* 指令名如果是多个单词,要使用kebab-case命名方式,不要用camelCase命名
生命周期
* 又名: 生命周期回调函数,生命周期函数,生命周期钩子
* 是什么: Vue在关键时刻帮助我们调用的一些特殊名称的函数
* 生命周期函数的名字不可以更改,//但函数的具体内容是程序员根据需求编写的
* /生命周期函数中的this指向是 vm 或 组件实例对象
生命周期总结
* 常用的生命周期钩子
* mounted:
* 发送Ajax请求,启动定时器,绑定自定义事件,订阅消息等(初始化 *** 作)
* 初始的真实DOM放入页面后
* beforceDestory: 清除定时器,解绑自定义事件,取消订阅消息等(收尾工作)
* 关于销毁Vue实例
* 销毁后借助Vue开发者看不到任何信息
* 销毁后自定义事件会失效,但原生DOM事件依然有效
* 一般不会在beforceDestory *** 作数据,因为即便 *** 作数据,也不会再次触发更新流程了
组件
含义
用来实现局部(特定)功能效果的代码集合(html/css/js/image...)
为什么
一个界面的功能很复杂
作用
复用编码,简化项目编码,提高运行效率
Vue中使用组件的三大步骤
定义组件 (创建组件构造器--调用Vue.extend()方法)
注册组件--调用Vue.component(全局组件,意味着可以在多个Vue的实例下面使用)
调用Vue.component()需要传递两个参数:
注册组件的标签名
组件构造器
使用组件(写组件标签)--在Vue实例的作用范围内
如何定义一个组件
使用Vue.extend(options)创建,其中options和 new Vue(options)时传入的那个options几乎一样,但也有点区别
区别如下
/el不要写(最终所有的组件都要经过一个vm的管理,由vm中的el决定服务那个容器)
/data必须写成函数(避免组件被复用时,数据存在引用关系)
备注: 使用template可以配置组件结构
如何注册组件
局部注册: 靠new Vue的时候传入compenents选项
全局注册: 靠Vue.compenent('组件')
编写组件标签
* 组件化是Vue.js中的重要思想
* 它提供了一种抽象,让我们可以开发出一个个独立复用的小组件来构造我们的应用
* 任何的应用都会被抽象成一颗组件树
* 组件化思想的应用
* 有了组件化的思想,我们在之后的开发中就要充分利用它
* 尽可能的将页面拆分成为一个个小的、可复用的组件
* 这样让我们的代码更加方便组件组织和管理,并且拓展性也更强
组件注意点
* 关于组件名
* 一个单词组成
* 第一种写法(首字母小写): school
* 第二种写法(首字母大写): School
* 多个单词组成
* 第一种写法(kebab-case命名): my-school
* 第二种写法(CamelCase命名): MySchool //(需要Vue脚手架支持)
* 备注
(1) //组件名尽可能回避HTML中已有的元素名称,例如: h2、H2都不行
(2) //可以使用name配置项指定组件在开发者工具中呈现的名字
* 关于组件标签
第一种写法:
第二种写法:
#备注: 不用使用脚手架时, 会导致后续组件不能渲染
* 一个简写方式 const school = Vue.extend(options)
* 可简写为: const school = options
模板的分离写法
* Vue提供了两种方案来定义HTML模板内容
* 使用