起步
引入 vue.js
核心: 声明式渲染
这里的声明式渲染表示整个Vue实例都是基于数据+模型组成的, Vue本身就是一个数据的载体, 通过双向绑定渲染到DOM中, 其中还可以添加一些方法或是计算属性来响应式修改DOM,基础非常简单易懂
Vue的真正能力是高度组件化, 路由, 高效状态管理,不过通过学习Vue基础就可以很好的将Vue应用在一些简单页面并享受到双向绑定的优势
<div id="app">
{{message}}
<!--使用{{}}的方式引入vue中的属性-->
</div>
var app = new Vue({
el: '#app', // 选取的dom元素, 获得vue特性
data: {//给予该dom的数据,即本身拥有的属性
message: 'Hello Vue'
}
})
执行函数
<div id="app">
<p>{{message}}</p>
<button v-on:click="dosometing">click</button>
<!--使用v-on:click绑定点击事件-->
</div>
var app = new Vue({
el: '#app',
data: {
message: 'Hello World'
},
methods: {//声明该dom携带的函数(function)
dosometing: function() {
this.message = 'Hello Vue'
}
}
})
注册组件
<div id="app">
<ul>
<todo
v-for = "item in list"
v-bind:todo = "item"
v-bind:key = "item.id"
></todo><!--从父组件中获取数据及添加到子组件的属性(props)中-->
</ul>
</div>
Vue.component('todo', {//这里的todo是需要注册的组件的name,即标签名
props: ['todo'],//这里绑定的是该组件所携带的props,即属性,也就是从父组件中获取到的数据
template: '<li>{{todo.text}}</li>'//这里为改组件所渲染的dom元素及相应的模板
})
var app = new Vue({
el: '#app',
data: {
list: [//父组件拥有的数据
{id: 0, text:'第一项'},
{id: 1, text:'第二项'},
{id: 2, text:'第三项'},
{id: 0, text:'第一项'}
]
}
})
Vue实例
一个new Vue()
便是一个新的Vue应用实例
数据与方法
这里vm的data是来源于变量data,vm.data指向data.data,同时可以通过添加前缀$
来区分用户自定义属性
var data = { data: 'data' }//初始化Vue应用数据
var vm = new Vue({
data: data
})
console.log(vm.$data === data.data);
vm.$data = 'datas';
console.log(data.data);
更深入的探讨
生命周期(钩子函数)
Vue使用虚拟DOM算法, 即DOM元素会以最小消耗插入到html中, 在这期间提供的钩子函数,可以插入自己的代码
模板语法
- 文本 {{}}
采用Mustache{{}}的插值方式 - 原始HTML v-html
使用v-html渲染html, 容易导致xss攻击
<div v-html="rawHtml">{{rawHtml}}</div>
- 为DOM添加属性 v-bind
可以使用v-bind为DOM添加相应的属性, 同样的,这里的数据也是来源于Vue实例中的data
<div v-html="rawHtml" v-bind:id="raw">{{rawHtml}}</div>
注意
//这些falsy值都将转为false
if (false)
if (null)
if (undefined)
if (0)
if (NaN)
if ('')
if ("")
//这些truthy值都将转为true
if (true)
if ({})
if ([])
if (42)
if ("foo")
if (new Date())
if (-42)
if (3.14)
if (-3.14)
if (Infinity)
if (-Infinity)
- javascript表达式
Vue的模板支持简单的表达式,只支持单个表达式
<div v-bind:id="'list-' + id"></div>
{{ number + 1}}
{{ ok ?'YES': 'NO'}}
{{ messsage.split('').reverse().join('')}}
指令
Vue带有大量的指令, 用于控制DOM, 如
<p v-if="seen">现在你看到我了</p>
- 参数
某些指令可以添加参数, 可以响应式更新DOM属性
<a v-bind:href="url">Link</a>
<a v-on:click="click">Click</a>
- 修饰符
修饰符(Modifiers), 用于让某一指令应该以特殊方式绑定, 非常有用
如,这里的.provent
代表触发onSubmit事件时调用event.preventDefault()
<form v-on:submit.prevent="onSubmit">Submit</form>
- 缩写
v-本身是用来识别Vue的特性, 不过Vue.js是用于开发单页面(SPA)时, 过长的指令还是比较繁琐
<a :href="url">Link</a>
<a @click="click">Click</a>
计算属性
对于复杂逻辑, 使用计算属性是Vue推荐的方式
计算属性声明在Vue实例中的computed中,使用方式与普通的渲染一致
<div id="app">
<p>{{reversedMessage}}</p>
</div>
var vm = new Vue({
el: '#app',
data: {
message: 'Hello World'
},
computed: {
//在这里声明
reversedMessage: function(){
//在这里处理
return this.message.split('').reverse().join('');
}
}
})
与methods相比, 计算属性是基于它们的依赖,比如上方的message来进行缓存的, 即message不改变的情况下, 计算属性能立即返回值, 而methods定义的方法则每次都需要调用, 相应的, 如果不需要缓存, 则使用methods更好
VUe提供了一种侦听属性来观察相应的数据变动
计算属性默认只提供getter, 不过需要的时候也可以提供一个setter
//...
computed: {
fullName: {
get: function() {
return this.firstName + '' + this.lastName
},
set: function() {
var names = newValue.split(' ');
this.firstName = names[0];
this.lastName = names[names.length -1];
}
}
}
//...
Class及Style
- 绑定HTML Class
通过传入v-bind:class
一个对象, 可以动态切换class
<div v-bind:class="{ active: isActive }"></div>
<div class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }">
</div><!--可以与普通的class共存-->
当isActive为true时则绑定.active样式
相应的, 这里的数据可以绑定在Vue实例中
data: {
classObject: {
active: true,
"text-danger": false
}
}
同时也可以绑定一个返回对象的计算属性,常用而有效,推荐使用
<div v-bind:class="classObject"></div>
data: {
isActive: true,
error: null
},
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
}
- 数组语法
v-bind:class
可以接收一个数组
<div v-bind:class="[activeClass, errorClass]"></div>
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
写法还有多种
<!--三元表达式-->
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
<!--对象语法-->
<div v-bind:class="[{ active: isActive }, errorClass]"></div>
<!--使用在组件上-->
<my-component v-bind:class="{ active: isActive }"></my-component>
- 绑定内联样式
v-bind:style
与绑定class相似,同样传入对象绑定, 不过css属性名必须使用小驼峰写法
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
相应的也可以使用对象及数组语法, 而且Vue能自动检测浏览器并自动添加内核前缀
<!--data对象写法-->
<div v-bind:style="styleObject"></div>
<!--数组语法-->
<div v-bind:style="[baseStyles, overridingStyles]"></div>
<!--多重值 v2.3.0+-->
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}
条件渲染 v-if
Vue提供v-if
, v-else-if(2.1.0+)
及v-else
指令执行条件渲染
<h1 v-if="ok">Yes</h1>
<h1 v-else>No</h1>
Vue会自动复用已有的元素,而非进行重新渲染, 另外可以通过添加唯一key属性来让Vue不复用该元素
<!--不添加key-->
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address">
</template>
<!--添加key-->
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address" key="email-input">
</template>
在v-if
外, 还提供了一个v-show
, 用法相同, 不过后者的元素始终会被渲染并保留在DOM中
列表渲染 v-for
v-for
指令需要使用item in items
形式的特殊语法
- 迭代渲染一个数组
<ul id="example-1">
<li v-for="item in items">
{{ item.message }}
</li>
</ul>
<!--使用of代替in-->
<div v-for="item of items"></div>
var example1 = new Vue({
el: '#example-1',
data: {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
})
v-for
支持一个可选的第二个参数为当前项的索引
<ul id="example-2">
<li v-for="(item, index) in items">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
</ul>
- 迭代渲染一个对象
<ul id="v-for-object" class="demo">
<li v-for="value in object">
{{ value }}
</li>
</ul>
<!--可选的第二个参数,键名-->
<div v-for="(value, key) in object">
{{ key }}: {{ value }}
</div>
<!--可选的第三个参数,索引-->
<div v-for="(value, key, index) in object">
{{ index }}. {{ key }}: {{ value }}
</div>
var example1 = new Vue({
el: '#v-for-object',
data: {
object: {
firstName: 'John',
lastName: 'Doe',
age: 30
}
}
})
同样的,为Vue能获取每个节点而非简单复用原有的元素, 添加key是一个更加方便的写法
<div v-for="item in items" :key="item.id">
<!-- 内容 -->
</div>
数组更新检测
Vue能观察数组的变化而触发视图更新,即数组更新时,视图随着更新
不过部分情况下,Vue不能检测变动的数组
//通过索引直接设置一项
vm.items[indexOfItem] = newValue
//相应的解决方法
// Vue.set
Vue.set(example1.items, indexOfItem, newValue)
// Array.prototype.splice
example1.items.splice(indexOfItem, 1, newValue)
//修改数组长度
vm.items.length = newLength
//相应的解决方法
example1.items.splice(newLength)
相应的,Vue 也不能检测对象属性的添加或删除
不过可以通过Vue.set
添加新的属性
Vue.set(vm.userProfile, 'age', 27);
//使用Object.assgin()时
this.userProfile = Object.assign({}, this.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})
显示过滤排序结果
通过计算属性
<li v-for="n in evenNumbers">{{ n }}</li>
data: {
numbers: [ 1, 2, 3, 4, 5 ]
},
computed: {
evenNumbers: function () {
return this.numbers.filter(function (number) {
return number % 2 === 0
})
}
}
通过methods
<li v-for="n in even(numbers)">{{ n }}</li>
data: {
numbers: [ 1, 2, 3, 4, 5 ]
},
methods: {
even: function (numbers) {
return numbers.filter(function (number) {
return number % 2 === 0
})
}
}
v-for
与v-if
可以同时使用
<li v-for="todo in todos" v-if="!todo.isComplete">
{{ todo }}
</li>
事件处理 v-on
可以使用v-on
来绑定事件
<button v-on:click="counter += 1">增加 1</button>
相应的,可以将事件写在methods中
<button v-on:click="greet">Greet</button>
<!--添加参数-->
<button v-on:click="say('what')">Say what</button>
<!--原生DOM事件-->
<button v-on:click="warn('Form cannot be submitted yet.', $event)">Submit</button>
methods: {
greet: function (event) {
// `this` 在方法里指当前 Vue 实例
alert('Hello ' + this.name + '!')
// `event` 是原生 DOM 事件
if (event) {
alert(event.target.tagName)
}
},
say: function (message) {
alert(message)
},
warn: function (message, event) {
// 现在我们可以访问原生事件对象
if (event) event.preventDefault()
alert(message)
}
}
事件修饰符
Vue提供一些事件修饰符来解决DOM事件细节
<!-- 阻止单击事件冒泡 -->
<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>
键值修饰符
Vue提供一些键值修饰符来监听键盘事件
<!-- 只有在 keyCode 是 13 时调用 vm.submit() -->
<input v-on:keyup.13="submit">
同时也有相应的别名
<!-- 同上 -->
<input v-on:keyup.enter="submit">
<!-- 缩写语法 -->
<input @keyup.enter="submit">
//由Vue提供的别名
.enter
.tab
.delete (捕获“删除”和“退格”键)
.esc
.space
.up
.down
.left
.right
可以通过全局 config.keyCodes 对象自定义键值修饰符别名
// 可以使用 v-on:keyup.f1
Vue.config.keyCodes.f1 = 112
系统修饰键
2.1.0
可以用如下修饰符开启鼠标或键盘事件监听,使在按键按下时发生响应
.ctrl
.alt
.shift
.meta
<!-- Alt + C -->
<input @keyup.alt.67="clear">
<!-- Ctrl + Click -->
<div @click.ctrl="doSomething">Do something</div>
鼠标按钮修饰符
2.1.0
.left
.right
.middle
表单输入绑定 v-model
- 文本
<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>
- 多行文本
<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<br>
<textarea v-model="message" placeholder="add multiple lines"></textarea>
- 复选框
<!--单个勾选框-->
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>
<!--多个勾选框-->
<div id='example-3'>
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>
<br>
<span>Checked names: {{ checkedNames }}</span>
</div>
new Vue({
el: '#example-3',
data: {
checkedNames: []
}
})
- 单选按钮
<div id="example-4">
<input type="radio" id="one" value="One" v-model="picked">
<label for="one">One</label>
<br>
<input type="radio" id="two" value="Two" v-model="picked">
<label for="two">Two</label>
<br>
<span>Picked: {{ picked }}</span>
</div>
new Vue({
el: '#example-4',
data: {
picked: ''
}
})
- 选择列表
<div id="example-5">
<select v-model="selected">
<option disabled value="">请选择</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<span>Selected: {{ selected }}</span>
</div>
<!--多选列表-->
<div id="example-6">
<select v-model="selected" multiple style="width: 50px;">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<br>
<span>Selected: {{ selected }}</span>
</div>
<!--动态渲染-->
<select v-model="selected">
<option v-for="option in options" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
<span>Selected: {{ selected }}</span>
new Vue({
el: '#example-5',
data: {
selected: ''
}
})
//动态渲染
new Vue({
el: '...',
data: {
selected: 'A',
options: [
{ text: 'One', value: 'A' },
{ text: 'Two', value: 'B' },
{ text: 'Three', value: 'C' }
]
}
})
后边的查文档吧,不想写了, 大同小异