先说一句题外话,对于 Vue 的探索和应用我只服 ElemeFE
基础
软件工程学
代码风格
基本功
Vue.js 官方文档
ES6
Vue 三大特性
数据的双向绑定
通过数据绑定连接 View 和 Model, 让数据的变化自动映射为视图的更新。
数据驱动的组件系统
用嵌套的组件树来描述用户界面,每一个组件对应MVVM中的ViewModel。
基于构建工具的单文件组件系统
借助webpack强大的loader API,来定义对不同文件格式的预处理逻辑,从而将 vue 文件当作 javascript 模块来使用,从而极大提升了代码的可复用性。
开始
俗话说“工欲善其事必先利其器”,再往前递推,工欲利其器必先得其器。在进行一次 vue 项目的开发之前,如何将 vue 引入是我们面对的第一个问题。
这里我主要介绍两种引入方式。
传统的<script>
大法
遥想当年,在和jQuery一起玩耍的时候,在每撸一个页面之前,都会先把jq的cdn路径放在处于</body>
前的<script>
里面,因为这样做才可以和她愉快的玩耍。
虽说 jq 和 vue 不是一个概念(库 vs 框架),但是基于浏览器解析js的原理,两者可以用相同的方式引入。
npm install
NPM(Node Package Manager)是Node.js自带的一款包管理工具,只需要简单的在键盘上敲下 npm install *package name*
就可以将你需要的包安装至你的项目中,进而借助模块加载器就可以把她们引入到你的文件中。
当然,除了npm之外,还有其他的包管理工具,比如 bower 和 yarn,可以根据个人喜好进行选择。
不过值得一提的是,yarn 是 Facebook 推出的一款包管理工具,他们的工程师在使用 npm 的时候发现了很多需要改进的地方,为了达到预期的效果,打造了 yarn 这款工具。所以,如果你感兴趣,可以试试 yarn。
评估
对于上面两种方式的选择,你需要权衡一些因素:
如果你是尝试在已有的项目中添加一点新鲜的血液作为预研,建议选择
<script>
标签的形式如果你是在从零开始搭建一个 vue 项目,建议选择用包管理工具的方式
为什么需要构建
要回答这个问题,就要追溯到另外一个问题:在将代码发布到生产环境之前,我们还需要做什么?
如果能回答好这个问题,我们就会知道——到底为什么需要构建?
答案可以大致分为以下几种:
预处理
代码风格检测
资源压缩
静态资源替换
因为本文侧重点的关系,这里说一下预处理。
这又是另外一个问题了——为什么需要预处理?
因为无时不刻都在面临着浏览器的兼容问题,比如说ES6,一些语法糖写起来确实很爽,但是并不是所有浏览器都认识她;再者,React 的 jsx,Vue 的单文件,浏览器统统不认识,怎么办?只能预处理。
这里推荐 Vue 官方认证的好基友—— Webpack(其实我是gulp粉...)
如果你用的<script>
来引入Vue,不用关注这个问题,因为你已经协助浏览器进行了“在线编译”。
组件化
Vue 的 slogan 是:轻量高效的前端组件化方案。
这些年,伴随着 React 对 Web component 的不断实践与推动,组件化的思想被前端er们毫无抵触的接受,相比 React,个人认为 Vue 对组件化的解决方案更加优雅一些——借助构建工具的单文件组件系统。
在一个.vue
文件中,有三个主标签:<template>, <script>, <style>
,分别对应着当前组件的结构、交互逻辑和样式。
口说无凭,举个栗子
先来看看 React 的 JSX
render(){
let { item } = this.props;
let children;
if ( items.length > 0 ) {
children = (
<ul>
{ items.map( item =>
<li key={item.id}>{item.name}</li>
) }
</ul>
);
} else {
children = <p>No items found.</p>
}
return (
<div className = 'list-container'>
{ children }
</div>
);
}
其实看起来也不是多么的不堪,能够利用完整的 JavaScript 功能来构建视图页面,也是一件有意义的事情。
相同的业务逻辑,用 Vue 来写
<template>
<div class="list-container">
<ul v-if="items.length">
<li v-for="item in items">{{ item.name }}</li>
</ul>
<p v-else>No items found.</p>
</div>
</template>
是不是比 React 的 jsx 语法和内联样式优雅的多呢?
你需要做的就是根据业务逻辑组织好你的 components tree,接着搭配一款模块化方案,就能实现一个基于 Vue 的单文件组件系统啦。
当然,Vue 也同样支持 jsx 语法,你也不必非得采用单文件的组织形式,一切都取决于你的业务以及你的团队。
Vue Object
每个 Vue 实例在被创建之前都要经过一系列的初始过程。Vue 在这一周期中提供了一些钩子函数,这就给我么提供了执行自定义逻辑的机会。
Vue 是否有“控制器”的概念?
答: 没有。但是你可以将组件的自定义逻辑分布并实现在这些钩子函数中。 、
附上一张描述 Vue 对象生命周期的官方神图 ↓
做一下简单的翻译工作。
beforeCreate
在实例初始化之后,数据观测(data observer)和 event/watcher 事件配置之前被调用。
created
实例已经创建完成之后被调用。实例已经完成数据观测、属性和方法的运算、watch/event事件回调,但还没有开始挂载。
beforeMount
在挂在之前被调用
mounted
挂载之后
beforeUpdate
数据更新时调用,发生在 vdom 重新渲染和打补丁之前。
updated
由于数据更改导致的 vdom 重新渲染和打补丁,在这之后调用。
beforeDestroy
实例销毁之前调用。在这一步,实例仍然完全可用。
destroyed
实例销毁之后调用。
数据流 & 事件流
组装好了各个组件,你现在面临的问题是——如何让这些东西协同工作?
Props
props 是定义在子组件中的属性,用来定义期望从父组件传入的数据(在父组件中向子组件添加 v-bind 绑定属性即可)。
Event
使用
$on()
监听事件使用
$emit()
触发事件使用
$dispatch()
派发事件,沿父链冒泡使用
$broadcast()
广播事件,传导给所有的后代
有时候,你也许需要一个帮手—— vuex
当应用比较庞大,数据流和状态也会越发的难以管理和维护,这个时候你就需要 vuex 了。
21秒精通 Vue.js
接下来从一个新手司机的角度,总结一些可以帮助你快速上手 Vue 的小经验。
不要一上来就用 vue-cli
连手枪都没打过,你一上来就问我要他娘的意大利炮?(一个出自《亮剑》的梗)
vue-cli
是 Vue 官方推出的一款可以快速构建一个 vue app 的脚手架,各项配置也是全到没谁了。
但是,作为一个刚起步的选手,尤其是当你一开始要去搞的项目没那么复杂,还是不要用vue-cli
了,原因有以下两点:
如果你像我一样(对于构建玩的不是特别6),当你在
Terminal
按照指引敲击完几条命令之后,看着各种配置文件,肯定会一脸蒙蔽,会非常打击你的学习热情。更多的时候,你的项目可能还不需要用到如此完(yōng)整(zhǒng)的构建体系。
所以,自己动手搭一个吧,从最简单的开始,迟早有一天你也可以写出一个100%切合自己项目的脚手架。
你不仅需要ES6教程,还需要.babelrc
你是一个有理想的 JavaScript 开发者,你时刻关注着这门语言的发展趋势,终于有一天,你深深的迷恋上了ES6,她诸多的新特性都令你为之神往,所以你决定紧随她的脚步。
但事与愿违,很多浏览器在很大程度上并不认同这位姑娘,所以你需要作为中间人,让这些观念老旧的浏览器认识到新时代的风尚——这就是编译(此案例默认为预编译)。
通常情况下,我们在构建工具中引入babel
对自己的脚本进行语法上的转换,实现向后兼容。
比如在webpack.config.js
中引入这样的规则:
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'stage-0']
}
}
事实证明,在大多数情况下,这样是ok的。
但,当我们的项目是借助构建工具实现的单文件组件系统时,我们的 JavaScript 都写在了.vue
文件中,所以当你编译之后会得到一堆错误,这些错误都是在你使用ES6语法的地方出现的。
原因是因为我们用vue-loader
去处理.vue
文件,这本身没错。但是,vue-loader
用到了babel-loader
,却没有配置babel-loader
的地方,所以呢,gg。
查看官方文档,就会找到解决办法。
“babel-loader respects .babelrc, so it is the recommended approach to configure the Babel presets and plugins.”
参加这里。
综上,把 babel 相关配置放到 .babelrc 文件中去。
使用组建之前先注册
想上车?先买票!
组件 (Components) 是 Vue.js 最强大的功能之一。
如果你没有使用那个单文件组件系统,在使用组件的时候,你要这么做 ↓ (注册一个全局组件,Vue.component(tagName, options)
)
Vue.component('my-component',{
// options
});
组件在注册之后,便可以在父实例的模块中以自定义元素<mu-component></my-component>
的形式使用。
要确保在初始化根实例之前注册了组件:
<div id="example">
<my-component></my-component>
</div>
// 注册
Vue.component('my-component', {
template: '<p>Hello Vue component</p>'
});
// 创建根实例
new Vue({
el: '#example'
});
你也可以通过使用组件实例选项注册,可以使组件仅在另一个实例/组件的作用域中可用,这也是单文件组件系统的注册方式,即局部注册。
官方文档写的已经非常详细了,如果你仍然对这里有疑虑,给你一个传送门。
父子组件是怎么协同工作的?
父子组件的关系可以总结为 props down, events up。
父组件通过 props 向下传递数据给子组件,子组件通过 events 给父组件发送消息。
这就好比,老子给儿子生活费(props),儿子一有事就告诉老子:“爸,我没钱了”、“爸,有人打我”、“爸,我饿了”(events)。
让你更方便的调试 Vue
官方提供了一款 Chrome 插件,用于调试你的 Vue app —— Vue.js devtools。
最后
全文是从个人的视角出发,描述对 Vue 的认识以及在开发过程中一些问题的理解。
如果有不正确、或是与你理解有偏差的地方,希望你能指出这些问题,共同学习。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。