vue简介
1.vue是什么? vue是一套用于构建用户界面的渐进式javascript框架
渐进式:vue可以自底向上逐层的引用。 简单应用:只需一个轻量小巧的核心库。 复杂应用:可以引入各式各样的vue插件
2.vue的特点
-
采用组件化模式,提高代码复用率,且让代码更好维护。 -
声明式编码,让编码人员无需直接操作DOM,提高开发效率。 -
使用虚拟DOM(内存里的数据)+优秀的Diff算法,尽量复用DOM节点。
搭建开发环境
root可以更换为js获取dom的写法
1.cdn 2.npm
vue实例和容器只能一一对应,不可一对多也不可多对一
注意区分:js表达式和js代码(语句)
- 表达式:一个表达式会产生一个值,可以放在任何一个需要值的地方:
a a+b demo(1) x==y?‘a’:‘b’ - js代码(语句)
if(){} for(){}
模板语法
- 差值语法
*功能:*用于解析标签体内容 写法:{{xxx}},xxx是js表达式,且可以直接读取到data中的所有属性。 - 指令语法:
功能: 用于解析标签(包括:标签属性、标签体内容、绑定事件…) 距离: (v-bind是单向数据绑定{能根据数据展示,但不能跟页面改变而改变数据})v-bind:href=“xxx”或者简写为:href=“xxx”,xxx同样要写js表达式,且可以直接读取到data中的所有属性。 备注: vue中有很多指令,且形式都是v-??,此处只是拿v-bind举个栗子
数据绑定
单向数据绑定:v-bind{数据只能从data流向页面} 双向数据绑定:v-model{数据不仅能从data流向页面,还可以从页面流向data}
v-model只能绑定表单元素(input…)表单元素都有value v-model:value可以简写成v-model,因为v-model默认收集的是value值
el与data的两种写法
在对象里面写函数可以省略:function,这里需要特别注意不可以写箭头函数,一旦写了箭头函数,this就不在是vue实例了
理解mvvm
数据代理
数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)
let number = 18
let person = {
name:'zhangsan',
sex:'boy',
}
Object.defineProperty(person,'age',{
get:function(){
console.log('有人读取age属性了')
return number
},
set:function(value){
console.log('有人修改时')
number = value
}
})
- vue中的数据代理:
通过vm对象来代理datra对象中属性的操作(读/写) - vue中数据代理的好处:
更加方便的操作data中的数据 - 基本原理:
通过Object.defineProperty()把data对象中所有属性添加到vm上 为每一个添加到vm上的属性,都指定一个getter/setter 在getter/setter内部去操作(读/写)data中对应的属性
事件
事件传参
<div @click="info">事件1</div>
<div @click="info2($event,66)">事件2</div>
//传参就加口号,不传参就不加
methods:{
info(event){
console.log(event)
},
info(event,number){
console.log(event,number)
}
}
- 使用v-on:xxx或@xxx绑定事件,其中xxx是事件名
- 事件的回调需要配置在methods对象中,最终会在vm上
- methods中配置的函数,不要用箭头函数!否则this就不是vm了
- methods中配置的函数,都是被vue所管理的函数,this的指向是vm或组件实例对象
- @click=“demo”和@click=“demo($event)”效果一致,但后者可以传参
事件修饰符
- .prevent:阻止默认事件
- .stop:阻止事件冒泡
- .once:事件只触发一次
- .capture:使用事件捕获模式
- .self:只有event.target是当前操作的元素是才触发事件
- .passive:事件的默认行为立即执行,无需等待事件回调执行完毕
- number 配合input表单type属性为number一起使用,将其数据变成数字类型
- lazy:配合textarea一起使用当这个失去焦点的时候将其数据响应(不加会边输入边存储)
- trim 去掉前后空格
键盘事件
- enter 回车
- delete 删除和退格
- esc 退出
- space 空格
- tab换行(特殊:必须要配合keydown去使用)
- up上
- down
- left
- right
<button @keyup.enter="getInfo">点击获取信息</button>
系统修饰键: ctrl、alt、shift、meta(win键) 配合keyup使用:按下修饰键的同时,在按下其他键,事件才会被处罚 配合keydown使用,正常触发 修饰符可以连续写
计算属性
计算属性与methods的优势:计算属性内部有缓存机制(复用),效率更高,调试方便。
<div>{{fullName}}</div>
完整写法
computed:{
fullName:{
get(){
return this.firstName+ '-' + this.lastName
},
set(value){
const arr = value.split('-')
this.firstName = arr[0]
this.lastName = arr[1]
}
}
}
简写写法:只读不改才可以简写
computed:{
fullName(){
return this.firstName+ '-' + this.lastName
}
}
监视属性
- 当被监视的属性变化时,回调函数自动调用,进行相关操作
- 监视的属性必须存在,才能进行监视
- 监视的两种写法
- new Vue传入watch配置
- 通过vm.$watch监视
watch:{
isHot:{
immediate:true,
handler(newValue,oldValue){
console.log(newValue,oldValue)
}
}
}
深度监视
data:{
numbers:{
a:1,
b:2
}
},
watch:{
'numbers.a':{
handler(){
console.log('a被改变了')
}
},
numbers:{
deep:true,
handler(){
console.log('numbers被改变了')
}
}
}
简写写法:前提不需要deep和innediate的时候使用
watch:{
isHot(newValue,oldValue){
console.log('isHot被改变了')
}
}
const vm = new Vue({})
vm.$watch('isHot',function(newValue,oldValue){console.log('isHot被改变了')})
深度监视:
- vue中的watch默认不监视对象内部值的改变(一层)
- 配置deep:true可以检测对象内部值改变(多层)
备注: - vue自身可以检测对象内部值的改变。但vue提供的watch默认不可以
- 使用watch时根据数据的具体结构,决定是否才用深度监视
watch和computed的区别:
- computed能完成的功能,watch都可以完成
- watch能完成的功能,computed不一定能完成。eg:watch可以进行异步操作
两个重要的小原则 - 所被vue管理的函数,最好写成普通函数,这样this的指向才是vm或组件实例对象。
- 所有不被vue所管理的函数(定时器的回调函数、ajax的回调函数等),最好写成箭头函数,这样this的指向才是vm或组件实例对象。
列表过滤 所以两者选择计算属性更好 +排序
当每次用什么方法你需要想到:这个方法能收到什么+需不需要写返回值+改变不改变原数组
class绑定样式
- 绑定class样式-----字符串写法,适用于:样式的类名不确定,需要动态绑定
<div class="basic" :class="mood" @click="changeMood">{{name}}</div>
data:{
mood:'normal'
},
methods:{
changeMood(){
this.mood='haapy'
}
}
- 绑定class样式-----数组写法:适用于:要绑定的样式个数不确定、名字也不确定
<div class="basic" :class="classArr">{{name}}</div>
data:{
classArr:['normal','normal1']
},
- 绑定class样式----对象写法,适用于:要绑定的样式个数确定、名字也确定,但要动态决定用不用
<div class="basic" :class="classObj">{{name}}</div>
data:{
classObj:{
normal:true,
normal2:false,
}
},
绑定style样式
- 对象
- 数组
<div :style="styleObj">{{name}}</div>
<div :style="styleArr">{{name}}</div>
data:{
styleObj:{
fontSize:'40px'
},
styleArr:[
{backgroundColor:'red'}
]
},
条件渲染
- v-if
写法:
v-if=“表达式”
v-else-if=“表达式”
v-else=“表达式”
适用于:切换频率较低的场景
特点:不展示的DOM元素直接被移除
注意:v-if可以喝v-else-if、v-else一起使用,但要求结构不能被打断
- v-show
写法:
v-show=“表达式”
适用于:切换频率较高的场景
特点:不展示的DOM元素未被移除,仅仅是使用样式隐藏掉
备注:使用v-if的时,元素可能无法获取到,而使用v-show一定可以获取到
列表渲染
v-for指令
- 用于展示列表数据
- 语法:v-for=“(item,index) in xxx” :key=“yyy”
- 可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)
key的作用
- 虚拟DOM中key的作用:
key是虚拟DOM对象的标识,当状态中的数据发生变化时,vue会根据【新数据】生成【新的虚拟DOM】,随后vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较 - 对比规则:
- 旧虚拟DOM中找到了与新虚拟DOM相同的key:
若虚拟DOM中内容没变,直接使用之前的真实DOM 若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM - 旧虚拟DOM中未找到与新虚拟DOM相同的key
创建新的真实DOM,随后渲染到页面 - 用index作为key可能会引发的问题:
1. 若对数据进行:逆序添加、逆序删除等破坏顺序操作:会产生没有必要的真实DOM更新==》界面效果没问题,但效率低 2. 如果结构中还包含输入类的DOM,会产生错误DOM更新==》界面有问题 - 开发中如何选择key
1. 最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值 2. 如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的
vue监视数据
- vue会监视data中所有层次的数据
- 如何检测对象中的数据?
通过setter实现检测,且要在new vue时就传入要检测的数据
- 对象中后追加的属性,vue默认不做响应式处理
- 如需给后添加的属性做响应式,请使用如下
Vue.set(target,propertyName/index,value)或 this/vm.$set(target,propertyName/index,value) - 如何检测数组中的数据?
通过包裹数组更新元素的方法实现,本质就是做了两件事
- 调用原生对应的方法对数组进行更新
- 重新解析模板,进而更新页面
- 在vue修改数组中的某个元素一定要用如下方法
- 使用这些API:push() pop() shift() unshift() splice() sort() reverse()
- Vue.set()或vm.$set()
特别注意:Vue.set()和vm.$set()不能给vm或vm的根数据对象添加属性
过滤器
日期过滤:bootcdn------mont.js/day.js
定义:对要显示的数据进行特定格式化再显示(适用于一些简单逻辑的处理) 语法:
- 注册过滤器:Vue.filter(name,callback)或new Vue(filters:{})
- 使用过滤器:{{xxx|过滤器名}}或v-bind:属性=‘xxx|过滤器名’
备注: - 过滤器也可以接收额外参数、多个过滤器也可以串联
- 并没有改变原来的数据,是产生新的对应的数据
指令
- v-on/@ 事件
- v-bind 单向绑定
- v-model 双向绑定
- v-for 遍历数组、对象、字符串
- v-if条件渲染
- v-else-if条件渲染
- v-else条件渲染
- v-show条件渲染
- v-text渲染文本内容
v-text与{{}}(差值)语法的区别:v-text会替换节点中的内容,而差值不会
- v-html 渲染包含html结构的内容
与差值语法的区别:
- v-html会替换掉节点中所有的内容,差值不会
- v-html可以识别html结构
注意:html有安全性问题 - 在网络上动态渲染任意html是非常尾项的,容易导致xss攻击。
- 一定要在可信的内容上使用v-html,永不要用在用户提交的内容上
- v-clock
<style>
[v-clock]{
display:none;//解决页面闪动问题
}
</style>
<div v-clock></div>
本质是一个特殊属性,vue实例创建完毕并接管容器后,会删掉v-clock属性 使用css配合v-clock可以解决网速慢时页面展示出{{xxx}}的问题
- v-once:所有节点在初次动态渲染后,就视为静态内容了。以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能
<div v-once>初始化值{{n}}</div>//点击之后还是初始化
<div >当前的值{{n}}</div>//点击之后会根据点击的逻辑变化
<button @click="n++">+1</button>
- v-pre:跳过其所在节点的编译过程。可利用他掉过:没有使用指令语法、没有使用差治愈大的节点,会加快编译
//效果
<div v-once>{{n}}</div>//页面展示:{{n}}
//一般放在不需要解析的dom节点是上-这样就不需要解析了
<div v-once>hahhahah</div>//页面展示:hahhahah
自定义指令
自定义指令何时调用:
- 指令与元素成功绑定时(一上来)
- 指令所在的模板被重新解析时
函数式
<div v-big="n"></div>
//如果自定义指令的名字是多个-用-分割
<div v-big-number="n"></div>
directives:{
big(element,binding){
element.innerText = binding.value
console.log(element,'被绑定的元素',binding,'绑定给的值')
},
'big-number'(element,binding){
element.innerText = binding.value
console.log(element,'被绑定的元素',binding,'绑定给的值')
}
}
对象式
<input type="text" v-fbing=""/>
directives:{
fbing:{
bind(element,binding){
element.innerText = binding.value
},
inserted(element,binding){
element.focus()
},
update(element,binding){
element.innerText = binding.value
}
}
}
Vue.directive('fbing',{
bind(element,binding){
element.innerText = binding.value
},
inserted(element,binding){
element.focus()
},
update(element,binding){
element.innerText = binding.value
}
})
Vue.directive('big',function(element,binding){
element.innerText = binding.value
console.log(element,'被绑定的元素',binding,'绑定给的值')
})
所有指令相关的函数this指向是window—写箭头函数和正常函数都可
生命周期
常用的生命周期钩子:
- mounted:发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】
- beforeDestroy:清除定时器、解绑自定义事件、取消订阅消息【收尾工作】
关于销毁vue实例: - 销毁后借助vue开发者工具看不到任何信息
- 销毁后自定义事件会失效,但原生dom事件依然有效
- 一般不会在beforeDestroy操作数据,因为即便操作数据,也不会再触发更新流程了
组件
**定义:**实现应用中局部功能代码和资源的集合 使用组件的三大步骤:
- 定义组件(创建组件)
- 注册组件
- 使用组件(写组件标签)
如何定义一个组件? 使用vue.extend(options)创建,其中options和new Vue(options)时传入的那个options几乎一样,但也有点区别: 区别如下: - el不要写,为什么?——最终所有的组件都要经过一个vm的管理,由vm中的el的决定服务哪个容器
- data必须写成函数,为什么?——避免组件被复用时,数据存在引用关系
备注:使用templete可以配置组件结构
如何注册组件?
- 局部注册:new Vue({components:{}})
- 全局注册:Vue.component(‘组件名’,组件)
编写组件标签 <组件名></组件名>
注意事项:
- 组件名写法:
一个单词组成:首字母小写+手字母大写 多个单词组成:my-school和MySchool 备注: 1.组件名尽可能会比html中已有的元素名称,例如:h2和H2都不行 2. 可以使用name配置项指定组件在开发者工具中呈现的名字 - 关于组件的标签:
第一种写法: <组件名></组件名> 第二种写法: <组件名/> 备注:不用使用脚手架时,<组件名/>会导致后续组件不能渲染 一个简写方式: const school = vue.extend(options)可简写const school = options
非单文件组件
定义:一个文件中包含有n个组件
单文件组件
定义:一个文件中只包含1个组件
vueComponent构造函数
- school组件本质是一个名为vueComponent构造函数,且不是程序员定义的,是vue.extend生成的
- 我们只需要写或,vue解析时会帮我们创建school组件的实例对象,即vue帮我们执行的:new vueComponent(options)
- 特别注意:每次调用vue.extend,返回的都是一个个全新的vueComponent
- 关于this指向
1. 组件配置中:data函数、methods函数、watch函数、computed中的函数 他们的this均是【vueComponent实例对象】 2. new vue(options)配置中:data函数、methods函数、watch函数、computed中的函数 她们的this均是【vue实例对象】 - vueComponent的实例对象,以后简称vc(也可称之为:组件实例对象)
vue实例对象以后简称vm
|