Vue

此篇文章更多的是讲述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] )

  1. exoOrFn:为表达式或计算属性函数,也可以是一个属性。
  2. 触发的回调函数。
  3. 可添加的选项。

例如:

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的时候,控制台输出:

-------------本文结束感谢您的阅读-------------