三、使用 Vue CLI、组件、属性和插槽

上一章介绍了 Vue 的基本概念。我们将从更现实的方法开始本章:我们将介绍 Vue cli。我们将研究组件层次结构、全局和本地组件以及组件之间的通信。我们将介绍老虎机,我们还将研究老虎机和属性之间的区别

在本章中,我们将介绍以下主题:

  • Vue 组件层次结构以及全局和本地组件
  • 使用视图-CLI
  • 设置要与 Vue 一起使用的代码编辑器
  • 基于 Vue cli 的项目的结构
  • 向子组件添加基本功能
  • 为我们的HelloAgain.vue添加属性
  • 老虎机简介

Vue 组件层次结构以及全局和本地组件

正如我们在第 2 章Vue 2 的基本概念、中了解到的,为了运行一个新的 Vue 实例,我们使用了新的 Vue:

new Vue(
  el: "#app",
  // the rest of the Vue instance code here
)

我们的app组件驻留在此 Vue 实例中。

app 组件通常有一个子组件,就像我们在第 2 章Vue 2的基本概念:中看到的例子一样 https://codepen.io/AjdinImsirovic/pen/xzpOaJ

Vue.component('custom-article', {
  template: `
    <article>
      Our own custom article component!
    </article>`
})
new Vue({
    el: '#app'
})

我们在上一章中没有提到的是:

  • 子组件可以根据需要多次重用
  • 子组件也可以有自己的子组件

以下钢笔中提供了一个示例:https://codepen.io/AjdinImsirovic/pen/ZjdOdK

以下是演示这两个原则的代码:

// JS
Vue.component('custom-article', {
  template: `
    <article>
      Our own custom article component!
    </article>`
})
Vue.component('another-custom-article', {
  template: `
    <article>
      Another custom article component! 
      This one has it's own child component too!
      Here it is:
      <custom-article></custom-article>
    </article>`
})
new Vue({
    el: '#app'
})

/* CSS */
article {
  font-size: 40px;
  padding: 20px;
  color: limegreen;
  font-family: Arial;
  border: 3px solid green;
  border-radius: 10px;
}

<!-- HTML -->
<main id="app">
    <custom-article></custom-article>
    <custom-article></custom-article>
    <another-custom-article></another-custom-article>
</main>

如前所述,要将组件添加到我们的 Vue 实例中,我们将使用以下语法:

Vue.component('another-custom-article', { // etc...

在 Vue 术语中,我们使用此代码注册组件。如前所述,称为全球注册。还有本地注册

本地注册的工作原理与[T0]语法类似。代码中唯一的区别是,与全局组件相比,我们如何引入局部组件。在前面的代码中,我们有以下全局组件:

Vue.component('custom-article', {
  template: `
    <article>
      Our own custom article component!
    </article>`
})

将此全局组件转换为本地组件非常简单,只需删除以下代码片段:

Vue.component('custom-article'

与前面的代码不同,我们只需创建一个新变量,并为其提供与我们在全局组件中使用的完全相同的 options 对象,如下所示:

var customArticle = {
  template: `
    <article>
      Our own custom article component!
    </article>`
}

为了在我们的 Vue 实例中使用此本地组件,我们将引入components选项,如下所示:

new Vue({
    el: '#app',
    components: { 
      'custom-article': customArticle
    }
})

此处提供了一个带有本地组件的示例:https://codepen.io/AjdinImsirovic/pen/ZMzrpr

但是,前面的示例故意不完整。我们可以看到,customArticle本地组件仅在主 Vue 实例中可用,但在anotherCustomArticle组件中不可用。

要使这项工作正常并完成示例,我们需要调整以下代码:

Vue.component('another-custom-article', {
  template: `
    <article>
      Another custom article component! 
      This one has it's own child component too!
      Here it is:
      <custom-article></custom-article>
    </article>`,
    //components: {
    // 'customArticle': customArticle
    //}
})

我们将删除这三行上的注释:

    components: {
     'customArticle': customArticle
    }

这样,我们就在全局组件anotherCustomArticle中注册了本地组件customArticle。基本上,我们遵循在主 Vue 实例中注册本地组件的相同过程,并在anotherCustomArticle全局组件中应用注册本地组件的相同方法。

To get into the nuances of global and local registration, you can refer to this section of the official Vue documentation:   https://vuejs.org/v2/guide/components-registration.html.

在下一节中,我们将开始使用 Vue cli。

使用视图-CLI

为了开始使用 Vue cli,我们需要在机器上设置 Node.js,并且我们还需要在我们选择的操作系统上安装一个命令行应用程序。

例如,我首选的工具是 Windows 10 和 Git bash For Windows。

There are many different operating systems and command-line apps that you could potentially be using.

If you run into problems during the installation of any of the tools mentioned in this section, it might be worthwhile to have a look at this in-depth guide on installing Node.js on your operating system:

https://www.packtpub.com/mapt/book/web_development/9781788626859/2

安装 GitBash

您首先需要访问https://git-scm.com/downloads ,它允许您在 macOS X、Windows 和 Linux/Unix 安装之间进行选择。单击 Windows 下载后,可以继续 Git bash 的安装步骤。在安装过程中,只需遵循默认预设选项即可。

安装 nvm

要下载 Windows 节点版本管理器,请访问此链接: https://github.com/coreybutler/nvm-windows/releases

进入页面后,点击nvm-setup.zip文件下载,然后运行下载的nvm-setup.exe并完成常规安装步骤。

接下来,以管理员权限启动 Git bash 并运行以下命令:

nvm install 8.11.4

以下消息将记录到控制台:

Downloading node.js version 8.11.4 (64-bit)...

为什么要使用 nvm?

有两个主要原因:

  • 安全关键升级

  • 更容易在不同项目中的节点版本之间切换

这里列出的第一个原因与 Node.js 的未来更新有关。若在本书出版几个月后有一个主要的安全补丁,那个么更新系统上的节点将是明智的。使用 nvm 使这变得简单,这就引出了第二点。即使没有可供升级的 Node 的主要版本,您仍然可以根据将要处理的不同项目的需要运行不同版本的 Node。不管怎样,使用 nvm 都是值得的。

下载完成后,在 Git bash 中,我们只需运行以下命令:

nvm use 8.11.4

现在,我们可以使用 Vue cli 了。

安装和更新 Vue cli

值得注意的是,Vue cli 是一个围绕 Webpack 的包装器,它经过了调整和调整,因此在开发过程中以及将 Vue 应用程序发布到生产环境中时都能提供最佳体验。这对开发人员来说是一个很大的好处,因为这种设置让我们可以专注于编码,而不必长时间地使用工具链。

让我们打开 Git bash 并运行以下命令:

npm install -g vue-cli

由于 Vue cli 是一个npm包,因此您可以在此处阅读更多有关它的信息:https://www.npmjs.com/package/vue-cli

要检查系统上安装的 Vue cli 的当前版本,请运行以下命令:

vue -V

请注意,Vue cli 版本 2 和 3 之间进行了重大升级。要确保您使用的是系统上的最新版本,可以运行以下命令:

npm install @vue/cli

此命令将您的 Vue cli 版本更新为最新版本。更新是本地的,这意味着它将把它放在运行上一个命令的文件夹的node_modules文件夹中。请注意,由于需要安装所有依赖项,此操作可能需要一些时间。

在使用 Vue cli 初始化我们的项目之前,最好快速列出 Vue cli 版本 3 带来的改进。希望这将加强第 1 章介绍 Vue中关于 Vue 易用性的一些要点。

Vue cli 第 3 版的目标如下:

  • 简化和简化工具,避免前端开发的工具链疲劳
  • 遵循工具中的最佳实践,从而使其成为 Vue 应用程序的默认设置

Vue cli 的新版本还提供了一系列功能和升级:

  • 预设网页包配置,用于热模块更换、摇树等
  • ES2017 功能
  • 巴别塔 7 支持
  • 邮政编码支持
  • 可选集成 Typescript、PWA、Jest、E2E 测试等

简单地说,Vue.js 与时俱进,Vue cli 就是最好的证明。

使用 Vue cli 初始化新项目

安装后,我们可以使用以下命令初始化新项目:

vue create quickstart-vue

我们正在为我们的 Vue 应用程序命名为快速启动 Vue。我们不妨给它起个别的名字。

运行上述命令后,我们可以选择使用预设,或手动拾取要使用的功能:

$ vue create quickstart-vue
 ? Please pick a preset: (Use arrow keys)
 > default (babel, eslint)
 Manually select features

我们可以选择默认预设,但作为一个小练习,让我们选择手动选择功能选项。那么我们将选择npm而不是yarn。这将在屏幕上产生以下输出:

$ vue create quickstart-vue
 ? Please pick a preset: (Use arrow keys)
 ? Please pick a preset: default (babel, eslint)
 ? Pick the package manager to use when installing dependencies: (Use arrow keys)
 ? Pick the package manager to use when installing dependencies: NPM
Installing CLI plugins. This might take a while...

当您看到以下消息时,您将知道插件已安装:

...
Successfully created project quickstart-vue.
Get started with the following commands:
$ cd quickstart-vue
 $ npm run serve

现在我们只需按照前面的说明,切换到quickstart-vue目录:

cd quickstart-vue

接下来,我们将运行服务器(它实际上在后台运行一个 Webpack dev 服务器):

npm run serve

我们的应用程序在端口8080可用的消息将注销到控制台。那么,让我们在http://localhost:8080打开浏览器,看看默认站点:

在下一节中,我们将设置两个编辑器,用于新的 Vue 项目。这些编辑器是崇高的文本和 VisualStudio 代码。

设置要与 Vue 一起使用的代码编辑器

我们可以使用许多代码编辑器和IDE集成开发环境)与 Vue 一起工作。一些较受欢迎的方案包括:

  • 副标题 https://www.sublimetext.com/
  • Visual Studio 代码(VS 代码),.T0https://code.visualstudio.com/ T1

  • 原子,T0https://atom.io/ T1

  • 【网络风暴】https://www.jetbrains.com/webstorm/
  • Visual Studio 2017,“T0”https://visualstudio.microsoft.com/downloads/ T1

在本节中,我们将了解如何在 Sublime 文本和 VS 代码中使用 Vue.js。

在 Sublime Text 3 中使用 Vue.js

Sublime Text 是一个成熟而有趣的文本编辑器,因此我们将下载它并将其设置为与我们的 Vue.js 项目一起使用。

这是一篇精彩的文章 3

我们将从下载页面下载升华文本 3 开始: https://www.sublimetext.com/3

接下来,访问网站https://packagecontrol.io/ ,这是 Sublime 文本包管理器的所在地

安装软件包管理器

在 package manager 网站上,单击页面右上角的立即安装按钮,然后按照以下安装步骤进行操作:

  1. 选择并复制升华文本 3 选项卡内的所有文本。
  2. 打开新安装的升华文本 3。
  3. 在升华文本 3 内,按键盘快捷键Ctrl+`(按住并按 control,然后按 backtick 键)。在大多数键盘上,在键盘的字母数字部分,数字 1 的左边有反勾字符。
  4. 粘贴从复制的代码 https://packagecontrol.io 进入上一步打开的底部输入字段。

完成这些步骤后,重新启动 Sublime Text,您将可以通过以下快捷键访问快速启动安装程序:Ctrl+Shift+P

这个键盘组合将在屏幕中间显示一个小的输入,你可以在里面键入单词“Tyt0}”。这将显示不同的选项,您可以用鼠标单击或使用arrow uparrow down键高亮显示,然后使用Enter键运行:

接下来,选择读取包控制的选项:Install Package。

这是我们将安装的软件包列表:

Interestingly, the Chrome browser has recently received a similar quick-launch functionality, available via the same shortcut keys. To see it in action, you can simply open the developer tools utility with the F12 key and then run the Ctrl + Shift + P* shortcut keys.  For example, in the launcher that opens, you can type the word node, then click on the first command in the drop-down, Capture node screenshot. This command will capture a screenshot of the element you are currently on in the DOM tree of the DevTools.

  • A few months ago

在下一节中,我们将介绍如何在 VS 代码中设置基于 Vue 的项目。

在 VS 代码中使用 Vue.js

虽然升华文本具有成熟性和系统轻量级的优势,这使得它易于在较慢的机器上使用,但 VS 代码是一种可行的替代方案。

安装 VS 代码和扩展

让我们导航到https://code.visualstudio.com/download 并下载适用于我们操作系统的 VS 代码的相应版本。

If you are using Widows 10, you can easily see if your system is 32-bit or 64-bit. Simply use the shortcut keys Winkey + X, then click System in the contextual menu. A new window will open and you'll see whether your system is 32-bit or 64-bit in the Device Specifications | System type area.

一旦下载并打开 VS 代码,就可以很容易地向其添加扩展。只需单击屏幕左侧最底部的图标(扩展图标):

单击该图标将打开“扩展”窗格,您可以在其中键入 Vue 并返回类似以下内容的结果:

接下来,只需选择 Vue VS 代码扩展包,然后单击绿色的安装按钮。作为此包一部分的扩展包括语法高亮显示、代码片段、linting 和错误检查、格式设置(如 js beautify)、自动完成、悬停信息、自动重命名标记、对 VS 代码的 npm 支持、ES6 代码片段、ESLint 等。

Alternatively, if you want to avoid bloat in your VS Code extensions, you can reduce it somewhat by installing the Vetur extension by Pine Wu instead of the previously mentioned Vue extension pack.

一旦安装完成,我们可以简单地单击读为 Reload 的按钮重新启动 VS 代码并激活扩展。最后,要返回到项目的树结构,只需单击屏幕左侧最上面的图标,就在 VS 代码的主菜单下

基于 Vue cli 的项目的结构

在本节中,我们将查看使用 Vue cli 设置的 Vue 项目的文件结构。我们的quickstart-vue文件夹结构如下:

我们先来看看main.js文件的内容:

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App)
}).$mount('#app')

我们首先从vue文件夹导入Vue。此vue文件夹位于您的node_modules文件夹中

接下来,我们从App.vue导入App

正如我们已经了解到的,new Vue创建一个 Vue 实例,然后将 options 对象传递给它。

在 options 对象中,我们只设置了render属性。我们可以看到,render属性的值是一个箭头函数:

h => h(App)

arrow 函数接受我们在main.js文件第二行导入的App组件作为其参数。

正如您可能知道的,前面的函数是用 ES6 编写的。传输到 ES5 时,它将如下所示:

function(h) {
  return h(App);
}

前面的函数接收要渲染的 Vue 模板。它将呈现在哪里?它将在我们的index.html页面中呈现它,替换我们传递给$mount()函数的 DOM 的任何静态部分。

DOM 中的哪个位置取决于我们作为参数传递给$mount()函数的内容。在前面的代码中,我们传递了#app参数

'#app'来自哪里?它来自App组件,或者更具体地说,来自src文件夹中的App.vue文件。

src文件夹保存了我们 Vue 项目的所有实际应用程序代码

Note that main.js is the only actual JavaScript file in our project—all the files in the src folder have the .vue extension. Every .vue file has three parts: the template, the script, and the style tag. The template defines the HTML of the component, the script defines the JS, and the style tag defines the CSS. Also, Vue-cli (with Webpack under the hood) puts all of this together because it understands how to work with .vue files.

让我们更改src文件夹中的App.vue文件,使其如下所示:

<template>
  <div id="app">
    <HelloWorld msg="Welcome to Vue Quickstart!"/>
    <HelloAgain />
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue';
import HelloAgain from './components/HelloAgain.vue'

export default {
  name: 'app',
  components: {
    HelloWorld, HelloAgain
  }
}
</script>

<style>
#app {
  font-family: sans-serif;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

我们再修改一下HelloWorld.vue的内容,如下图:

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <p>
      This is the beginning of something great.
    </p>
 </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
p {
  font-size: 20px;
  font-weight: 600;
  text-align: center;
}
</style>

最后,让我们在src/components/文件夹中添加另一个组件。我们将其命名为HelloAgain.vue,我们将给它以下代码:

<template>
 <p class="hello-again">
 This is another component.
 </p>
</template>

<script>
export default {
 name: 'HelloAgain'
}
</script>

<style scoped>
p {
 font-size: 16px;
 text-align: center;
 color: tomato;
}
</style>

我们在这三个文件中所做的是,我们主要只是删除了一些额外的代码片段,以便更清楚地演示以下几点:

  • 每个vue文件都包含一个文件组件
  • 每个文件组件的结构遵循相同的模式:顶部的模板、中间的脚本和底部的样式。
  • 样式可以限定为每个单独的文件
  • App.vue文件从components文件夹导入组件并导出自身,以便main.js可以使用
  • HelloWorldHelloAgain组件只是将自己导出到父组件App.vue文件中
  • 为了使用新引入的组件(HelloAgain组件),App.vue文件需要将其添加到其<template>标记中
  • App.vue文件还需要导入和导出HelloAgain单文件模板,以便main.js可以使用

App.vue, HelloWorld.vue, and HelloAgain.vue are examples of single-file components. Single-file components are the preferred way of working with components in our Vue projects.

如果您已按照前面所述更改了文件,您的浏览器中应在http://localhost:8080处显示以下屏幕:

现在我们已经了解了vue/components/文件夹的组织方式及其基本工作原理,我们将列出 Vue 项目中的其他重要文件:

  1. Git 源代码版本控制不应跟踪的文件列表:.gitignore
  2. 巴别塔的配置文件:.babel.config.js 列出我们基于 npm 项目的依赖关系和其他信息的文件:*package.json 我们应用程序的降价手册:README.md*

****当然,还有一个公共文件夹,它包含我们编译的应用程序,引用自index.html文件。随着我们的 Vue 应用程序不断编译,index文件的内容非常简单:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title>quickstart-vue</title>
  </head>
  <body>
    <noscript>
      <strong>
        We're sorry but quickstart-vue doesn't work properly 
        without JavaScript enabled. Please enable it to continue.
      </strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

如前所述,id属性设置为appdiv是我们的 Vue 应用程序的入口点。

现在我们对项目结构有了更好的理解,我们将继续构建子组件。

在下一节中,我们将向HelloAgain组件添加一些基本功能。

向子组件添加基本功能

在本节中,我们将向子组件添加一些非常基本的功能。在详细介绍如何实现这一点之前,我们还需要安装正式的 Vue Chrome 扩展

用于 Chrome 的 Vue 开发者工具扩展可从以下 URL 获得:http://bit.ly/2Pkpk2I

安装官方 Vue Chrome 扩展非常简单;您只需像其他 Chrome 扩展一样安装它。

完成安装后,Chrome 的右上角区域将显示一个 Vue 徽标,单击该徽标将显示以下消息:

在此页面上检测到 Vue.js。打开 DevTools 并查找 Vue 面板。

打开 DevTools 很容易:只需按 F12 键。然后,您可以在包含以下选项卡的区域中找到 Vue 面板作为选项卡之一:元素、控制台、源等等。您应该会看到类似于以下屏幕的内容:

回到 VS 代码中,让我们打开HelloAgain.vue组件并更新代码的模板部分,使其如下所示:

<template>
 <p class="hello-again">
 This is another component.
 <button v-on:click="incrementUp">Add One</button>
 <br>
 <span>Current value of the counter: {{ counter }}</span>
 </p>
</template>

我们还要更新[T0]标记,如下所示:

<script>
export default {
 name: 'HelloAgain',
 data() {
     return {
         counter: 0
     }
 },
 methods: {
     incrementUp: function() {
         this.counter++
     }
 }
}
</script>

最后,我们将更新样式,使按钮看起来更漂亮:

<style scoped>
p {
 font-size: 16px;
 text-align: center;
 color: tomato;
}
button {
    display: block;
    margin: 10px auto;
    background: tomato;
    color: white;
    border: none;
    padding: 5px 10px;
    font-size: 16px;
    border-radius: 4px;
    cursor: pointer;
}
</style>

此更新的最终结果将在我们的浏览器中呈现,如下所示:

现在,我们已经了解了构建模板和使用一些基本功能,让我们将重点转移到另一个重要主题:组件之间的通信。我们将首先回顾属性,它是父组件和子组件之间进行通信的一种方式。

为我们的 HelloAgain.vue 添加属性

在本节中,我们将简要回顾属性,以了解如何在 Vue 中的父组件和子组件之间进行通信的一个实际示例。换句话说,我们希望从父组件获取一些数据并将其传递给子组件。我们将要传递的数据只是要包含在quickstart-vue应用程序计数器中的附加数字。

在“T0”文件中,我们将添加一个按钮:

<template>
  <div id="app">
    <HelloWorld msg="Welcome to Vue Quickstart!"/>
    <button v-on:click="addTen">Add 10</button>
    <HelloAgain v-bind:counterFromParent="countUp"/>
  </div>
</template>

按钮位于我们已经拥有的两个组件之间。我们添加了一个v-on指令,跟踪按钮上的点击事件。点击事件将触发addTen方法,因此我们将在App.vue文件的<script>标记之间指定它:

  methods: {
    addTen() {
      this.countUp += 10
    }
  },

addTen方法使用的是countUp段数据,所以我们也将此新数据添加到<script>中:

  data: function() {
    return {
      countUp: 0
    };
  },

因此,最初,App.vue中的data函数返回零的countUp。每当用户点击App.vue组件中的按钮,countUp的值增加 10。这个值是我们想要传递给子组件的数据,即传递给HelloAgain.vue子组件的数据。我们的目标是将来自父组件的数据添加到存储在子组件计数器中的值中。

这就是 props 语法的用武之地。为了向我们的HelloAgain.vue组件指定它应该期望来自父级的数据,我们将添加以下代码:

props: ['counterFromParent']

props键的值是一个数组,我们添加了子组件应该从父组件获得的属性字符串。

Note that the props option can also be an object. An example of using an object for our props option would be, for example, if we'd want to validate the data being passed from the parent to the child component. We will validate props in later chapters of this book.

仍然在HelloAgain.vue中,我们将更改其模板中的<span>标记,如下所示:

<span>Current value of the counter: {{ counter + counterFromParent }}</span>

现在我们已经在父级和子级中设置了代码,现在只需要将数据从一个传递到另一个。我们将在App.vue模板中通过将v-bind指令添加到<HelloAgain />标记中来实现这一点。以下是更新后的App.vue模板:

<template>
  <div id="app">
    <HelloWorld msg="Welcome to Vue Quickstart!"/>
    <button v-on:click="addTen">Add 10</button>
    <HelloAgain v-bind:counterFromParent="countUp"/>
  </div>
</template>

请注意,我们将counterFromParent绑定到countUp的值。countUp的值从零开始,每点击一次父按钮,就会运行addTen方法,我们在父<script>标签的methods选项中指定。

addTen方法将countUp的当前值加 10。

在子项方面,在HelloAgain.vue组件中,我们只需将counterFromParent的当前值添加到counter变量中。为了得到counterFromParent的值,我们将其列在HelloAgain.vue组件的<script>标签的props数组中。

将数据从子组件传递到父组件

要将数据从子组件传递到父组件,我们使用以下语法:

this.$emit();

$符号表示内置的 Vue 功能。此特定事件$emit用于向父级发送自定义事件。我们传递给$emit函数的第一个参数是自定义事件的名称。例如,我们可以将计数器重置为零,因此可以将自定义事件命名为:

this.$emit('counterHasBeenReset')

第二个参数是要传递的数据,因此我们将传递当前计数器值,如下所示:

this.$emit('counterHasBeenReset', this.countUp);

当然,这意味着我们需要更新countUp的值,使其返回到零。为此,我们需要更新HelloAgain子组件script标记中的methods选项,使其如下所示:

 methods: {
     incrementUp: function() {
         this.counter++
     },
     resetTheCounter() {
         this.countUp = 0;
         this.$emit('counterHasBeenReset', this.countUp);
     }
 }

基本上,我们在方法选项中说,无论何时运行resetTheCounter方法,countUp值都应该重置为0。接下来,我们通过在counterHasBeenReset定制事件中发出这个更新的值来跟进。

现在,让我们在子组件template标记中添加一个重置按钮,也在HelloAgain.vue中。我们只需在template标签上添加另一行即可:

<button v-on:click="resetTheCounter">Reset parent-added values</button>

正如我们在这里看到的,点击按钮将运行resetTheCounter方法。

现在我们正在发射事件,我们将使用以下语法在父组件中捕获它:

<HelloAgain v-bind:counterFromParent="countUp" v-on:counterHasBeenReset="countUp = $event" />

正如我们在这里看到的,我们已经在父组件中添加了<HelloAgain>标记。具体而言,我们增加了v-on指令如下:

v-on:counterHasBeenReset="countUp = $event" />

组件正在侦听counterHasBeenReset自定义事件,该事件将从子组件发出。当在父级中捕获此类事件时,countUp的值将被设置为事件本身中的任何值。既然我们已经把它设为零,那就是它的样子。

Vue 中的组件之间有其他通信方式(包括父到子和子到子),我们将在后面讨论 Vuex 时讨论这些方式。

此练习的最终结果是,我们将重置计数器中已从父组件添加的值,但该事件不会影响从子组件添加的值。

现在我们已经了解了自定义事件,我们可以通过查看插槽继续讨论组件。

老虎机简介

插槽是重用组件的一种方式。使用 props,我们将数据传递给组件。但是如果我们想把整个组件传递给其他组件呢?这就是吃角子老虎机的原因。

插槽只是将更复杂的代码传递给组件的一种方式。它们可以只是一些 HTML,甚至是整个组件。

要将 HTML 元素从父组件插入子组件,我们在子组件中使用slot元素:

<slot></slot>

插槽的实际内容在父组件中指定。

以下是正在使用的插槽示例:

<!-- HTML -->
<div id="app"></div>

// JS
Vue.component("basicComponent", {
  template: `
    <div>
      <slot name="firstSlot"></slot>
      <slot name="secondSlot"></slot>
      <slot></slot>
    </div>
  `
});

new Vue({
  el: "#app",
  template: `
    <basicComponent>
      <p slot="firstSlot">
        This content will populate the slot named 'firstSlot' 
        in the 'basicComponent' template
      </p>
      <p slot="secondSlot">
        This content will populate the slot named 'secondSlot' 
        in the 'basicComponent' template
      </p>
    </basicComponent>
  `
});

/* CSS */
div {
  font-size: 30px;
  padding: 20px;
  color: darkgoldenrod;
  font-family: Arial;
  border: 3px solid darkgoldenrod;
  border-radius: 0px;
}

此示例可在此处实时查看:https://codepen.io/AjdinImsirovic/pen/ERoLQM

使用插槽时有几个关键点:

  • 插槽是基于 web 组件的规范草案实现的
  • 插槽样式由子组件中的范围样式标记确定
  • 插槽支持使用可组合组件
  • 您可以在插槽中使用任何模板代码
  • 如果您有多个插槽,您可以命名它们(使用name属性)
  • 如果您有多个插槽,您可以在其中一个插槽中省略name属性,该插槽将成为默认插槽
  • 从 Vue 2.1.0 开始,插槽的作用域可以确定
  • 插槽范围可以使用 ES2015 表达式解构进行解构

要向插槽添加默认信息,只需向插槽标记添加内容即可。

只需更改插槽标记的代码即可:

<slot></slot>

并将其更改为:

<slot>This is some default information</slot>

如果您通过添加此行上方引用的默认未命名插槽代码来更新提供的示例笔,您将注意到插槽已填充,即使我们在 Vue 实例中没有引用它

总结

在本章中,我们介绍了 Vue 的组件。我们讨论了 Vue 组件层次结构以及全局组件和本地组件之间的差异。我们启动了 Vue cli v3 并学习了如何使用它。我们使用了.vue文件,并在几个代码编辑器中进行了开发。我们学习了向子组件添加功能以及属性和插槽的用例。最后,我们研究了 Vue 中的组件通信。

在下一章中,我们将讨论过滤器作为一种在不影响屏幕后面数据的情况下更改屏幕上呈现内容的方法。我们还将看到如何在 mixin 的帮助下坚持编程的干式规则。****