注意
所演示的示例,都是在JS中将Vue实例绑定至HTML中的指定元素,然后再通过Vue实例中data
内的属性或者methods
中的方法,来对所绑定元素的子元素进行操作的,而不是对指定ID元素本身进行操作。
<div id="app">
{{ message }}
</div>
有时候代码正常,但是Vue会报如下的错误,可能是因为在HTML页面中,JS脚本的载入在HTML页面的渲染之前执行了,解决方法就是把相关的script
标签移动至body
标签内最后的部分。
[Vue warn]: Cannot find element: #element-id
声明式渲染 – Declarative Rendering
简单的文本渲染
在HTML的元素内写上{{ message }}
,然后在JS中为data
内的message
属性指定值,即可显示所指定的文本,这是最基础的显示文本的方式。
在JS中,el用于定位HTML元素,Vue实例中的message属性与HTML中的字段同名,其值则会被渲染在最终的HTML页面中。
如果在控制台中手动更改app1.message
的值,则能够看到HTML页面中显示的文本也会即时更新。
<div id="app1">
{{ message }}
</div>
var app1 = new Vue({
el: '#app1',
data: {
message: 'Hello Vue!'
}
})
HTML元素属性绑定
在HTML中,通过v-bind
这个指令来绑定至元素的指定属性,如v-bind:title
就会将Vue实例绑定至HTML元素的title
属性上。
带v-
前缀的指令用于对所渲染的DOM执行响应式操作。
下面的代码实现的效果是:当鼠标悬浮至span
元素所显示的文本上时,就会显示JS中message
的值,即:
'You loaded this page on ' + new Date()
<div id="app2">
<span v-bind:title="message">
Hover your mouse over me for a few seconds to see my dynamically bound title!
</span>
</div>
var app2 = new Vue({
el: '#app2',
data: {
message: 'You loaded this page on ' + new Date()
}
})
如果用下面第一行的写法,那么最终渲染出来的HTML源代码则为第二行中的样子,而不是期望中的:将innerHTML
属性绑定至message
字段即可显示指定的文本。
<div v-bind:innerHTML="message"></div> // original code
<div innerHTML="Hello Vue"></div> // rendered content
条件判断与循环
条件判断
Vue不仅可以将数据绑定至属性,还能够绑定到DOM的结构上。
通过设置Vue实例中任意属性值为true
或者false
,可以生成或删除该元素。
查看最终的HTML源代码可知,Vue删除元素并不是更改其display
属性,而是直接将整个HTML元素替换为<!---->
这段字符串,这样更安全,用户将无法通过查看源代码的方式来拿到元素原本的内容。
<div id="app3">
<p v-if="seen">Now you see me :)</p>
</div>
var app3 = new Vue({
el: '#app3',
data: {
seen: true
}
})
循环
v-for
指令用于循环遍历数组中的元素。
在下面的示例中,Vue实例的todos
属性包含三个元素,元素字段名为text
,字段值为字符串。
而在HTML页面中,在ol
之内的li
元素只需写一个。通过v-for
指令,能够根据Vue实例中对应属性里的元素个数,直接生成指定个li
元素,其中不包含HTML原始代码里的那个li
元素。
对于每个生成的li
元素,设置其文本为所绑定todos
属性中所对应的text
字段的值。即第一个li
元素的值,为todos
属性中第一个text
字段的值,第二个li
元素的值为第二个text
字段的值,以此类推。
<div id="app-4">
<ol>
<li v-for="todo in todos">
{{ todo.text }}
</li>
</ol>
</div>
var app4 = new Vue({
el: '#app-4',
data: {
todos: [
{ text: 'Learn JavaScript' },
{ text: 'Learn Vue' },
{ text: 'Build something awesome' }
]
}
})
app4.todos.push({ text: 'You made it!'})
语句会在app4
这个Vue实例的todos
属性的最后再添加一个text
字段。
处理用户输入
调用函数
v-on
指令用于绑定事件监听至指定的HTML元素上,这样可以调用所关联的Vue实例中的方法。
在下面的示例中,通过Vue实例中的reverseMessage
方法,来将message
属性中的文本逆序排列。
<div id="app-5">
<p>{{ message }}</p>
<button v-on:click="reverseMessage">Reverse Message</button>
</div>
var app5 = new Vue({
el: '#app-5',
data: {
message: 'Hello Vue!'
},
methods: {
reverseMessage: function () {
this.message = this.message.split('').reverse().join('')
}
}
})
双向数据绑定
v-model
实现双向数据绑定的效果。
在下面的示例中,v-model="message"
实现对message
的双向绑定。
在input
控件中输入的内容会同步更新至p
元素。
但是!p
元素的内容被更改之后,input
控件中的内容并不会同步更新。(那应该如何理解这个双向数据绑定呢?)
<div id="app-6">
<p>{{ message }}</p>
<input type="text" v-model="message">
</div>
var app6 = new Vue({
el: '#app-6',
data: {
message: 'Hello Vue!'
}
})
组件系统
在Vue中,组件 – Component,是一个非常重要的概念。
编写大型应用时,很多地方是通用的,可以划分为若干个体积小的、自包含的(啥意思?)、可重用的组件。比如以列表形式展示内容的模块,就可以编写为一个大组件,而列表中的每个内容,又是一个小组件。
本质上,Vue中的组件就是一个带预定义设置的Vue实例。下面的代码示范了如何注册一个Vue组件:
Vue.component('todo-item', {
template: '<li>This is a todo</li>'
})
注册完组件之后,在HTML中,就可以用下面的方式创建一个组件的实例:
<ol>
<todo-item></todo-item>
</ol>
但是以上面的方式来简单地定义一个组件的话,如果创建多个组件的实例,生成的文本都是相同的。为了让各个组件有不同的内容,可以通过props
属性,来将父级域的值,传递给子组件。
Vue.component('todo-item', {
props: ['todo'],
template: '<li>{{ todo.text }}</li>'
})
然后就可以通过v-bind
指令,在HTML中将父元素的值传递给各个子组件。
下面的代码,在HTML中遍历Vue实例中groceryList
属性里的每一项item
,并将每个item
与todo
绑定。
而在定义组件的JS代码中,接收传入的todo
,并在li
元素中显示todo
中的字符串。
// 定义Vue组件todo-item
// 组件中通过名为todo的props属性
// 来从父级域向子组件中传递数据
// 下面的代码即是将传递给todo属性的text字段渲染至'li'元素中
Vue.component('todo-item', {
props: ['todo'],
template: '<li>{{ todo.text }}</li>'
}
// Vue实例中定义属性数组groceryList
new Vue({
...
data: {
groceryList: [
{ text: '...' },
{ text: '...' },
{ text: '...' }
]
}
})
// HTML中创建todo-item组件
// 遍历属性数组groceryList中的每一项item
// 并将其与todo绑定
// 如此便可将每个todo中的数据传至各个组件中
<todo-item v-for="item in groceryList" v-bind:todo="item">
再总结一下上面的例子:
在Vue实例中定义属性数组,数组中的元素用于在前端页面上以有序列表形式显示;
定义Vue组件,设置好所绑定的props属性的名称,以及Vue实例中属性数组元素的显示格式;
在前端HTML页面中,写一个组件,用
v-for
遍历属性数组,并用v-bind
将实例中的数据传递给前台。