扩展VueJS组件

您的Vue应用程序中是否有共享类似选项的组件,甚至模板标记?

使用公共选项和标记创建基本组件,然后扩展基本组件以创建子组件,这是一个好主意。这样的体系结构将帮助您在代码中应用DRY原则(不要重复您自己),这将使您的代码更具可读性,并减少错误的可能性。

Vue提供了一些功能来帮助组件继承,但是您还必须添加一些自己的独创性。

例如:调查问题

下面是Vue.js做的一个简单的调查:

1567386541329430.jpg-600

你会注意到每个问题都有不同的相关输入类型:

  1. 文本输入

  2. 选择输入

  3. Radio input

一个好的架构应该是将每个问题/输入类型转换成不同的、可重用的组件。我将它们命名为与上述相对应的:

  • SurveyInputText

  • SurveyInputSelect

  • SurveyInputRadio

每个问题/输入都是一个不同的组件,这是有意义的,因为每个问题都需要自己的标记(例如<input type="text"> vs <input type="radio">),而且每个问题都需要自己的道具、方法等等。然而,这些组件有很多共同之处:

  • 一个问题

  • 验证功能

  • 错误状态

等等。所以我认为这是扩展组件的一个很好的用例!

基础部分

每个子组件都将继承一个名为SurveyInputBase的文件组件。请注意以下几点:

问题道具在每个组件中都是通用的。我们可以添加更多常见的选项,但是在这个简单的示例中,我们只使用一个选项。

我们需要以某种方式将这些道具从这个组件复制到任何扩展组件。

我们需要为模板内的不同输入插入标记。

SurveyInputBase.vue

<template>
  <div class="survey-base">
    <h4>{{ question }}</h4>
    <!--the appropriate input should go here-->
  </div></template><script>
  export default {    props: [ 'question' ],
  }</script>

继承组件选择

暂时忘记模板,我们如何让每个子组件继承道具?每个人都需要问题作为道具,以及他们自己独特的道具:

2.jpg-600

这可以通过导入基本组件并使用extends选项指向它来实现:

SurveyInputText.vue

<template>
  <!--How to include the question here???-->
  <input :placeholder="placeholder"></template>
<script>import SurveyInputBase from './SurveyInputBase.vue';
  export
default {
    extends:
    SurveyInputBase,
    props: ['placeholder'],
  }</script>

查看Vue Devtools,我们可以看到使用extends确实为我们的子组件提供了基本的支持:

3.jpg-600

合并策略

您可能想知道子组件是如何继承问题支持而不是覆盖它的。extends选项实现了一个合并策略,该策略将确保正确组合选项。例如,如果这些道具有不同的名称,它们显然都会被包含进来,但是如果它们有相同的名称,Vue将优先选择子组件。

合并策略还可以与其他选项一起工作,比如方法、计算属性和生命周期钩子,并将它们与类似的逻辑组合起来。检查文档中关于Vue如何实现它的确切逻辑,但是如果需要,您可以定义自己的定制策略。

注意:还可以选择在组件中使用mixin属性而不是extends。不过,对于这个用例,我更喜欢extend,因为它有一个稍微不同的合并策略,赋予子组件选项更高的优先级。

扩展的模板

扩展组件的选项相当简单——但是模板呢?

合并策略不适用于模板选项。我们要么继承基本模板,要么定义一个新模板并覆盖它。但是我们如何把它们结合起来呢?

我的解决方案是使用Pug预处理器。它提供了包含和扩展选项,因此看起来非常适合这种设计模式。

基础组件

首先,我们将基本组件的模板转换为Pug语法:

<template lang="pug">
  div.survey-base
    h4 {{ question }}
    block input</template>

请注意以下几点:

  • 我们将lang="pug"添加到模板标记中,以告诉vue-loader将其作为pug模板处理(此外,不要忘记将pug模块以及npm i——save-dev pug添加到您的项目中)

  • 我们使用块输入为子组件内容声明一个outlet。

这里有点乱。如果我们想让我们的子组件扩展这个模板,我们需要把它放在自己的文件:

SurveyInputBase.pug

div.survey-base
  h4 {{ question }}
  block input

然后我们把这个文件包含在我们的基本组件中,这样它仍然可以作为一个正常的独立组件使用:

SurveyInputBase.vue

<template lang="pug">
  include SurveyInputBase.pug</template><script>
  export default {    props: [ 'question' ]
  }</script>

这样做很遗憾,因为它违背了“单文件”组件的目的,但是对于这个用例,我认为它是值得的。也许您可以定制一个webpack加载器来避免这样做。

子组件

现在让我们把我们的子组件的模板转换为Pug:

SurveyInputText.vue

<template lang="pug">
  extends SurveyInputBase.pug
  block input
    input(type="text" :placeholder="placeholder")</template><script>
  import SurveyInputBase from './SurveyInputBase.vue';  
export default {    extends: SurveyInputBase,    props: [ 'placeholder' ],
  }</script>

子组件使用Pug的extended特性,该特性包括基本组件并输出输入块中的任何自定义内容(这是一个与插槽无关的概念)。

下面是子组件的模板在扩展基础并被翻译回常规HTML Vue模板后的效果:

<div class="survey-base">
  <h4>{{ question }}</h4>
  <input type="text" :placeholder="placeholder"></div>

把所有的东西放在一起

使用这个策略,我们可以继续创建另外两个子组件SurveyInputSelect和SurveyInputRadio,它们都有自己的支持和标记。

如果我们在一个项目中使用它们,我们的主模板可能是这样的:

<survey-input-text
  question="1. What is your name?"
  placeholder="e.g. John Smith"></survey-input-text><survey-input-select
  question="2. What is your favorite UI framework?"
  :options="['React', 'Vue.js', 'Angular']"></survey-input-select><survey-input-radio
  question="3. What backend do you use?"
  :options="['Node.js', 'Laravel', 'Ruby']"
  name="backend"></survey-input-radio>

下面是呈现的标记:

<div class="survey-base">
  <h4>1. What is your name?</h4>
  <input type="text" placeholder="e.g. John Smith"></div><div class="survey-base">
  <h4>2. What is your favorite UI framework?</h4>
  <select>
    <option>React</option>
    <option>Vue.js</option>
    <option>Angular</option>
  </select></div><div class="survey-base">
  <h4>3. What backend do you use?</h4>
  <div><input type="radio" name="backend" value="Node.js">Node.js</div>
  <div><input type="radio" name="backend" value="Laravel">Laravel</div>
  <div><input type="radio" name="backend" value="Ruby">Ruby</div></div>

注意:我们也可以实例化SurveyInputBase组件,因为它可以独立工作,但是在这个例子中并不真正需要它。不过,我认为这一点很重要。

英文原文地址:https://vuejsdevelopers.com/2017/06/11/vue-js-extending-components/

以上就是扩展VueJS组件的详细内容,更多请关注0133技术站其它相关文章!

赞(0) 打赏
未经允许不得转载:0133技术站首页 » Vue.js 教程