Vue.js 快跑:构建触手可及的高性能 Web 应用

第 1 章 Vue.js 基础

为什么选择 Vue.js

使用框架,项目代码可维护程度提高,简化了大部分工作。

使用 Ajax 下载一个列表数据并在页面上显示。

jQuery

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<ul class="js-items"></ul>

<script>
$(function(){
$.get('https://example.com/items.json')
.then(function(data){
ar $itemUL = $('.js-items');
if(! data.items.length){
var $noItems = $('li');
$noItems.text('Sorry,there are no items');
$itemsUl.append($noItems);
}else{
data.items.forEach(function(item){
var $newItem = $('li');
$newItem.text(item);
if(item.includes('blue')){
$newItem.addClass('is-blue');
}
$itemUl.append($newItem);
})
}
})
})
</script>

这段代码执行了以下逻辑:
1、使用 $.get() 发起 Ajax 请求。
2、选取类名为 .js-items 的元素并将它存入 $itemUl 变量。
3、如果下载的列表中没有列表项,则创建一个 li 元素,设置这个 li 元素的文本节点以表示当前没有列表项,然后将它添加到文档流中。
如果列表中存在列表项,则循环遍历每一个列表项。
4、为列表中的每一项创建一个li元素,并将其文本节点设置为该列表项的值。然后判断该列表项是否包含blue字符串,如果包含则将li元素的类名设置为is-blue。最后,将li元素添加到文档流中。

Vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<ul class='js-items'>
<li v-if='! items.length'> Sorry, there are no items. </li>
<li v-for="item in items" :class="{'is-blue': item.includes('blue')}">
{{item}}
</li>
</ul>

<script>
new Vue({
el: '.js-items',
data: {
items: []
},
created(){
fetch('https://example.com/items.json')
.then((res) => res.json())
.then((data) =>{
this.items = data.items;
})
}
})
</script>

这段代码执行了以下逻辑:
1、使用fetch()发起一个Ajax请求。
2、将返回的JSON数据解析为JavaScript对象。
3、将下载的列表项存储为data对象中的items属性。

vue-router 用于路由控制——根据应用的不同URL来显示不同的内容。
vuex 用于状态管理——通过一个全局数据中心在组件间共享数据。
vue-test-utils 用于 Vue 组件的单元测试。

安装和设置

安装 Vue 不需要任何特殊的工具,使用下面的代码就可以实现:

1
2
3
4
5
6
7
8
9
10
11
<div id="app">
</div>

<script>
new Vue({
el: '#app',
created(){
// 这段代码会在应用启动时运行
}
})
</script>

1、有一个 ID 为 app 的 div 元素用于初始化 Vue。
2、在页面上引用 CDN 版本的 Vue 文件,也可以下载到本地并引用。
3、运行一些 JavaScript 代码,创建一个 Vue 的实例,并将该实例的 el 属性指向之前提到的div元素。

vue-loader和webpack

vue-loader是一个webpack的加载器,允许组件的所有HTML、JavaScript和CSS代码编写到同一个文件中。

webpack

1
2
3
4
5
6
7
8
9
module: {
loaders: [
{
test: /\.vue$/,
loader: 'vue',
}
// ... 其他加载器 ...
]
}

如果还没有配置好 webpack 或者 不知如何添加vue-loader,可以使用一份现成的模板来初始化 Vue 项目。

Vue-cli

bach
1
2
$ npm install --global vue-cli
$ vue init webpack

依赖选择

模板(Template)、数据(Data)和指令(Directive)

Vue 的核心是将数据显示在页面上,这一功能通过模板实现。为正常的HTML添加特殊的属性——被称作指令——借助它来告诉 Vue 我们想要实现的效果以及如何处理提供给它的数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div id="app">
<p v-if="isMorning"> 早上好! </p>
<p v-if="isAfternoon"> 中午好! </p>
<p v-if="isEvening"> 晚上好! </p>
</div>
<script>
var hours = new Date().getHours();

new Vue({
el: '#app',
data: {
isMorning: hours < 12,
isAfternoon: hours >= 12 && hours < 18,
isEvening: hours >= 18
}
});
</script>

v-if

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div id="app">
<p v-if="hours < 12"> 早上好! </p>
<p v-if="hours >= 12 && hours < 18"> 中午好! </p>
<p v-if="hours >= 18"> 晚上好! </p>
</div>

<script>
new Vue({
el: '#app',
data: {
hours: new Date().getHours()
}
});
</script>

插值

1
2
3
4
5
6
7
8
9
10
11
12
<div id="app">
<p>Hello, {{ greetee }}! </p>
</div>

<script>
new Vue({
el: '#app',
data: {
greetee: 'world'
}
});
</script>

插值和指令结合

1
2
3
4
5
6
7
8
9
10
11
12
<div id="app">
<p v-if="path === '/'">你正位于首页</p>
<p v-else> 你正位于 {{ path }} </p>
</div>
<script>
new Vue({
el: '#app',
data: {
path: location.pathname
}
});
</script>

location.pathname 是当前页面URL的路径值。

传递数组或对象

1
2
3
4
5
6
7
8
9
10
11
12
13
<div id="app">
<p>第二条狗的名字是 {{ dogs[1] }}</p>
<p>所有狗的名字是 {{ dogs }} </p>
</div>

<script>
new Vue({
el: '#app',
data: {
dogs: ['Rex','Rover','Henrietta','Alan']
}
});
</script>

v-if vs v-show

v-if

1
2
<div v-if="true">one</div>
<div v-if="false">two</div>

输出内容

1
<div>one</div>

v-show

v-show 指令使用CSS样式控制元素的 显示/隐藏 。

1
2
<div v-show="true">one</div>
<div v-show="false">two</div>

输出内容

1
2
<div>one</div>
<div style='display: none'>two</div>

使用 v-if 隐藏的内部元素不会被显示,Vue 不会尝试生成对应的HTML代码;
意味着隐藏尚未加载的内容时,v-if 指令更好一些。

示例:抛出一个异常

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div id="app">
<div v-show="user">
<p>User name: {{ user.name }}</p>
</div>
</div>

<script>
new Vue({
el: '#app',
data: {
user: undefined
}
})

</script>

会抛出异常是因为 Vue 尝试执行user.name —— 一个尚不存在的对象的属性。在该示例中如果使用v-if就会正常工作,因为 Vue 直到v-if语句为真时才会去尝试生成元素的内部内容。

v-if v-else-if v-else

1
2
3
4
5
6
7
8
9
<div v-if="state === 'loading'">
加载中
</div>
<div v-else-if="state === 'error'">
出错了
</div>
<div v-else>
... 我们的内容!
</div>

使用 v-if 会有性能开销。每次插入或者移除元素时都必须要生成元素内部的 DOM 树,这在某些时候是非常大的工作量。而 v-show 除了在初始创建开销时之外没有额外的开销。如果希望频繁地切换某些内容,那么v-show会是最好的选择。

如果元素包含任何图片,那么仅使用CSS隐藏父节点可以使浏览器在图片显示之前就加载它,这意味着一旦v-show变为真值,图片就可以显示出来。如果是v-if指令,图片会直到要显示时才开始加载。

Vue.js 快跑:构建触手可及的高性能 Web 应用

http://example.com/2020/03/06/Book9/

作者

Fallen-down

发布于

2020-03-06

更新于

2020-08-01

许可协议

You need to set install_url to use ShareThis. Please set it in _config.yml.
You forgot to set the business or currency_code for Paypal. Please set it in _config.yml.

评论

You forgot to set the shortname for Disqus. Please set it in _config.yml.
You need to set client_id and slot_id to show this AD unit. Please set it in _config.yml.