文章目录
- 一、vue条件渲染 v-if
- 二、vue循环渲染 v-for
- 三、vue的事件 v-on
- 四、vue的双向绑定 v-model
- 五、VUE2的缺点
- 5.1 vue底层原理
- 解决方案
在上节 【VUE2-01】vue2的起步,中写hello world!例子的时候使用了一个指令 v-bind绑定元素属性
一、vue条件渲染 v-if
v-if控制切换一个元素是否显示
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>条件渲染</title>
</head><body><div id="app-3"><p v-if="seen">现在你看到我了</p></div><script src="vue.js"></script><script>var app3 = new Vue({el: '#app-3',data: {seen: true}})</script></body></html>
注意: 可以在控制台中输入app3.seen = false可以发现文字消失了,也可以在dom节点中使用,隐藏dom节点
也可以用 v-else 添加一个“else 块”:
<p v-if="seen">现在你看到我了</p><p v-else>Oh no !<p>
注意: v-else 元素必须紧跟在带 v-if 或者 v-else-if 的元素的后面,否则它将不会被识别。
v-else-if,顾名思义,充当 v-if 的“else-if 块”,可以连续使用:
<div v-if="type === 'A'">A
</div>
<div v-else-if="type === 'B'">B
</div>
<div v-else-if="type === 'C'">C
</div>
<div v-else>Not A/B/C
</div>
注意: 类似于 v-else,v-else-if 也必须紧跟在带 v-if 或者 v-else-if 的元素之后。
v-show根据条件展示元素
v-show与v-if的不同:
v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
二、vue循环渲染 v-for
v-for可以绑定数组的数据来渲染一个项目列表
v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名。
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>循环渲染</title>
</head><body><div id="app-4"><ol><li v-for="todo in todos">{{ todo.text }}</li></ol></div><script src="vue.js"></script><script>var app4 = new Vue({el: '#app-4',data: {todos: [{ text: '学习 JavaScript' },{ text: '学习 Vue' },{ text: '整个牛项目' }]}})</script></body></html>
注意: 尽可能的v-for和v-if不能同时使用,v-for是渲染数组或者对象的,v-for的优先级高,这会导致每循环一次就会去v-if一次,又因为v-if是通过创建和销毁来完成显示隐藏的,所以就会不停的去创建和销毁,造成页面的卡顿
三、vue的事件 v-on
v-on指令添加一个事件监听器
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>事件</title>
</head><body><div id="app-5"><!-- 插值语法:里面的内容是要显示的内容 --><p>{{ message }}</p><!-- 在button中添加一个名为reverseMessage的点击事件 --><button v-on:click="reverseMessage">反转消息</button></div><script src="vue.js"></script><script>var app5 = new Vue({//el指的是绑定的vue的某一块区域,此例中是绑定的id名,要唯一el: '#app-5',data: {message: 'Hello Vue.js!'},// 新的对象methods对象中的内容是各种方法methods: {reverseMessage: function () {this.message = this.message.split('').reverse().join('')}}})</script></body></html>
注意: vue的优势在此处可以显示出来,reverseMessage 方法中,我们更新了应用的状态,但没有触碰 DOM——所有的 DOM 操作都由 Vue 来处理,你编写的代码只需要关注逻辑层面即可。
四、vue的双向绑定 v-model
v-model实现表单输入和应用状态之间的双向绑定
v-model 指令在表单 、 及 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。
v-model 在内部为不同的输入元素使用不同的 property 并抛出不同的事件:
text 和 textarea 元素使用 value property 和 input 事件;
checkbox 和 radio 使用 checked property 和 change 事件;
select 字段将 value 作为 prop 并将 change 作为事件。
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>双向绑定</title>
</head><body><div id="app-6"><p>{{ message }}</p><input v-model="message"></div><script src="vue.js"></script><script>var app6 = new Vue({el: '#app-6',data: {message: 'Hello Vue!'}})</script></body></html>
修饰符:
.lazy 类似于change事件,当焦点发生改变的时候才会触发
.number 将输入的字符转为有效数字,不加则是字符串类型
.trim 过滤首尾空格
注意: 此处的写入输入框的内容,并不能实际改变message中的内容,也就是不能触碰到vue的数据,此处也是vue2的一大缺点,面试题中会经常问道,原本笔者想重新开一节讲述这个缺点,但是在此遇上了,便简述一下,后续可能会开启一个更详细讲述该经过的章节
五、VUE2的缺点
5.1 vue底层原理
当把一个普通的JavaScript对象传入Vue实例作为data选项,Vue将遍历对象所有的property,并使用Object.defineProperty把这些property全部转为getter/setter方法
getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property 被访问和修改时通知变更。这里需要注意的是不同浏览器在控制台打印数据对象时对 getter/setter 的格式化并不同,所以建议安装 vue-devtools 来获取对检查数据更加友好的用户界面。goole
此处可以写个demo来实现数据劫持,通过vue开发者工具可以看到劫持的数据内容以及原始数据是否修改
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Vue2的缺点</title><script src="./vue.js"></script>
</head><body><div id="app"><div v-for="val in obj">{{val}}</div><!-- <div v-for="val in arr">{{val}}</div> --><button @click="handle">添加一个属性</button></div><script>//通过手动修改的(get\set方法进行修改),不能动态添加,不会自动刷新,检测到页面有内容刷新的时候才会刷新var vm = new Vue({el: "#app",data: {obj: {name: "你好",age: "23"},arr: [11, 22, 33, 44, 55]},methods: {handle () {this.obj.id = "123321";this.obj.name = "更改的name值";// console.log(this.obj);}}})// 数据劫持let perser = {name: "张三",age: 22}let p = {};//底层会加两个object,为name和age值,检测到name改变之后才会重新在加载一下,数据劫持,修改原有的属性才会更新视图Object.defineProperty(p, "name", {get () {console.log("name被查询了");return perser.name;},set (val) {console.log("name被修改了");perser.name = val;}});</script></body></html>
在控制台打印p对象中的某个属性值的时候,会出现数据劫持的情况,其中get方法是数据被查询时触发的方法,set方法是数据被修改触发的方法,但是此时数据修改并没有动态添加,不会自动刷新,也就是初始的值并没有被修改
解决方案
因为vue2通过使用Object.defineProperty()方法,所以存在下列问题,对象新增属性时,删除属性时,界面不会更新,直接通过下标修改数组界面不会自动更新
解决方式:
1.$set
2.数组使用内置的方法
$ set的三个参数
this.$set(要改变的数组或者对象,下标或者键名,要添加的数据)
数组的内置方法详情请看【JavaScirpt-06】数组的内置方法(重点!)
综上: 所有的指令有v-model、v-for、v-if、v-show、v-on、v-bind
另还有v-html和v-text,类似于innerHTML和innerText;
v-once:定义它的标签或者组件,只会初始化渲染一次包含子节点,首次渲染后,不会再随着数据的改变而改变,变成静态内容
v-once所在节点在初次动态渲染后,就视为静态内容了
以后数据的改变不会引起v-once所在的解构的更新,可以用于优化性能