原文:intro-to-vue-3-vue-cli-lifecycle-hooks

译者:nzbin

这是 JavaScript 框架 Vue.js 五篇教程的第三部分。在这一部分,我们将学习 Vue-cli ,还会涉及真实的开发流程。这个系列教程并不是一个完整的用户手册,而是通过基础知识让你快速了解 Vuejs 以及它的用途。

系列文章:

  1. 渲染, 指令, 事件
  2. 组件, Props, Slots
  3. Vue-cli (你在这!)
  4. Vuex
  5. 动画

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, beforeDestroydestroyed 。如果你想深入了解,可以看看 介绍每种方法 的 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 中介绍它们,以及为什么及何时使用。

最新文章

  1. LBS上传到百度地图
  2. 数据库高可用架构(MySQL、Oracle、MongoDB、Redis)
  3. anroid studio 找不到符号 位置: 类 drawable
  4. Why did Jimmy Wales invest in Quora? Is he afraid that it will take over Wikipedia?
  5. POJ 1811Prime Test(米勒拉宾素数测试)
  6. 关于ql createNativeQuery生成json数据
  7. 普通 Java 项目转换为 Maven 项目
  8. 基于vue的多引擎搜索及关键字提示
  9. 谷歌浏览器的各种插件网址Chrome插件(谷歌浏览器)-超级详细
  10. Buffer的工作方式
  11. 鼠标事件-MouseEvent
  12. git最佳实践之feature和hotfix分支
  13. Access无法启动应用程序,工作组信息文件丢失,或是已被其他用户已独占方式打开
  14. spring boot 当参数传入开头多个0时,报错:JSON parse error: Invalid numeric value: Leading zeroes not allowed
  15. 什么是wsgi,uwsgi,uWSGI
  16. HTTP Methods 和 RESTful Service API 设计
  17. ajax的基础
  18. MVC中导航菜单,选中项的高亮问题。
  19. [实战]MVC5+EF6+MySql企业网盘实战(2)——验证码
  20. FileUpload控件实现单按钮图片自动上传并带预览显示

热门文章

  1. Zepto学习笔记
  2. 响应式布局之媒体查询 @media
  3. spring bean初始化及销毁你必须要掌握的回调方法
  4. 【BZOJ】1798: [Ahoi2009]Seq 维护序列seq 线段树多标记(区间加+区间乘)
  5. python学习笔记(十)之格式化字符串
  6. 使用vscode实现git同步
  7. web deploy 安装失败解决
  8. Linux系统调优及安全设置
  9. GitHub vs GitLab:它们有什么区别?
  10. windows下phpstrom中xdebug的使用