Vue.js 系列教程 3:Vue
原文:intro-to-vue-3-vue-cli-lifecycle-hooks
译者:nzbin
这是 JavaScript 框架 Vue.js 五篇教程的第三部分。在这一部分,我们将学习 Vue-cli ,还会涉及真实的开发流程。这个系列教程并不是一个完整的用户手册,而是通过基础知识让你快速了解 Vuejs 以及它的用途。
系列文章:
- 渲染, 指令, 事件
- 组件, Props, Slots
- Vue-cli (你在这!)
- Vuex
- 动画
Vue-cli 和构建过程
如果你还没有读过上一部分关于 Vue.js 组件和 props 的内容,我强烈建议你在读这篇文章之前先读读上一部分,另外,部分内容缺乏语境。
Vue 提供了一个好用的 命令行工具 ,你可以选择一些构建工具启动项目, 还提供了简单的启动模板。这是个非常好的工具。在安装 vue-cli 之前,需要检查 node 的版本,以及升级 npm 或者 yarn 。首先要安装 vue-cli ( -g 表示全局安装 )
$ npm install -g vue-cli
有多种构建工具可供选择,但是在我们的例子中将使用 webpack:
$ vue init webpack <project-name>
可以通过命令行进入目录安装所有内容,设置 `package.json` 文件,然后通过以下命令在 localhost:8080 端口启动本地服务:
$ npm run dev
程序运行成功!我喜欢这种简单的设置。你可以从 `/src/` 目录下的 APP 文件以及 `/components/`目录下的 `Hello.vue`文件开始项目。这非常好,因为你已经看到如何建立文件,以及如何进行文件的导入导出。
先看一下 `.vue` 这个文件扩展名,因为你还没有使用过 vue,所以你之前也没有遇到这种文件。
在 `.vue` 文件中,可以放任何组件内容。我们不需要再用 <script type="text/x-template">
包裹模板,现在我们将按下面的逻辑创建更具有语义化的文件:
<template>
<div>
<!-- Write your HTML with Vue in here -->
</div>
</template> <script>
export default {
// Write your Vue component logic here
}
</script> <style scoped>
/* Write your styles for the component in here */
</style>
我针对 Sublime Text 建立了一个 Vue snippets 的仓库 ,可以针对 `.vue` 文件快速生成上述模板 ( 这是 vbase
snippet 输出的 )。 这个 是针对 atom 的 ( 它指出 Vue 需要 1+ 的版本,而 Vue 现在是 v2),还有 这个 是针对 vscode 的。
这里要注意的几件事: 和 React 一样,必须返回一个闭合的标签,在这里我使用一个 div 。在SVG中我也使用 <g>
元素。任何标签都可以,但是整个模板必须包裹在一个标签中。
你注意到我们在这里将使用 export default
编写脚本,比如之前使用的 data function 或者 methods ,但是如果我们想在这个 `.vue` 文件中使用子组件,我们需要导入 import 它们 ( 之后详细介绍 )。
你也会注意到在样式标签中有一个特殊的 scoped
属性值。这使我们能够很容易地将此组件的样式仅限于此组件。我们也会使用 <style>
,它将创建整个程序的样式。我通常会为应用程序创建一个通用的样式表,包括像 fonts 和 line-heights 的共同样式, 所以我将借助 vue-style-loader 导入 @import
到 App.vue 文件的 <style>
标签中。我也会使用 <style scoped>
标签为模板制定特殊的样式,但是只对当前模板有效! Vue-cli 的好处就是让你自己决定如何组织文件,而且你不必添加其它的依赖或模块来限制样式的作用范围。
之前简答地介绍了 slots ,当我们在 Vue 组件中通过局部样式标签使用 slots 时,它们适用于具有 slots 的组件。这是非常有用的,因为你可以很容易地切换组件和改变样式。
在开发过程中,使用特殊的 `.vue` 文件来组织 HTML,styles 和 JS 非常有帮助。我喜欢完全分离的方式,可以很清楚地看到每一部分,我还不适应这种紧密联系在一起的方式。它可以加快我的开发,而且我发现这种标记语言是语义化的。
你可能注意到语法高亮并不能自动识别 `.vue` 文件,所以我在 Sublime Text 中安装了 这个 。
下面是将组件 导入/导出 文件的基本方式 ( 在 vue-sublime snippets 中是 vimport:c ):
import New from './components/New.vue'; export default {
components: {
appNew: New
}
}
举一个生活中的例子,看一下上次我们用过的酒瓶标签的案例,它的组件有两个独立的模板:
App.vue:
<template>
<div class="container"> <main>
<component :is="selected">
<svg class="winebottle" aria-labelledby="title" xmlns="http://www.w3.org/2000/svg" viewBox="0 155 140 300">
...
</svg>
</component>
</main> <aside>
<h4>Name your Wine</h4>
<input v-model="label" maxlength="18">
<div class="button-row">
<h4>Color</h4>
<button @click="selected ='appBlack', labelColor = '#000000'">Black Label</button>
<button @click="selected ='appWhite', labelColor = '#ffffff'">White Label</button>
<input type="color" v-model="labelColor" defaultValue="#ff0000">
</div>
</aside> </div>
</template> <script>
import Black from './components/Black.vue'
import White from './components/White.vue'
...
export default {
data: function () {
return {
selected: 'appBlack',
label: 'Label Name',
...
};
},
components: {
appBlack: Black,
appWhite: White,
...
}
}
</script> <style>
@import "./assets/style.css";
</style>
黑色组件:
<template>
<div>
<slot></slot>
</div>
</template> <style scoped>
.label {
fill: black;
}
.bottle, .wine-text {
fill: white;
}
.flor {
fill: #ccc;
}
.bkimg {
filter:url(#inverse)
}
</style>
注意我在这里给组件中的 slot 设置了不同的样式,这是很好的工作方式,但这只是一种方法。通过 components,slots 和 props 构建程序的方法还有很多。这里的代码也只显示了部分内容。我建立了该示例的 仓库 ,使用 Vue-cli 构建的。为了熟悉工作流程,我强烈建议使用 Vue-cli 构建组件以及通过 props 传递状态。只要完成初始设置,这种方式直观而且快速。
生命周期钩子
在讨论生命周期钩子之前,需要回顾一下我在第一篇文章中提到的虚拟 DOM。我提到 Vue.js 具有虚拟 DOM,但没有说明它的用途。
当你使用像 jQuery 的框架工作时,你可能听说过 DOM 并且通过 DOM 更新改变内容。最后,我们花了大量的时间来检查 DOM 在做什么并存储状态。相反,虚拟 DOM 是 DOM 的抽象表示,有点像复制品,但在这种情况下,它将是主副本。在这个系列文章中,当我们用 Vue 的方式使用状态时,我们创建状态并观察状态的更新。
当一个 Vue 实例更新后,Vue 将会检查它是否与之前的有不同之处。如果确实有不同,Vue 将会调用生命周期的方法,更新 DOM 变化的部分。这是为了提高效率,这种方式下,DOM 只更新需要的部分。
生命周期钩子提供了一些 方法 ,因此你可以在组件生命周期的不同时刻精确地触发某些操作。当我们将组件实例化时,组件会被创建,反之会被销毁,比如当我们使用 v-if/v-else 指令切换时。
可以使用的钩子有: beforeCreate, created, beforeMount, mounted, beforeUpdate, updated, activated, deactivated, beforeDestroy
, destroyed
。如果你想深入了解,可以看看 介绍每种方法 的 API 文档。下面的小例子展示了部分工作原理(检查控制台):
const Child = {
template: '#childarea',
beforeCreate() {
console.log("beforeCreate!");
},
...
}; new Vue({
el: '#app',
data() {
return {
isShowing: false
}
},
methods: {
toggleShow() {
this.isShowing = !this.isShowing;
}
},
components: {
appChild: Child
}
});
<div v-if="isShowing">
<app-child></app-child>
</div>
注意我们在这里使用了 v-if
而没有使用 v-show
,因为 v-if
会真实的创建或者销毁组件,而 v-show
只是切换可见性(组件仍然存在于 DOM 中)。同样的, <keep-alive></keep-alive>
也不会创建或者销毁, 而是激活或停用—— 因为组件仍然存在,只是没有使用。
正如组件中的方法会自动绑定 this,生命周期钩子也会自动绑定实例,所以可以使用组件的状态和方法。仍然不需要通过 console.log 查看 this
的指向! *heartiest eyes* 尽管如此,你不应该在生命周期方法中使用箭头函数,因为它会绑定父类上下文,而不是 Vue 实例。
在下面的例子中,当组件最初被创建时,会有大量的元素被移动,所以我将使用 mounted 钩子函数为每一个组件触发相应的动画。你可以点击右下角的 return 按钮来看启动动画。
mounted() {
let audio = new Audio('https://s3-us-west-2.amazonaws.com/s.cdpn.io/28963/rain.mp3'),
tl = new TimelineMax(); audio.play();
tl.add("drops"); //drops in
tl.staggerFromTo("#droplet-groups g path", 0.3, {
drawSVG: "0% -10%"
}, {
drawSVG: "100% 110%",
repeat: 3,
repeatDelay: 1,
ease: Sine.easeIn
}, 0.5, "drops");
…
}
在这个例子中我使用了很多 Vue 提供的漂亮且复杂的 <transition>
和 <transition-group>
组件,我将在系列文章的最后一部分 Animation 中介绍它们,以及为什么及何时使用。
Vue.js 系列教程 3:Vue的更多相关文章
- Vue.js系列(一):Vue项目创建详解
引言 Vue.js作为目前最热门最具前景的前端框架之一,其提供了一种帮助我们快速构建并开发前端项目的新的思维模式.本文旨在帮助大家认识Vue.js,并详细介绍使用vue-cli脚手架工具快速的构建Vu ...
- Vue.js 系列教程 ②
这是关于 JavaScript 框架 Vue.js 五个教程的第二部分.在这一部分,我们将学习组件,Props 以及 Slots.这不是一个完整的指南,而是基础知识的概述,所以你可以了解Vue.js ...
- Vue.js 系列教程 3:Vue-cli,生命周期钩子
原文:intro-to-vue-3-vue-cli-lifecycle-hooks 译者:nzbin 这是 JavaScript 框架 Vue.js 五篇教程的第三部分.在这一部分,我们将学习 Vue ...
- Vue.js 系列教程 4:Vuex
这是关于 JavaScript 框架 Vue.js 五个教程的第四部分.在这一部分,我们会学习使用 Vuex 进行状态管理. 这不是一个完整的指南,而是基础知识的概述,所以你可以了解 Vue.js 以 ...
- Vue.js 系列教程 5:动画
原文:intro-to-vue-5-animations 译者:nzbin 译者的话:经过两周的努力,终于完成了这个系列的翻译,由于时间因素及个人水平有限,并没有详细的校对,其中仍然有很多不易理解的地 ...
- Vue.js 系列教程 2:组件,Props,Slots
原文:intro-to-vue-2-components-props-slots 译者:nzbin 这是关于 JavaScript 框架 Vue.js 五个教程的第二部分.在这一部分,我们将学习组件, ...
- Vue.js系列之一初识Vue
在看vue.js之前,可以先看这两篇文章,对于为什么要使用vue会有一定帮助 1.Vue.js !important 2.界面之下:还原真实的MV*模式 !important 3.web前端优化之re ...
- Vue.js系列之二Vue实例
每个Vue应用都是通过Vue函数创建一个新的Vue实例开始,代码如下: var vm=new Vue({}); {}是创建Vue应用时的参数对象 1.Vue实例的data属性 当一个Vue对象被创建时 ...
- Vue.js 系列教程 ①
原文:intro-to-vue-1-rendering-directives-events 译者:nzbin 如果要我用一句话描述使用 Vue 的经历,我可能会说“它如此合乎常理”或者“它提供给我需要 ...
随机推荐
- Linux type命令的用法
一般情况下,type命令被用于判断另外一个命令是否是内置命令,但是它实际上有更多的用法. 1.判断一个名字当前是否是alias.keyword.function.builtin.file或者什么都不是 ...
- css3中新增的样式使用方法
在PC版开发中由于IE原因,我们很少用到css3,但随着平板和智能手机进入我们的生活,以及现在越来越流行,在手机版和平板版开发中我们就可以大胆的使用了,下面我们探讨常用几个css3属性: 1.css3 ...
- C.Fountains(Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2)+线段树+RMQ)
题目链接:http://codeforces.com/contest/799/problem/C 题目: 题意: 给你n种喷泉的价格和漂亮值,这n种喷泉题目指定用钻石或现金支付(分别用D和C表示),C ...
- 四. Jmeter--JDBC 请求
一, SQLserver 1.下载 JDBC Driver (sqljdbc_6.0.8112.100_enu.exe) https://www.microsoft.com/en-us/downlo ...
- 转: oracle中schema指的是什么?
看来有的人还是对schema的真正含义不太理解,现在我再次整理了一下,希望对大家有所帮助. 我们先来看一下他们的定义:A schema is a collection of database obje ...
- python操作上级子文件
. └── folder ├── data │ └── data.txt └── test1 └── test2 └── test.py import os '***获取当前目录***'print o ...
- 在shell中如何判断字符串是否为有效的IP地址【转】
转自 在shell中如何判断字符串是否为有效的IP地址_echoisecho_新浪博客http://blog.sina.com.cn/s/blog_53a844e50100xxus.html 近来需要 ...
- openjudge-NOI 2.6-1759 最长上升子序列
题目链接:http://noi.openjudge.cn/ch0206/1759/ 题解: 奇怪……之前博客里的o(nlogn)标程在codevs和tyvj上都能AC,偏偏它这里不行 #include ...
- caffe Python API 之Model训练
# 训练设置 # 使用GPU caffe.set_device(gpu_id) # 若不设置,默认为0 caffe.set_mode_gpu() # 使用CPU caffe.set_mode_cpu( ...
- 关于linux环境下crontab命令环境变量的问题
这几天在弄数据库备份的事情,其中涉及到使用crontab命令自动执行shell脚本的问题,发现将写好的数据库导出脚本export.sh ################################ ...