一 介绍
(1) 声明式渲染, 文本插值
<div id="app">
<p>{{message}}</p>
</div>
<script src="scripts/vue.js"></script>
<script>
new Vue({
el:'#app',
data:{
message:'Hello Vue.js!'
}
})
</script>
(2) v-bind绑定DOM元素属性
<div id="app-2">
<span v-bind:title="message">鼠标悬停几秒,可看到此处动态绑定的title</span>
</div>
<script src="scripts/vue.js"></script>
<script>
var app2 = new Vue({
el:"#app-2",
data:{
message:'页面加载于 ' +new Date()
}
})
</script>
<div id="demo">
<div v-bind:href="url">a</div>
</div>
<script src="scripts/vue.js"></script>
<script>
new Vue({
el:"#demo",
data:{
url:'http://baidu.com'
}
})
</script>
(3) 条件与循环,
v-if:
<div id="demo">
<p v-if="seen">you can see me</p>
</div>
<script src="scripts/vue.js"></script>
<script>
new Vue({
el:"#demo",
data:{
seen:true
}
})
</script>
v-for:
<div id="app-4">
<ol>
<li v-for="todo in todos">{{todo.text}}</li>
</ol>
</div>
<script src="scripts/vue.js"></script>
<script>
var app4 = new Vue({
el:"#app-4",
data:{
todos:[
{text:'学习JavaScript'},
{text:'学习vue'},
{text:'创建激动人心的代码'}
]
}
})
</script>
(4) 处理用户输入
v-on
指令 来增加事件监听器,触发事件后会调用 Vue 实例中 methods 下定义的方法:
<div id="app-5">
<p>{{message}}</p>
<button v-on:click="reverseMessage">翻转message</button>
</div>
<script src="scripts/vue.js"></script>
<script>
var app5 = new Vue({
el:"#app-5",
data:{
message:'hello'
},
methods:{
reverseMessage:function(){
this.message = this.message.split('').reverse().join('')
}
}
})
</script>
v-model
指令,实现表单输入和应用程序状态之间的双向绑定:
<div id="app-6">
<p>{{message}}</p>
<input v-model="message" />
</div>
<script src="scripts/vue.js"></script>
<script>
var app6 = new Vue({
el:'#app-6',
data:{
message:'hello vue'
}
})
</script>
(5) Component
<div id="app-7">
<ol>
<todo-item v-for="item in groceryList"
v-bind:todo="item"
v-bind:key="item.id">
</todo-item>
</ol>
</div>
<script src="scripts/vue.js"></script>
<script>
Vue.component('todo-item',{
props:['todo'],
template:`<li>{{todo.text}}</li>`
})
var app7 =new Vue({
el:"#app-7",
data:{
groceryList:[
{id:0,text:'蔬菜'},
{id:1,text:'奶酪'},
{id:2,text:'水果'}
]
}
})
</script>
二 vue实例
(1) 构造函数
可以通过预先定义选项扩展 Vue 构造函数,从而创建可复用的组件构造函数:
var MyComponent = Vue.extend({ // 扩展选项 }) // `MyComponent` 的所有实例,都将由预先定义的扩展选项来创建 var myComponentInstance = new MyComponent() |
(2) 属性与方法
var data = { a: 1 }
var vm = new Vue({
data: data
})
vm.a === data.a // -> true
// 设置属性也会影响到原始数据
vm.a = 2
data.a // -> 2
// ... 反之亦然
data.a = 3
vm.a // -> 3
var data = { a: 1 }
var vm = new Vue({
el: '#example',
data: data
})
vm.$data === data // -> true
vm.$el === document.getElementById('example') // -> true
// $watch 是一个实例方法
vm.$watch('a', function (newVal, oldVal) {
// 这个回调函数将在 `vm.a` 改变后调用
})
(3) 实例生命周期钩子函数
var vm = new Vue({
data: {
a: 1
},
created: function () {
// `this` 指向 vm 实例
console.log('a is: ' + this.a)
}
})
// -> "a is: 1"
三 模板语法
(1) 插值
文本插值:
<div id="demo">
<span>{{message}}</span>
</div>
<script src="scripts/vue.js"></script>
<script>
new Vue({
el:"#demo",
data:{
message:'hi'
}
})
</script>
纯html,v-html:
<div id="demo">
<div v-html="message"></div>
</div>
<script src="scripts/vue.js"></script>
<script>
new Vue({
el:"#demo",
data:{
message:'<span>hello</span>'
}
})
</script>
属性,v-bind:
<div id="demo">
<div v-bind:href="url">a</div>
</div>
<script src="scripts/vue.js"></script>
<script>
new Vue({
el:"#demo",
data:{
url:'http://baidu.com'
}
})
</script>
Javascript表达式:
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-' + id"></div>
(2) 指令
v-前缀的特殊属性
v-bind
指令被用来响应地更新 HTML 属性:
<div id="demo">
<div v-bind:href="url">a</div>
</div>
<script src="scripts/vue.js"></script>
<script>
new Vue({
el:"#demo",
data:{
url:'http://baidu.com'
}
})
</script>
修饰符(Modifiers)是以半角句号 .
指明的特殊后缀,用于指出一个指令应该以特殊方式绑定:
<div id="demo">
<form v-on:submit.prevent="onSubmit">a</form>
</div>
<script src="scripts/vue.js"></script>
<script>
new Vue({
el:"#demo",
methods:{
onSubmit:function(){
alert('hi')
}
}
})
</script>
(3) 过滤器
Vue 2.x 中,过滤器只能在 mustache 绑定和 v-bind
表达式(从 2.1.0+ 开始支持)中使用,因为过滤器设计目的就是用于文本转换。
<!-- in mustaches -->
{{ message | capitalize }}
<!-- in v-bind -->
<div v-bind:id="rawId | formatId"></div>
<div id="demo">
{{message|capitalize}}
</div>
<script src="scripts/vue.js"></script>
<script>
new Vue({
el:"#demo",
data:{
message:'helloyi'
},
filters:function(value){
if(!value) return ''
value = value.toString();
return value.charAt(0).toUpperCase() + value.slice(1);
}
})
</script>
(4) 缩写
<!-- 完整语法 -->
<a v-bind:href="url"></a>
<!-- 缩写 -->
<a :href="url"></a>
<!-- 完整语法 -->
<a v-on:click="doSomething"></a>
<!-- 缩写 -->
<a @click="doSomething"></a>
四 计算属性
(1) 模板中绑定表达式比较方便,但只适用于简单的操作。模板中放入太多的逻辑会让模板过重且难以维护。这时可以选择计算属性。
<div id="example">
<p>Original message:"{{message}}"</p>
<p>Computed reversed message:"{{reversedMessage}}"</p>
</div>
<script src="scripts/vue.js"></script>
<script>
var vm = new Vue({
el:'#example',
data:{
message:'hello'
},
computed:{
reversedMessage:function(){
return this.message.split('').reverse().join('')
}
}
})
</script>
// Original message: "Hello"
// Computed reversed message: "olleH"
(2) 计算缓存 与 Methods
<div id="example">
<p>{{now}}</p>
</div>
<script src="scripts/vue.js"></script>
<script>
var vm = new Vue({
el:'#example',
data:{
message:'hello'
},
computed:{
now:function(){
return Date.now()
}
}
})
</script>
<div id="example">
<p>Original message:"{{message}}"</p>
<p>Computed reversed message:"{{reversedMessage()}}"</p>
</div>
<script src="scripts/vue.js"></script>
<script>
var vm = new Vue({
el:'#example',
data:{
message:'hello'
},
methods:{
reversedMessage:function(){
return this.message.split('').reverse().join('')
}
}
})
</script>
Ps:计算属性是基于它的依赖缓存。计算属性只有在它的相关依赖发生改变时才会重新取值。而methods调用总会执行函数。
(3) 计算属性 与 watched属性
<div id="demo">
{{ fullName }}
</div>
<script src="scripts/vue.js"></script>
<script>
var vm = new Vue({
el:'#demo',
data:{
firstName:'Foo',
lastName:'Bar',
fullName:'Foo Bar'
},
watch:{
firstName:function(val){
this.fullName = val + ' ' + this.lastName
},
lastName:function(val){
this.fullName = this.firstName + ' ' +val
}
}
})
</script>
<div id="demo">
{{ fullName }}
</div>
<script src="scripts/vue.js"></script>
<script>
var vm = new Vue({
el:'#demo',
data:{
firstName:'Foo',
lastName:'Bar'
},
computed:{
fullName: function(){
return this.firstName + ' ' + this.lastName
}
}
})
</script>
(4) 计算setter
<div id="demo">
{{ fullName }}
</div>
<script src="scripts/vue.js"></script>
<script>
var vm = new Vue({
el:'#demo',
data:{
firstName:'Foo',
lastName:'Bar'
},
computed:{
fullName:{
get:function(){
return this.firstName + ' ' + this.lastName
},
set:function(newValue){
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
}
}
}
})
</script>
五 class与style绑定
(1) 绑定html class
对象语法:传给v-bind:class一个对象,以动态地切换class
<div id="demo">
<div class="static" v-bind:class="{active:isActive,'text-danger':hasError }"></div>
</div>
<script src="scripts/vue.js"></script>
<script>
new Vue({
el:"#demo",
data:{
isActive:true,
hasError:false
}
})
//渲染结果为div的class="static active"
</script>
<div v-bind:class="{ active: isActive }"></div>
<div id="demo">
<div v-bind:class="classObject"></div>
</div>
<script src="scripts/vue.js"></script>
<script>
new Vue({
el:"#demo",
data: {
classObject:{
active:true,
'text-danger':false
}
}
})
//渲染结果为div的class="active"
</script>
<div id="demo">
<div v-bind:class="classObject"></div>
</div>
<script src="scripts/vue.js"></script>
<script>
new Vue({
el:"#demo",
data:{
isActive:true,
error:null
},
computed:{
classObject:function(){
return {
active:this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
}
})
//渲染结果为div的class="active"
</script>
数组语法:把一个数组传给v-bind:class,以应用一个class列表
<div id="demo">
<div v-bind:class="[activeClass,errorClass]"></div>
</div>
<script src="scripts/vue.js"></script>
<script>
new Vue({
el:"#demo",
data:{
activeClass:'active',
errorClass:'text-danger'
}
})
//渲染结果为div的class="active text-danger"
</script>
<div id="demo">
<div v-bind:class="[isActive ? activeClass : ' ',errorClass]"></div>
</div>
<script src="scripts/vue.js"></script>
<script>
new Vue({
el:"#demo",
data:{
isActive:true,
activeClass:'active',
errorClass:'text-danger'
}
})
//渲染结果为div的class="active text-danger"
//此例始终添加errorClass,但只要在isActive为true的情况下添加activeClass的值
</script>
<div id="demo">
<!-- 当有多个条件class时,可以如下方式在数组语法中使用对象语法-->
<div v-bind:class="[{active:isActive},errorClass]"></div>
</div>
<script src="scripts/vue.js"></script>
<script>
new Vue({
el:"#demo",
data:{
isActive:true,
activeClass:'active',
errorClass:'text-danger'
}
})
//渲染结果为div的class="active text-danger"
</script>
用在组件上:
<div id="demo">
<my-component class="baz boo"></my-component>
</div>
<script src="scripts/vue.js"></script>
<script>
Vue.component('my-component',{
template:`<p class="foo bar">hi</p>`
})
new Vue({
el:"#demo",
})
//HTML 最终将被渲染成为:<p class="foo bar baz boo">Hi</p>
</script>
<div id="demo">
<my-component v-bind:class="{active:isActive }"></my-component>
</div>
<script src="scripts/vue.js"></script>
<script>
Vue.component('my-component',{
template:`<p class="foo bar">hi</p>`
})
new Vue({
el:"#demo",
data:{
isActive:true
}
})
//当 isActive 为 true 的时候,HTML 将被渲染成为:<p class="foo bar active">Hi</p>
</script>
(2) 绑定内联样式
对象语法:
<div id="demo">
<div v-bind:style="{color:activeColor,fontSize:fontSize + 'px'}">hi</div>
</div>
<script src="scripts/vue.js"></script>
<script>
new Vue({
el:"#demo",
data:{
activeColor:'red',
fontSize:26
}
})
</script>
<div id="demo">
<div v-bind:style="styleObject">hi</div>
</div>
<script src="scripts/vue.js"></script>
<script>
new Vue({
el:"#demo",
data:{
styleObject:{
activeColor:'red',
fontSize:26
}
}
})
</script>
数组语法:可以将多个样式应用到一个元素上
<div id="demo">
<div v-bind:style="[baseStyles,overridingStyles]">hi</div>
</div>
<script src="scripts/vue.js"></script>
<script>
new Vue({
el:"#demo",
data:{
baseStyles:{
activeColor:'red',
fontSize:26
},
overridingStyles:{
activeColor:'green',
backgroundColor:'grey'
}
}
})
</script>
六 条件渲染
(1)v-if
<div id="demo">
<p v-if="seen">you can see me</p>
</div>
<script src="scripts/vue.js"></script>
<script>
new Vue({
el:"#demo",
data:{
seen:true
}
})
</script>
<div id="demo">
<h1 v-if="ok">yes</h1>
<h1 v-else>no</h1>
</div>
<script src="scripts/vue.js"></script>
<script>
new Vue({
el:"#demo",
data:{
ok:false
}
})
</script>
(2)<template>中v-if条件组
<div id="demo">
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph</p>
<p>Paragraph</p>
</template>
</div>
<script src="scripts/vue.js"></script>
<script>
new Vue({
el:"#demo",
data:{
ok:true
}
})
</script>
(3)v-else
<div id="demo">
<div v-if="Math.random() > 0.5">Sorry</div>
<div v-else>not sorry</div>
</div>
<script src="scripts/vue.js"></script>
<script>
new Vue({
el:"#demo"
})
</script>
(4)v-show简单的切换元素的css属性display
<div id="demo">
<h1 v-show="ok">hello</h1>
</div>
<script src="scripts/vue.js"></script>
<script>
new Vue({
el:"#demo",
data:{
ok:true
}
})
</script>
Ps:
v-if,真实的条件渲染,确保条件块在切换当中适当地销毁与重建条件块内的事件监听器和子组件。V-if是惰性的,即在初始渲染条件为假时,什么也不做,在条件第一次变为真时才开始局部编译。更高的切换消耗。
v-show,元素始终被编译并保留,只是简单的基于css切换。更高的初始渲染消耗。
Ps:当v-if与v-for一起使用时,v-for具有比v-if更高的优先级。
七 列表渲染
ps:文中例子来源于vue官网 https://vuefe.cn/v2/guide/
ps:未完待续。。。