是前端的一个框架
是一个渐进式框架
基于mvvm的框架
渐进式:不强求一次性使用和接受他的所有功能。如果你想用其中的一个或者多个再引用相对应的功能就好了。
mvvm:
m:数据对象。
v:前端展示页面。
vm:双向绑定数据。vue的实例。数据改变视图,自动刷新。
开发模式:
声明式开发:程序告诉机器我要干什么,怎么我不管。 组件化开发 自定义开发 将标签成为组件 虚拟dom命令式开发:应用程序 业务逻辑 开发将每一步实现步骤都需要代码实现。 vm啥呀?答:初始化 Vue的实例
// body中:
{{msg}}
// script中
vue模板
啥呀? 答:类似ejs 在视图上渲染vm上面的数据 {{ }}
{{msg}}
{{'这是一个字符串'}}
显示:
若是:
{{这是一个字符串}}
会报错!
必须是表达式 变量js定义的变量不可以哦
data:{
msg:'这是一个msg'
}
这里的这个msg会挂载到vm实例上
我们在模板中引用的变量去vm实例上去找
白名单:
‘Infinity,undefined,NaN,isFinite,isNaN,’ +
‘parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,’ +
‘Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,’ +
‘require’
全局使用后最终结果是一个值
抛弃原来 *** 作dom语法 一切以数据驱动 指令干哈用的:将视图上元素不同状态和不同m绑定 打通视图和数据之间的关联
怎么写:扩展了html标签属性的语法
<标签 v-指令名="值">
将元素的文本内容与一个数据进行绑定
msg的值为:“这是一个值”
// msg的值会在div的内容上显示
v-html
渲染富文本
msg的值为:“这是一个值”
// div里面的内容为标题一的 “这是一个值”
v-show
将元素的显示隐藏状态和一个布尔值进行绑定
v-show的值为真,元素显示
v-show的值为假,元素隐藏
v-bind:属性
属性:可以是任何属性,html里面的属性,或者自定义的都可以。万能指令:没有特定的功能,将一个普通属性变成一个动态属性。将属性的值和数据进行绑定。
简写:v-bind:属性名
==》 :属性名
// 将src属性值绑定到imgArr的值,简而言之imgArr值是什么src的值就是什么
v-model
将表单控件的值与vm上数据进行双向绑定
v-on:事件将原生事件合成为vue事件(将事件函数变成vm上的方法)直接绑定事件,在事件中修改vm上的数据
简写:@事件名
事件绑定vm上的方法有两种方式:
1 绑定时加括号
methods:{
fn(){
// 这是一个挂载在vm上面的方法
}
}
用于:事件触发时传递参数
在实例上找,没有找到就报错
2 绑定时不加括号
methods:{
fn(参数一,参数二,......){
// 这是一个挂载在vm上面的方法
}
}
用于:触发事件
在实例上找,没有找到就报错
绑定事件时,事件不加括号,那么第一个参数就是事件对象
methods:{
fn(e){
// 这里的e就是事件对象
}
}
绑定事件时,事件加括号
定义一个全局变量$event传入调用即可
methods: {
fn(n, e){
// e就是事件对象
}
}
事件修饰符
用于:修饰事件
.stop:取消事件冒泡
如果这种嵌套形式(祖宗套爷爷,爷爷套父亲,父亲套儿子…),给每个div绑定一个事件,点击儿子的时候也会触发父亲、爷爷、祖宗的事件,执行的顺序为 7 6 5 4 3 2 1(从里面往外面触发)。
取消冒泡事件:
在某个div事件之后添加取消冒泡事件修饰符 @click.stop
那么点击div从里向外冒泡触发时遇到这个有修饰符的div时就停止
不再往上冒泡触发事件
案例:给上面div嵌套案例添加
输出:7 6 5 4 3
阻止一些元素自带的默认事件。比如点击会跳转链接。
点击表单的button会自动提交。
从外向里捕获。
简单来说就是,拿上面的案例(七个嵌套div)来说,如果在div4添加捕获事件修饰符,输出变成4 7 6 5 3 2 1。先捕获,首先执行div4上面的事件,然后从最里层往外冒泡,当冒泡到对应的div4,它已经触发过了,所以不触发,继续向上触发上面的事件。
添加一个小案例:
// 给div2添加捕获事件修饰符
// 给div4添加捕获事件修饰符
按照上面的解析,首先从外往内捕获,div2事件触发 div4事件触发 然后 从div7到div1开始冒泡触发事件。
已经触发过的不再触发。所以最后得到的输出结果是 2 4 7 6 5 3 1。
.self:事件只能由自己触发,后代元素无法触发
只能由自己触发,后代子元素无法触发。
什么场景使用:d窗(点击按钮显示d窗,点击d窗以外的部分d窗隐藏)。
// 点击父元素隐藏
// 父元素点击,子元素不受影响
这是内容1
const vm = new Vue({
el: '#app',
data: {
isShow: false
},
methods: {
showModal(){
this.isShow = true;
},
hideModal(){
this.isShow = false;
}
}
})
.once:事件只绑定一次
绑定的事件只能执行一次。
事件修饰符修饰v-model 用于绑定输入框
.trim{{msg}}
去除输入框中 开头和结尾的空格
.lazy{{msg}}
.lazy的使用效果
双向绑定由input触发改为change触发
.number过滤为数字,过滤规则同parseFloat
如果首字母就是非数字 直接停止工作 变成普通v-model
v-if和v-show区别?
相同点:
都是绑定布尔值,值true元素显示。false元素隐藏
不同点:
当元素隐藏时,v-show控制 display:none v-if 直接在dom树上移除这个元素
使用场景?
v-show有更高切换性能,适用于 频繁切换状态场景
当初始不渲染时,v-if性能更高,适用于 初始不渲染,且 切换状态不频繁。因为一开始的dom会变得很少,加载快
v-else绑定元素,一定是 v-if绑定元素的下一个兄弟元素
多分支v-if v-else-if必须是相邻的兄弟
列表渲染 循环 v-for 普通循环
{{ item }}
循环时声明变量 包括下面下标,作用域 只能在 v-for绑定标签内部使用
循环得到下标
{{ item }}
循环对象
{{value}}
->
{{key}}
->
{{index}}
复杂循环
使用场景:网站首页楼层
循环嵌套循环,需要注意的时,如果需要在内层 使用外层循环声明的变量或者下标,内外层命名一定不能冲突,否则 一定优先拿内层
{{floor.title}}
商品名字:{{item.name}}
商品价格:{{item.price}}
{{ i+1 }} 楼
vue深入响应式原理 MVVM原理
mvvm底层api : Object.defineProperty();
这个api在IE8及一下不支持。
当我们const vm=new Vue({})(new一个vm实例) 的时候,传入config对象,data属性也是对象,此时vue会立即遍历这个data对象,并利用Object.defineProperty();
将data中所有属性转换成getter
setter
,同时每一个实例,定义一个观察者watcher
(监听data里面的数据),当setter
触发,setter
会立即通知观察者,观察者在他的回调里会触发render
函数,功能是生成新的虚拟DOM,和上一次保存在内存中的虚拟DOM进行比较(利用diff算法
),得到代价最小的方案,来更新真实DOM。
产生的问题:如果vue数据修改直接更新DOM,会导致性能消耗太大,修改多少次就会导致DOM立即重建多少次。
什么是虚拟DOM:用js对象的结构来描述真实DOM结构
这是p
这是span
这是文本
转换成虚拟DOM:
{
tag: 'div',
attrs: {
id: 'box',
className: 'container'
},
children: [
{
tag: 'p',
attrs: {
className: 'op'
},
children: ['这是p']
},
{
tag: 'span',
attrs: {},
children: ['这是span']
},
'这是文本'
]
}
虚拟DOM是将真实的DOM节点用JavaScript模拟出来,将DOM变化的对比,放到 Js 层来做。
虚拟DOM在vue中做了什么:
vue中数据修改,视图刷新是异步的,
在vue中每一次修改都会生成新的虚拟DOM,和上一次保存在内存中未改变的虚拟DOM进行比较,比较过程中使用到diff算法
diff算法在虚拟DOM比较中做了什么优化:
实现同层比较
同层如果有相同key属性 同层同key进行比较
Vue可以通过key这种方式来观察数组或者对象中的数据哪些发生变化。v-for默认通过index索引值来追踪变化。但是尽可能使用数据唯一的ID来做每个元素的key。这样就更能准确的追踪。往下看,下面我们还介绍了为什么用唯一的ID做为key而不是用下标index。
key:独一无二
使用下标做key:
b // key==0
c // key==1
d // key==2
e // key==3
a // key==0
b // key==1
c // key==2
d // key==3
e // key==4
产生对比错位,从上图可以看到所有的li标签都发生了变化 ,diff认为每一个li都发生了改变,于是页面重新渲染了所有的列表项。
使用item做下标:
这样每个li都有一个单独的key,进入diff算法时进行新旧对比,只会删除第一项,不会渲染其他li,大大提高性能。
数组[下标]="值"
这样写的话,值变化了,但是视图上不会变化
原因:ObjectdefineProperty setter捕获不到这种 *** 作
解决方法:
this.$set(对象,属性,值)
this.$set(数组,下标,值)
$set
修改数组时 自己主动去触发render让视图刷新
直接修改数组的长度
原因:ObjectdefineProperty setter捕获不到这种 *** 作
解决方法:
使用splice取代修改length
属性在修改时,视图不刷新
原因:初始化遍历给data添加getter setter时,data中没有,属性就没有setter getter
解决方案:在data中定义合理的初始值
问题:
当我们在打开vue开发网页时,由于网页加载 顺序从上往下的,在实例未初始化完成时,html解析 vue模板 变成了普通字符串 来解析,等待vue实例初始化完成,模板挂载,并渲染,中间时间差,产生闪烁
解决:
vue提供了一个指令v-cloak
v-cloak的功能:vue实例初始化完成会自动去除视图所有v-cloak指令。
具体如何做:
// CSS属性选择器
// 这是什么原理不言而喻了,就是使用选择器让当前元素消失隐藏,当vue实例初始化时,v-clock去除,这样让元素显示,同时data也被遍历,数据显示出来。这样就看不到{{msg}}的模板了。
[v-cloak]:{
display:none
}
{{msg}}
数据修改 视图 异步刷新
vue 数据修改后,视图更新是异步 *** 作,当数据修改,立即获取最新dom,是拿不到的,拿到是上一次未更新前的dom,
vue设计了观察者,监听视图异步更新,当每一次数据更新完成后触发回调,在回调中可以拿到最新的dom。
this.$nextTick(()=>{
// 在这里可以拿到最新的dom
})
侦听器 watch
用于侦听实例上属性的变化 当数据改变时 侦听器会触发
侦听基础数据类型数据config中新增watch属性 watch定义侦听同名方法即可
watch:{
msg(newVal,oldVal){
}
}
针对对象 数组 改变数组长度改变
使用深度监听
watch:{
obj:{
handler(newVal){
},deep:true // 深度监听
}
}
计算属性
依赖已有一个或多个值经过计算得到一个新的值
使用场景:
某一个后端返回的数据,前端不能直接使用,需要转换一下才能用
计算属性基础
新增config对象中computed属性
在属性定义方法,在方法中基于依赖进行计算,返回计算结果
computed: {
reverseMsg(){
return this.msg.split('').reverse().join('')
},
doneTodoLen(){
return this.todos.filter(todo=>todo.done).length;
}
}
注意:计算属性最终编译成实例的属性
计算属性计算完成,基于依赖进行缓存,多次使用计算属性不会重新计算,拿缓存的值,只有依赖发生改变,重新计算。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)