1、Vue实例与数据绑定
1.1 实例与数据
Vue.js应用的创建很简单,通过构造函数Vue就可以创建一个Vue的根实例,并启动Vue应用:
var app = new Vue({
// 选项
});
变量app就代表了这个实例。
首先,必不可少的一个选项就是el。el用于指定一个页面中已存在的DOM元素来挂载Vue实例。
<div id="app">{{ name }}</div>
var app = new Vue({
el: document.getElementById('app'), // 或者 ‘#app’
data :{
name: 'Hello World'
}
});
其次,通过Vue实例的data选项,可以声明应用内需要双向绑定的数据。建议所有会用到得数据都预先在data内声明,这样不至于将数据散落在业务逻辑中,难以维护。
除了显示得声明数据外,也可以指向已有得变量,并且它们之间默认建立了双向绑定,当修改其中任意一项时,另一个也会一起变化,即匹配更新为新的值。
var myData = {
a:1
};
var app = new Vue({
el: ‘#app’,
data: myData
});
console.log(app.a); // 1
// 修改属性,原数据也会随之改变
app.a = 2;
console.log(myData.a); // 2
// 反之,修改原数据,Vue属性也会改变
myData.a = 3;
console.log(app.a); // 3
1.2 Vue生命周期
每个Vue实例创建时,都会经历一系列得初始化过程,同时也会调用相应的生命周期钩子,我们可以利用这些钩子,在合适的时机执行我们的业务逻辑。例如jQuery的ready()方法。
$(document).ready(function(){
// DOM加载完成后,会执行这里得代码
});
Vue的生命周期与之类似
Vue2.0 | Description |
---|---|
beforeCreate | 组件实例刚被创建,组件属性计算之前,如data属性等 |
created | 组件实例创建完成,属性已绑定,但DOM还未生成,$el 属性还不存在,需要初始化处理一些数据时会比较有用。 |
beforeMount | 模版编译/挂载之前 |
mounted | 模版编译/挂载之后,一般我们的第一个业务逻辑会在这里开始。 |
beforUpdate | 组件更新之前 |
updated | 组件更新之后 |
activated | for keep-alive,组件被激活时调用 |
deactivated | for keep-alive,组件被移除时调用 |
beforeDestory | 组件销毁前调用,主要解绑一些使用addEventListener监听的事件等。 |
destroyed | 组件销毁后调用 |
1.3 插值与表达式
文本
数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值:
<span>Message: {{ msg }}</span>
Mustache 标签将会被替代为对应数据对象上msg属性的值。无论何时,绑定的数据对象上 msg 属性发生了改变,插值处的内容都会更新。
原始 HTML
双大括号会将数据解释为普通文本,而非HTML代码。为了输出真正的 HTML,你需要使用 v-html 指令:
<p>Using v-html directive: <span v-html="rawHtml"></span></p>
这里需要注意,如果将用户产生得内容使用v-html输出后,有可能导致XSS攻击,所以要在服务端对用户提交得内容进行处理,一般可将尖括号“<>”转义。
v-pre
如果想显示{{}}标签,而不进行替换,使用v-pre即可跳过这个元素和它子元素得编译过程。
<span>{{ 这里的内容是不会被编译的 }}</span>
特性
Mustache 语法不能作用在 HTML 特性上,遇到这种情况应该使用 v-bind 指令:
<div v-bind:id="dynamicId"></div>
使用 JavaScript 表达式
对于所有的数据绑定,Vue.js 都提供了完全的 JavaScript 表达式支持
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-' + id"></div>
Vue.js只支持单个表达式,不支持语句和流控制。另外在表达式中,不能使用用户自定义的全局变量,只能使用Vue白名单内的全局变量,例如Math和Date。以下是一些无效得示例:
<!-- 这是语句,不是表达式-->
{{ let name = "hello world" }}
<!-- 不能使用流控制,要使用三元运算 -->
{{ if (ok) { return msg } }}
2、指令与事件
指令 (Directives) 是带有 v- 前缀的特殊特性。指令特性的值预期是单个 JavaScript 表达式 (v-for是例外情况)。指令的职责是,当表达式的值改变时,将其产生的连带影响,响应式地作用于DOM。
2.1 参数
v-bind 一些指令能够接收一个“参数”,在指令名称之后以冒号表示。例如,v-bind 指令可以用于响应式地更新 HTML 特性,比如id,class等。
<div id="app">
<a v-bind:href="url">链接</a>
<img v-bind:src="imgUrl">
</div>
<script>
var app = new Vue({
el:'#app',
data:{
url: "https://www.github.com",
imgUrl: "http://xxx.xxx.xx/img.png"
}
});
</script>
示例中的链接地址与图片得地址都与数据进行了绑定,当通过各种方式改变数据时,链接和图片都会自动更新。
v-on另一个例子是 v-on 指令,它用于监听 DOM 事件:
<div id="app">
<p v-if="isShow">看见还是看不见?</p>
<button v-on:click="handleClose">点击隐藏</button>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
isShow:true
},
methods:{
handleClose(){
this.isShow = false;
}
}
});
</script>
在button 按钮上使用v-on:click给元素绑定一个点击事件,在普通元素上,v-on可以监听原生DOM事件。除click外,还有dblclick、keyup、mousemove等。表达式可以是一个方法名,这些方法都写在Vue实例得methods属性内,并且是函数的形式,函数内this指向的当前Vue实例本身,因此可以直接使用this.xxx的形式来访问或修改数据。
表达式除了方法外,也可以直接是一个内联语句,上例也可以改为:
<div id="app">
<p v-if="isShow">看见还是看不见?</p>
<button v-on:click="show = false">点击隐藏</button>
</div>
<script>
var app = new Vue({
el:'#app',
data:{
isShow:true
}
});
</script>
这种场景只适用于简单得业务逻辑,如果绑定的事件要处理复杂得业务逻辑,建议还是在mothods里声明一个方法,这样可读性更强也利于维护。
2.2 语法糖
语法糖是指在不影响功能得情况下,添加某种方法实现同样得效果,从而方便程序开发。
Vue.js的v-bind和v-on都提供了语法糖,也可以说是缩写,
v-bind,可以直接省略v-bind,直接写一个冒号“:”:
<a v-bind:href="url">链接</a>
<img v-bind:src="imgUrl">
<!-- 缩写为 -->
<a :href="url">
<img :src="imgUrl">
v-on可以直接用“@”来缩写:
<button v-on:click="handleClose">点击隐藏</button>
<!-- 缩写为 -->
<button @click="handleClose">点击隐藏</button>
3、class与style绑定
3.1 绑定class的几种方法
1. 对象语法
给v-bind:class设置一个对象,可以动态的切换class,例如:
<div id="app">
<div :class="{ 'active': isActive }"></div>
</div>
<script>
var app = new Vue({
el: '#app',
data:{
isActive: true
}
});
上面示例中,类名active依赖与数据isActive,当其为true时,div会拥有类名active,为false时则没有,所以上面示例的最终渲染结果为:
<div class="active"></div>
当:class的表达式过长或逻辑复杂时,还可以绑定一个计算属性,这是一种很友好很常见的方法,一般当条件多于两个时,都可以使用data或者computed,例如使用计算属性:
<div id="app">
<div :class="classes"></div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
isActive: true,
error: null
},
computed:{
classes(){
return {
active: this.isActive && !this.error,
'text-fail': this.error && this.error.type==='fail'
};
}
}
});
</script>
除了计算属性,你也可以直接绑定一个object类型的数据,或者使用类似计算属性的mothods。
2. 数组语法
当需要多个class时,可以直接使用数组语法,给:class 绑定一个数组,应用一个class列表:
<div id="app">
<div :class="[activeCls,errorCls]"></div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
activeCls: 'active',
errorCls: 'error'
}
});
</script>
渲染的结果为:
<div class="active,error"></div>
也可使用三元运算表达式来根据条件切换class,例如下面的例子:
<div id="app">
<div :class="[isActive ? activeCls : '',errorCls]"></div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
isActive: true,
activeCls: 'active',
errorCls: 'error'
}
});
</script>
与数组语法一样,也可以使用data,computed和methods三种方法。
3.2 绑定内联样式
使用v-bind:style(即:style)可以给元素绑定内联样式,方法与:class类似,也有对象语法和数组语法,看起来就像直接在元素上写css:
<div id="app">
<div :style="{'color':color, 'fontSize':fontSize + 'px' }">文本</div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
color: red,
fontSize: 14,
}
});
</script>
css属性名称使用驼峰命名(camelCase)或者短横线分割命名(kebab-case),渲染后的结果为:
<div style="color:red;font-size:14px;">文本</div>
大多数情况下,直接写一长串的样式不便于阅读和维护,所以一般写在data或computed里,以data为例:
<div id="app">
<div :style="styles">文本</div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
styles: {
color: 'red',
fontSize: 14 + 'px',
}
}
});
</script>
应用多个样式时,可以使用数组语法:
<div :style=[styleA,styleB]>文本</div>
在实际业务中,:style的数组语法不常用,因为往往可以写在一个对象里面;而较为常用的应当是计算属性。
另外,使用:style时,Vue.js会自动给特殊的css属性名称增加前缀,比如transform。