Vuejs常用于快速构建单页应用,容易上手,其学习成本相对于Angular、React等要低。Vuejs最简单的用法是直接在页面用script标签加载独立包,独立包分为开发版本(Development Version)和生产版本(Production Version),区别在于前者包含非常友好的错误提醒方便debug,建议在开发环境使用前者、生产环境更换成后者,我们会在接下来的实践中体验这个Debug Mode。

初步认识Vuejs三例子

下面我们先通过三个简单的例子来初步认识一下Vuejs的概貌,你也可以在Vuejs的官网上查看到。学习Vuejs,甚至不管哪一门技术,你都不需要正儿八经地把它的教程和API先啃一遍, 先把最核心基础的搞定,然后通过实战边学边查,这样印象会更加深刻、更有效率。而这个三个例子是你的必经之路。

1、经典的hello world

1
2
3
4
<!-- 这里建议使用v-text代替{{}} -->
<div id="app">
{{ message }}
</div>
1
2
3
4
5
6
var App = new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
}
})

el,为实例挂载元素;data,实例的数据对象。上面html中有个建议,也就是改成<div id="app" v-text="message"></div>,这样做可以避免出现双向绑定未处理时的状态。所以,你也可以有两种默认值的写法:

1
2
3
<div id="app">
{{ message?message:'hello world!' }}
</div>
1
<div id="app" v-text="message?message:'hello world!'"></div>

2、双向绑定

1
2
3
4
<div id="app">
<p>{{ message }}</p>
<input v-model="message">
</div>
1
2
3
4
5
6
var App = new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
}
})

对于这种输入框有两个常用的和性能有关的特性,lazy和debounce。你可能不需要每次敲击的时候都需要同步输入框里的值,特别是输入一条路径显示一张图片或者是输入提示中的Ajax请求,这可能是一个高消耗的操作。所以你可以这样:

1
2
3
4
5
<!-- 改到change事件中同步 -->
<input v-model="message" lazy>

<!-- 设置延时同步时间 -->
<input v-model="message" debounce="500">

3、简单的todolist

1
2
3
4
5
6
7
8
9
<div id="app">
<input v-model="newTodo" v-on:keyup.enter="addTodo">
<ul>
<li v-for="todo in todos">
<span>{{ todo.text }}</span>
<button v-on:click="removeTodo($index)">X</button>
</li>
</ul>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var App = new Vue({
el: '#app',
data: {
newTodo: '',
todos: [
{ text: 'Add some todos' }
]
},
methods: {
addTodo: function () {
var text = this.newTodo.trim()
if (text) {
this.todos.push({ text: text })
this.newTodo = ''
}
},
removeTodo: function (index) {
this.todos.splice(index, 1)
}
}
})

通过这个例子,我们了解到通过v-for来渲染列表,这个和很多模版引擎非常相似;另外,也认识到了除el、data外又一个重要属性methods,它里面可以定义各种你想要的方法。在v-for模块里,它自带了一个非常方便的索引$index。但最重要的还是,它由数据驱动视图更新的这个思想。稍作加工和改进,你可以为自己量身定做一个todolist,如vue官方github的例子:TodoMvc。如果你还不知道localstorage怎么投入实践,通过这个例子,你也可以加深印象。

实例生命周期

每一个vue实例都有自己的生命周期,在生命周期的不同阶段,你可以通过调用生命周期钩子来实现一些操作。以一个例子来认识一下vue实例的生命周期:

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
var vm = new Vue({
// el: '#app',
data: {
a: 1
},
created: function () {
console.log('created')
},
beforeCompile: function(){
console.log('beforeCompile')
},
compile: function(){
console.log('compile')
},
ready: function(){
console.log('ready')
},
beforeDestroy: function(){
console.log('beforeDestroy')
},
destroyed: function(){
console.log('destroyed')
}
})
// vm.$destroy();

至此,我们再来安利一个Vue小工具:Vue实战-邮箱签名设计项目,项目地址:https://sign.aotu.io/,Github源码:https://github.com/o2team/sign

作者做成了一个Hexo主题的形式来发布项目,所以你会看到项目目录貌似有点复杂,但了解Hexo的话,你很容易就能抽取出Vue.js的部分,你只需要看index.ejs和sign.js两个文件就可以了。

从大体上来看,它就是下面这样一个Vue实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
var sign = new Vue({
el: 'app',
data: {
...
},
ready: function(){
...
},
methods: function(){
...
}

})

另外,它再使用了Vue filter过滤器(常用于输入的格式化)、Vue directive自定义指令,在methods中定义三个第三方工具的使用:DOM 转化为 IMG:dom-to-image、文件下载保存:FileSaver.js、个人头像裁切:cropperjs。拿来作为vue入门学习的案例之余还能学习三个很有用的小工具,可以看一看。

组件(Component)

脚手架Vue-cli

通常在一个实际的项目中,我们不会单纯地像上面那样像引进一个jquery那样就使用一个独立包来完成事情,到后期维护会很困难,需要进行模块化管理。你可以使用RequireJs或者SeaJs等进行模块化管理,但在这里直接使用ES6模块,这是一个趋势,而且你可以使用webpack进行打包和源码转换,妈妈再也不担心我的浏览器一脸萌逼。。。

使用脚手架工具 vue-cli 可以快速地构建项目,界面拆分为多个小组件,一个文件就是一个小组件,里面包含了它的 CSS 样式,模板和 JavaScript 定义。

安装和使用

1
2
3
4
5
npm install -g vue-cli
vue init webpack-simple my-project-simple
cd my-project
npm install
npm run dev

在初始化项目之前,根据个人喜好,安装最适合自己的模版,通过下面的命令,你可以查看现在的官方模版,在上面的的指令中,我们选择了webpack-simple模版。

1
vue list

项目初始化完毕,你需要看懂这个项目,如果你熟悉webpack、ES6,理解里面的东西将很容易。假如像我这样的小白,你可以先认识ES6 Module的导出export和导入import。

ES6倡导一个文件就是一个组件(模块),看下面的App.vue,你需要把它导出让别的文件能够使用,文件使用babel进行编译。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!-- App.vue -->
<template>
<div id="app">
<h1>{{ msg }}</h1>
</div>
</template>

<script>
export default {
data () {
return {
msg: 'Hello Vue!'
}
}
}
</script>


<style>
body {
font-family: Helvetica, sans-serif;
}
</style>

注意组件的data规定也是一个函数的形式,这和vue实例化的时候有点不一样。再对比遵循CommonJs范式的导出:

1
2
3
4
5
6
7
Module.exports = {
data: function(){
return {
msg: 'Hello Vue!'
}
}
}

组件的导入和使用:

1
2
3
4
5
6
7
import Vue from 'vue'
import App from './App.vue'

new Vue({
el: 'body',
components: { App }
})

至此,理解vue页面的组成没问题。这个模版剩下的就是webpack的东西了。如果选择了其他的模版,还可能有热加载、路由的设置,你需要再去看vue-loader、vue-router。

这里再放两个学习案例:这是一个碉堡了的教程goH5