Vue (读音 /vjuː/,类似于view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。——来介绍 — Vue.js (vuejs.org)

入门

启动Vue

我们通过在<scrpit>标签中使用如下代码便可以启动Vue

1
2
3
4
5
6
7
8
9
10
11
12
<div id="app">
<span>{{fullName}}</span>
</div>
<script type="text/javascript">
Vue.config.productionTip = false;
const vm = new Vue({
el: '#app',
data: {
fullName: 'Jayhrn'
},
})
</script>
  1. el表示绑定的是哪个元素,在一个Vue对象中只能绑定一个元素。

  2. data表示值,我们可以将返回的值呈现在屏幕上,data的写法有两种,一种是上述的写法,还有一种如下:

    1
    2
    3
    4
    5
    6
    7
    8
    <script type="text/javascript">
    el: ''
    data(){
    return {
    fullname: '',
    }
    }
    </script>

    第二种一般更为常用,可以适用于组件间的传值,并且函数式的写法可以防止数据被污染(因为调用时知只是调用了这个函数生成的数据副本)

  3. Vue.config.productionTip = false;只是为了关闭控制台生产环境下的提示消息。

基本语法

插值语法

如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
<div id="app">
{{message}}
</div>
<script>
const vm = new Vue({
el: '#app',
data() {
return {
message: '学习Vue'
}
},
})
</script>

使用{{...}},两组大括号之间写需要显示的元素,该元素可以是表达式,函数,也可以是data返回的数据。

Attribute

1. v-bind

我们发现如果我们在给HTML元素某些属性赋值时使用插值语法会发生不能生效的问题,如下:

1
2
3
4
<div id="app">
{{message}}
<a href="{{baidu}}">百度</a>
</div>
1
2
3
4
5
6
7
8
9
10
11
<script>
const vm = new Vue({
el: '#app',
data() {
return {
message: '学习Vue',
baidu: 'https://www.baidu.com/'
}
},
})
</script>

将会导致报错[Vue warn]: Error compiling template:href="{{baidu}}": Interpolation inside attributes has been removed. Use v-bind or the colon shorthand instead.

这里我们需要使用v-bind指令

1
2
3
<a v-bind:href="baidu">百度</a>
<!-- 也可以使用如下简写 -->
<a :href="baidu">百度</a>

2. v-model

上述的v-bind的使用只能单方向的传递值,如果我们需要双向的传递,那么v-bind显然是不够的,我们就需要使用v-model来解决了。

什么地方会用到双向传值呢?很显然,我们如果需要动态获取用户输入的值(例如用于监听是否合法时)我们就需要判断,用法也十分的简单。

1
2
3
4
5
6
<div id="app">
姓:<input v-model="firstName" /> <br />
<span>{{firstName}}</span> <br />
名:<input v-model="lastName" /> <br />
<span>{{lastName}}</span> <br />
</div>
1
2
3
4
5
6
7
8
9
10

<script type="text/javascript">
Vue.config.productionTip = false;
const vm = new Vue({
el: '#app',
data: {
firstName: '张',
lastName: '三',
},
</script>

运行我们可以观察到当我们输入姓或者名时,span标签里面的值就会跟着改变。

还有剩余的指令我们将会在后续的学习中讲到。

方法

Vue中,我们需要使用的方法不可以直接在<script>标签中进行书写,因为这样就无法被Vue进行管理了,Vue中有专门的写各种函数的地方,那就是methods

写法如下:

1
2
3
4
5
6
7
8
9
10
11
<script type="text/javascript">
methods: {
函数名() {
//return ...
}
//或者
函数名: function(){

}
},
</script>

例子,通过姓和名获取全名:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script type="text/javascript">
Vue.config.productionTip = false;
const vm = new Vue({

el: '#app',
data: {
firstName: '张',
lastName: '三',
numbers: {
a: 1,
b: 2
}
},
methods: {
fullName() {
return this.firstName + '-' + this.lastName
}
},
})
</script>

通过fullName()函数来返回全名。

计算属性

前面我们知道通过插值语法里面的内容可以直接写表达式,但是如果表达式过于复杂,我们并不推荐还直接在里面进行书写,在Vue官网中也提到了,于是我们就需要一个专门的地方进行计算,这就是computed

写法如下:

1
2
3
4
5
<div id="app">
姓:<input v-model="firstName" /> <br />
名:<input v-model="lastName" /> <br />
全名:<span>{{fullName}}</span>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script type="text/javascript">
Vue.config.productionTip = false;
const vm = new Vue({
el: '#app',
data: {
firstName: '张',
lastName: '三',
numbers: {
a: 1,
b: 2
}
},
computed: {
fullName: function () {
return this.firstName + '-' + this.lastName
}
},
</script>

姓和名被拼接起来展示到屏幕上了。

我们也可以如下写:

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
<script type="text/javascript">
Vue.config.productionTip = false;
const vm = new Vue({

el: '#app',
data: {
firstName: '张',
lastName: '三',
numbers: {
a: 1,
b: 2
}
},
computed: {
fullName: {
get() {
return this.firstName + '-' + this.lastName
},
//set() {

//}
}
},
})
</script>

如果我们不需要改变fullName的值的时候就可以使用第一种简写的方式,但是需要改变fullName的值的时候就需要采用第二种了。

看到这里我们是不是发现似乎computed能做的,好像methods也能做,为什么还要computed呢?这里我们可以看官网的解释是这样说的:两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要message还没有发生改变,多次访问reversedMessage计算属性会立即返回之前的计算结果,而不必再次执行函数。

这也同样意味着下面的计算属性将不再更新,因为Date.now()不是响应式依赖:

1
2
3
4
5
computed: {
now: function () {
return Date.now()
}
}

相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。

我们为什么需要缓存?假设我们有一个性能开销比较大的计算属性A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于A。如果没有缓存,我们将不可避免的多次执行A的 getter!如果你不希望有缓存,请用方法来替代。

如果还需要更多详细的内容可以参考计算属性和侦听器 — Vue.js (vuejs.org)