记录本文主要是为了总结,把多篇博文里我认为重要的点记录下来,以便查找。感兴趣的可以详细看原文。
一、
1、由于Vue使用getter/setter等ES5特性,所以兼容到IE9
2、每一个Vue实例(组件本质上就是一个Vue实例)需要有一个根元素
3、不应该在模板表达式中试图访问用户定义的全局变量
二、
1、命名约定
1.1 组件命名,字母小写且包含一个中划线(-)
<kebab-cased-component></kebab-cased-component>
1.2 注册组件时,使用中划线、小驼峰、大驼峰这三种任意一种都可以
// 在组件定义中
components: {
// 使用 中划线 形式注册
'kebab-cased-component': { /* ... */ },
// 使用 小驼峰 形式注册
'camelCasedComponent': { /* ... */ },
// 使用 大驼峰 形式注册
'PascalCasedComponent': { /* ... */ }
}
2、data
2.1 不应该对data
属性使用箭头函数
2.2 vue实例创建之后,可以通过vm.$data
访问原始数据对象,vue实例也代理了data对象上所有的属性
2.3 以_
或$
开头的属性不会被Vue实例代理,因为它们可能和Vue内置的属性或方法冲突。可以使用例如vm.$data._property
的方式访问这些属性
var values = {
message: 'Hello Vue!',
_name: '小火柴'
}
var vm = new Vue({
el: '#app',
data: values
})
console.log(vm._name);//undefined
console.log(vm.$data._name);//'小火柴'
3、隐藏未编译
一般地,使用模板差值时,页面上会显示大括号及占位符。编译完成后,再转换为真正的值。如果在网络条件不好的情况下,这种现象更加明显
【v-cloak】
这个指令保持在元素上直到关联实例结束编译。和 CSS 规则如 [v-cloak] { display: none }
一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕
<style>
[v-cloak]{display:none;}
</style>
<div id="example" v-cloak>{{message}}</div>
<script src="https://unpkg.com/vue"></script>
<script>
var vm = new Vue({
el: '#example',
data:{
message:'match'
},
})
</script>
4、class绑定
绑定class包括对象语法、数组语法和组件绑定
4.1 【对象语法】
<div id="app" class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }">
</div>
<script>
var app = new Vue({
el: '#app',
data:{
isActive:true,
hasError:false
}
})
</script>
<div id="app" :class="classObject"></div>
<script>
var app = new Vue({
el: '#app',
data: {
isActive: true,
error: null
},
// 绑定返回对象的计算属性。这是一个常用且强大的模式
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal',
}
}
}
})
</script>
4.2 【数组语法】
<div id="app" :class="[activeClass, errorClass]"></div>
<script>
var app = new Vue({
el: '#app',
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
})
</script>
如果要根据条件切换列表中的 class ,可以用三元表达式
<div id="app" :class="[isActive ? activeClass : '', errorClass]"></div>
也可以在数组语法中使用对象语法
<div id="app" :class="[{ active: isActive }, errorClass]"></div>
4.3 【组件绑定】
在一个定制组件上用到class
属性时,这些类将被添加到根元素上面,这个元素上已经存在的类不会被覆盖
<div id="app" class="test">
<my-component class="baz boo"></my-component>
</div>
<script>
Vue.component('my-component', {
template: '<p class="foo bar">Hi</p>'
})
var app = new Vue({
el: '#app'
})
</script>
最终将被渲染为如下所示
<div id="app" class="test">
<p class="foo bar baz boo">Hi</p>
</div>
5、style绑定
5.1 【对象语法】
<div id="app" :style="styleObject"></div>
<script>
var app = new Vue({
el: '#app',
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}
})
</script>
5.2 【数组语法】
<div id="app" :style="[baseStyles, overridingStyles]"></div>
<script>
// 可以将多个样式对象应用到一个元素上
var app = new Vue({
el: '#app',
data: {
baseStyles: {
color: 'red',
fontSize: '13px'
},
overridingStyles:{
height:'100px',
width:'100px'
}
}
})
</script>
5.3 【前缀】
当v-bind:style
使用需要特定前缀的CSS属性时,如transform
,Vue.js会自动侦测并添加相应的前缀
可以为 style
绑定中的属性提供一个包含多个值的数组,常用于提供多个带前缀的值
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }">
这会渲染数组中最后一个被浏览器支持的值。在这个例子中,如果浏览器支持不带浏览器前缀的 flexbox,那么渲染结果会是 display: flex
6、过滤器
过滤器可以用在两个地方:模板插值和v-bind
表达式。过滤器应该被添加在JS表达式的尾部,由“管道”符指示
过滤器设计目的是用于文本转换。为了在其他指令中实现更复杂的数据变换,应该使用计算属性
过滤器是JS函数,因此可以接受参数
{{ message | filterA('arg1', arg2) }}
filterA
是个拥有三个参数的函数。message
的值将会作为第一个参数传入。字符串 'arg1'
将作为第二个参数传给 filterA
,表达式 arg2
的值将作为第三个参数
<div id="app">
{{ message}}
{{ message | filterA('arg1', arg) }}
</div>
<script>
var app = new Vue({
el: '#app',
data:{
message: '小火柴',
arg: 'abc'
},
filters: {
filterA: function (value,arg1,arg2) {
return value + arg1 + arg2
}
}
})
</script>
<div id="app" :class="raw | format"></div>
<script>
// 在v-bind表达式中使用过滤器
var app = new Vue({
el: '#app',
data:{
raw: 'active'
},
filters: {
format: function (value) {
return value.split('').reverse().join('')
}
}
})
</script>
7、模板逻辑
7.1 条件渲染 元素不复用 【key属性】
添加一个具有唯一值的key
属性,来声明“这两个元素是完全独立的——不要复用它们”
每次切换时,输入框都将被重新渲染
【注意】<label>
元素仍然会被高效地复用,因为它们没有添加 key
属性
<div id="app">
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="输入用户名" key="username-input">
</template>
<template v-else>
<label>Email</label>
<input placeholder="输入邮箱地址" key="email-input">
</template>
<div>
<button @click="toggle">切换登录方式</button>
</div>
</div>
<script>
var app = new Vue({
el: '#app',
data:{
loginType:'username'
},
methods:{
toggle(){
if(this.loginType === 'username'){
this.loginType = '';
}else{
this.loginType = 'username';
}
}
}
})
</script>
7.2 元素显隐
v-if 的元素显隐会将元素从DOM删除或插入;
而v-show则只是改变该元素的display是否为none
【注意】v-show
不支持 <template>
语法,也不支持 v-else
v-if
是“真正的”条件渲染,因为它确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。v-if
是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真,才开始渲染条件块
而v-show
就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于CSS进行切换
一般来说, v-if
有更高的切换开销,而v-show
有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用v-show
较好;如果在运行时条件不太可能改变,则使用v-if
较好
7.3 循环渲染
7.3.1 可以用 of
替代 in
作为分隔符,它是最接近JS迭代器的语法
<ul id="example-2">
<li v-for="(item, index) of items">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
</ul>
和v-if
模板一样,也可以用带有v-for
的<template>
标签来渲染多个元素块
7.3.2 对象迭代
可以用 v-for
通过一个对象的属性来迭代,第二个参数为键名,第三个参数为索引
<ul id="repeat-object" class="demo">
<li v-for="(value, key, index) in object">
{{ index }}. {{ key }} : {{ value }}
</li>
</ul>
7.3.3 整数迭代
v-for
也可以取整数。在这种情况下,它将重复多次模板
【注意】整数迭代是从1开始,而不是从0开始的
<div id="example">
<span v-for="n in 10">{{ n }} </span>
</div>
1 2 3 4 5 6 7 8 9 10
8、vue数组更新
8.1 变异方法
Vue 包含一组观察数组的变异方法(会改变被这些方法调用的原始数组),它们将会触发视图更新,包含以下方法
push() 接收任意数量的参数,把它们逐个添加到数组末尾,并返回修改后数组的长度
pop() 从数组末尾移除最后一项,减少数组的length值,然后返回移除的项
shift() 移除数组中的第一个项并返回该项,同时数组的长度减1
unshift() 在数组前端添加任意个项并返回新数组长度
splice() 删除原数组的一部分成员,并可以在被删除的位置添加入新的数组成员
sort() 调用每个数组项的toString()方法,然后比较得到的字符串排序,返回经过排序之后的数组
reverse() 用于反转数组的顺序,返回经过排序之后的数组
8.2 非变异方法
不会改变原始数组,但总是返回一个新数组。当使用非变异方法时,可以用新数组替换旧数组
concat() 先创建当前数组一个副本,然后将接收到的参数添加到这个副本的末尾,最后返回新构建的数组
slice() 基于当前数组中一个或多个项创建一个新数组,接受一个或两个参数,即要返回项的起始和结束位置,最后返回新数组
map() 对数组的每一项运行给定函数,返回每次函数调用的结果组成的数组
filter() 对数组中的每一项运行给定函数,该函数会返回true的项组成的数组
以上操作并不会导致Vue丢弃现有DOM并重新渲染整个列表。Vue实现了一些智能启发式方法来最大化DOM元素重用,所以用一个含有相同元素的数组去替换原来的数组是非常高效的操作
8.3 无法检测
由于JS的限制, Vue 不能检测以下变动的数组:
1、利用索引直接设置一个项时,例如: vm.items[indexOfItem] = newValue
2、修改数组的长度时,例如: vm.items.length = newLength
以下两种方式都可以实现和vm.items[indexOfItem]=newValue
相同的效果, 同时也将触发状态更新
// Vue.set
Vue.set(example1.items, indexOfItem, newValue)
// Array.prototype.splice
example1.items.splice(indexOfItem, 1, newValue)
为了解决第二类问题,可以使用 splice
example1.items.splice(newLength)
9、vue事件处理
<!-- 阻止单击事件冒泡 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件侦听器时使用事件捕获模式 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当事件在该元素本身(比如不是子元素)触发时触发回调 -->
<div v-on:click.self="doThat">...</div>
<!-- 点击事件将只会触发一次 -->
<a v-on:click.once="doThis"></a>
【注意】使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,用 @click.prevent.self
会阻止所有的点击,而 @click.self.prevent
只会阻止元素上的点击
9.1 【stop】
阻止冒泡
<div id="example" @click="parentSetVal" style="border:1px solid black;width:300px;">
<button @click="setVal">普通按钮</button>
<button @click.stop="setVal">阻止冒泡</button>
</div>
若不加 stop,先调用 setVal 再调用 parentSetVal;否则阻止冒泡,只调用 setVal
9.2 【prevent】
取消默认事件
<div id="example">
<a href="http://cnblogs.com" target="_blank">普通链接</a>
<a @click.prevent href="http://cnblogs.com" target="_blank">取消默认行为</a>
</div>
点击普通链接,会在新窗口打开链接;
点击取消默认行为的a标签,不会在新窗口打开链接。
9.3 【capture】
事件捕获模式
<div id="example" @click.capture="parentSetVal" style="border:1px solid black;width:300px;">
<button @click.capture="setVal">事件捕获</button>
<button @click="reset">还原</button>
<div>{{result}}</div>
</div>
<script>var example = new Vue({
el: '#example',
data:{
result:''
},
methods:{
setVal(event){
this.result+=' 子级 ';
},
parentSetVal(){
this.result+=' 父级 ';
},
reset(){
history.go()
}
}
})
</script>
点击事件捕获按钮,先调用 parentSetVal,再调用 setVal;
点击还原按钮,县调用 parentSetVal,再调用 reset
9.4 【self】
<div id="example">
<div @click="setVal" :style="styleObj1">
<div :style="styleObj2">普通</div>
<button @click="reset">还原</button>
</div>
<div @click.self="setVal" :style="styleObj1">
<div :style="styleObj2">self</div>
<button @click="reset">还原</button>
</div>
</div>
点击普通div,会调用 setVal,点击普通div的父级div,也会调用 setVal
点击self div区域,不会调用 setVal,点击 self div的父级div,才会调用 setVal
9.5 【once】
只触发一次
<div id="example">
<button @click="setVal">普通按钮</button>
<button @click.once="setVal">触发一次</button>
</div>
9.6 鼠标修饰符
.left 左键
.right 右键
.middle 滚轮
<div id="example">
<button @mouseup.right="right" @mouseup.middle="middle" @mouseup.left="left">{{message}}</button>
</div>
9.7 键值修饰符
.enter 回车
.tab 制表键
.delete (捕获 “删除” 和 “退格” 键)
.esc 返回
.space 空格
.up 上
.down 下
.left 左
.right 右
<!-- 只有在 keyCode 是 13 时调用 vm.submit() -->
<input v-on:keyup.13="submit">
可以通过全局 config.keyCodes
对象自定义键值修饰符别名
<div id="example">
<button @keyup.a="a" @keyup.b="b">{{message}}</button>
</div>
<script>
Vue.config.keyCodes.a = 65;
Vue.config.keyCodes.b = 66;
var example = new Vue({
el: '#example',
data:{
message:'按下键盘上的a键或b键'
},
methods:{
a(){
this.message = 'a'
},
b(){
this.message = 'b'
},
}
})
</script>
9.10 修饰键
.ctrl
.alt
.shift
.meta
<!-- Alt + C -->
<input @keyup.alt.67="clear">
<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>