此篇文章更多的是讲述Vue的基础入门和一些基本的概念(因为笔者知识有限),如果你是探索Vue框架的底层实现原理或者对Vue的使用非常熟悉可以对本文略过。如果您在阅读本文的时候发现错误的地方,欢迎留言探讨。
Vue是什么
Vue是一款友好的、多用途且高性能的JavaScript框架。首先要理解的是Vue等目前框架和之前JQuery之类传统的不同的地方。他靠的是数据驱动,对DOM是不进行操作的,不使用DOM的增删改查,通过数据的变化 ,来渲染的当前的结构。
Vue的特点
Vue框架的主要的特色是响应式的数据绑定,区别于以往的命令式用法。也就是在var a=1;的过程中,拦截’=’的过程,从而实现更新数据,web视图也自动同步更新的功能。而不需要显式的使用数据更新视图(命令式)。
说到Vue就不得不说一下MVVM编程思想了。传统的MVC编程思想是将应用程序分为逻辑层、控制层、显示层三个层面进行开发,以达到高内聚,低耦合的目的。在MVVM框架下视图和模型是不能直接通信的,只能通VM(ViewModel)进行交互,它能够监听到数据的变化,然后通知视图进行自动更新,而当用户操作视图时,VM也能监听到视图的变化,然后通知数据做相应改动,这实际上就实现了数据的双向绑定。
Vue基础
插值表达式
数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值。
例如:1
2
3
4
5
6
7
8
9
10
11<div id="one">
<p>{{message}}</p>
</div>
<script type="text/javascript">
var v = new Vue({
el: '#one',
data: {
message: 'hello world!'
}
});
</script>
结果:
JavaScript表达式
对于所有的数据绑定,Vue.js都提供了完全的JavaScript表达式支持。
例如:1
2
3
4
5
6
7
8
9
10
11
12
13
14<div id="one">
<p>{{number + 1}}</p>
<p>{{number==1?"男":"女"}}</p>
<p>{{message.toUpperCase()}}</p>
</div>
<script type="text/javascript">
var v = new Vue({
el: '#one',
data: {
number: 1,
message: "hello vue"
}
});
</script>
结果:
指令
v-html
v-html:双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要使用 v-html 指令。
v-text
v-text:它的作用和插值表达式类似,和差值表达式的区别是,如果值已经被绑定那么就显示这个值,如果该值未被绑定就不显示。而插值表达式则会显示两个大括号。
v-bind
v-bind:可以绑定标签上的任何属性
绑定超链接地址:1
2
3
4
5
6
7
8
9<div id="three"><a v-bind:href="url">百度</a></div>
<script type="text/javascript">
var vm = new Vue({
el : '#three',
data : {
url : "https://www.baidu.com"
}
});
</script>
绑定图片路径:1
2
3
4
5
6
7
8
9<div id="three"><img v-bind:src="src">Logo</a></div>
<script type="text/javascript">
var vm = new Vue({
el : '#three',
data : {
src : "https://929050566.github.io/images/Vue/result0.bmp"
}
});
</script>
绑定class对象语法:
如果isActive为true,则返回的结果为 <div class=”active”></div>1
2
3
4
5
6
7
8<div v-bind:class="{active: isActive}" id='app'>
hei</div><script>
var vm = new Vue({
el: '#app',
data: {
isActive: true
}
});</script>
绑定class数组语法:
渲染的结果 <div class=”active text-danger”></div>1
2
3
4
5
6
7
8
9<div v-bind:class="[activeClass, dangerClass]" id='app'>
hei</div><script>
var vm = new Vue({
el: '#app',
data: {
activeClass: 'active',
dangerClass: 'text-danger'
}
});</script>
绑定style对象语法:
渲染的结果<div style=”color: red; font-size: 18px;”></div>1
2
3
4
5
6
7
8
9<div v-bind:style="{color: redColor, fontSize: font18 + 'px'}" id="app">
hei</div><script>
var vm = new Vue({
el: '#app',
data: {
redColor: 'red',
font18: 18
}
});</script>
绑定style数组语法:
渲染的结果<div style=”color:red;font-size:18px”>1
2
3
4
5
6
7
8
9
10
11
12<div v-bind:style="[color, fontSize]" id="app">abc</div><script>
var vm = new Vue({
el: '#app',
data: {
color: {
color: 'red'
},
fontSize: {
font-size: '18px'
}
}
});</script>
v-model
v-model:绑定数据源,实现了双向数据绑定1
2
3
4
5
6
7
8
9
10
11
12<div id="test">
<input type="text" v-model="message">
<p>{{ message }}</p>
</div>
<script>
var vm = new Vue({
el: '#test',
data: {
mesage: 'hello'
}
});
</script>
运行上面的脚本,可以看到P标签里面的数值,会和input标签输入的数值同步。这就实现了数据的双向绑定。
v-if/v-show
v-if:显示与隐藏1
2
3
4
5
6
7
8
9
10
11<div id="box">
<div style="width: 100px;height: 100px;background: black;" v-if="show"></div>
</div>
<script>
new Vue({
el: "#box",
data: {
show: true
}
})
</script>
如果show的值为true则该标签显示,如果为false则不显示。将v-if替换成v-show的显示效果是一样的,但是v-show:初始渲染开销比较大(切换次数多用show)。;v-if:更高的切换开销(切换次数少用if)。
v-else-if/v-else
v-else-if和v-else和Java中if-else-if和if-else语法是类似的。需要与v-if连用。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26<div id="box">
<input type="radio" v-model="language" value="1">A
<input type="radio" v-model="language" value="2">B
<input type="radio" v-model="language" value="3">C
<input type="radio" v-model="language" value="4">D
<div v-if="language=='1'">
C语言
</div>
<div v-else-if="language=='2'">
C++语言
</div>
<div v-else-if="language==='3'">
Java语言
</div>
<div v-else="language==='4'">
Python语言
</div>
</div>
<script>
new Vue({
el: "#box",
data: {
language: '1'
}
})
</script>
结果:
当选中不同的选项之后,会显示出对应的div。
v-on
v-on用于事件的绑定。1
2
3
4
5
6
7
8
9
10
11
12
13<div id="box">
<button v-on:click="say">按钮</button>
</div>
<script>
new Vue({
el: "#box",
methods: {
say: function() {
alert(111);
}
}
})
</script>
v-once
v-once:只加载一次,如果用到事件中就是事件只执行一次(@click.once=”show”)
v-pre
v-pre:把标签内部的元素原位输出
v-for
v-for的使用方式较多。
前提-script脚本:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23<script>
var vm = new Vue({
el : '#box',
data : {
student: {
name:'zhangsan', sex:'1', groupid:'1810'
},
students: [
{name:'张三',sex:'1',groupid:'1810'},
{name:'李四',sex:'0',groupid:'1810'},
{name:'王五',sex:'1',groupid:'1810'}
],
studentMap: {
totalrecords: '3',
students: [
{name:'张三',sex:"1",groupid:'1810'},
{name:'李四',sex:'0',groupid:'1810'},
{name:'王五',sex:'1',groupid:'1810'}
]
}
},
});
</script>
1-10的有序列表:1
2
3
4
5<div id="box">
<ul>
<li v-for="i in 10">{{i}}</li>
</ul>
</div>
提取student所有数据:1
2
3
4
5
6<div id="box">
<ul>
<li v-for="(s,key,index) in student">{{index}}:{{key}}-{{s}}</li>
</ul>
</div>
<script>
遍历list:1
2
3
4
5
6
7
8<ul>
<li v-for="s in students">
{{s.name}}-
<span v-if="s.sex == '1'">男</span>
<span v-else>女</span>
-{{s.groupid}}
</li>
</ul>
遍历map:1
2
3
4
5
6
7
8
9
10
11
12<div id="box">
<ul>
<li>{{studentMap.totalrecords}}</li>
</ul>
<ul>
<li v-for="s in studentMap.students">
{{s.name}}-
{{s.sex='1'?"男":"女"}}
- {{s.groupid}}
</li>
</ul>
</div>
执行结果如下:
实例属性
el
用于指定实例使用的根DOM,它的值一般都是#+标签id值:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16<body>
<div id="box">
<h4>你好,这是四级标题</h4>
<p>这是一个段落,我什么都不想说</p>
</div>
<button onclick="getEl()">获得el选项的DOM元素</button>
<script>
var vm = new Vue({
el:'#box'
})
function getEl(){
console.log(vm.$el);//获得DOM元素
vm.$el.style.color='red';//设置字体颜色
}
</script>
</body>
当点击button按钮之后,可以看到浏览器控制打印的信息:
data
Vue 实例观察的数据对象。Vue 实例代理了对其 data 对象属性的访问。
即可以访问data选项中的数据。1
2
3
4
5
6
7
8
9
10
11
12
13<button onclick="getData()">vm.$data获得数据值</button>
<script type="text/javascript">
var vm = new Vue({
data:{
msg:'你好你好',
arr:['what','are','you','doing','?']
}
})
function getData(){
console.log(vm.$data.msg);
console.log(vm.$data.arr.join(' '));
}
</script>
当点击button之后,控制台输出:
filter
filter:过滤器,过滤器可以用在两个地方:双花括号插值和v-bind表达式。过滤器应该被添加在JavaScript表达式的尾部,由“管道”符号指示:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<div id="four">
<span>{{message | filterA}}</span>
</div>
<script type="text/javascript">
var vm = new Vue({
el : '#four',
data : {
message: 'hello vue'
},
filters: {
filterA: function(value){
if(!value) return ''
value = value.toString();
return value.toUpperCase();
}
}
});
</script>
我们自定义了一个过滤器:filterA,它的功能是将字符串变成大写输出。
过滤器可以串联可以写成{ {message|filterA|filterB。。。} }
watch
语法:vm.$watch( expOrFn, callback, [options] )
- exoOrFn:为表达式或计算属性函数,也可以是一个属性。
- 触发的回调函数。
- 可添加的选项。
例如:1
2
3
4
5
6
7
8
9
10
11
12
13
14<div id="box">
<input type="text" v-model="msg">
</div>
<script type="text/javascript">
var vm = new Vue({
el: "#box",
data: {
msg:'你好你好'
}
});
vm.$watch('msg',function(newVal,oldVal){
console.log('新值为:' + newVal + ',旧值为:' +oldVal);
});
</script>
初始的input标签value为”你好你好”,当我修改成hello vue的时候,控制台输出: