Vue.js 系列教程 3:Vue-cli,生命周期钩子

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

译者:nzbinhtml

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

系列文章:

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

Vue-cli 和构建过程

若是你尚未读过上一部分关于 Vue.js 组件和 props 的内容,我强烈建议你在读这篇文章以前先读读上一部分,另外,部份内容缺少语境。node

Vue 提供了一个好用的 命令行工具 ,你能够选择一些构建工具启动项目, 还提供了简单的启动模板。这是个很是好的工具。在安装 vue-cli 以前,须要检查 node 的版本,以及升级 npm 或者 yarn 。首先要安装 vue-cli ( -g 表示全局安装 )webpack

$ npm install -g vue-cligit

有多种构建工具可供选择,可是在咱们的例子中将使用 webpack:github

$ vue init webpack <project-name>web

能够经过命令行进入目录安装全部内容,设置 `package.json` 文件,而后经过如下命令在 localhost:8080 端口启动本地服务:vue-cli

$ npm run devnpm

程序运行成功!我喜欢这种简单的设置。你能够从 `/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>

See the Pen lifecycle hooks shown in a child component by Sarah Drasner (@sdras) on CodePen.

注意咱们在这里使用了 v-if 而没有使用 v-show ,由于 v-if 会真实的建立或者销毁组件,而 v-show 只是切换可见性(组件仍然存在于 DOM 中)。一样的, <keep-alive></keep-alive> 也不会建立或者销毁, 而是激活或停用—— 由于组件仍然存在,只是没有使用。

正如组件中的方法会自动绑定 this,生命周期钩子也会自动绑定实例,因此可使用组件的状态和方法。仍然不须要经过 console.log 查看 this 的指向! *heartiest eyes* 尽管如此,你不该该在生命周期方法中使用箭头函数,由于它会绑定父类上下文,而不是 Vue 实例。

在下面的例子中,当组件最初被建立时,会有大量的元素被移动,因此我将使用 mounted 钩子函数为每个组件触发相应的动画。你能够点击右下角的 return 按钮来看启动动画。

See the Pen Vue Weather Notifier by Sarah Drasner (@sdras) on CodePen.

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 中介绍它们,以及为何及什么时候使用。

相关文章
相关标签/搜索