vuejs添加html,扩展VueJS组件

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

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

3104022ff25bef720eb1bedde55402f9.png

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

例如:调查问题

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

b1a1b5fe0985188469037b15a9e8628c.png

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

选择输入

Radio input

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

SurveyInputSelect

SurveyInputRadio

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

验证功能

错误状态

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

基础部分

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

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

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

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

SurveyInputBase.vue

{{ question }}

继承组件选择

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

6a6ede54b81cdac2aafe0fa9697a3362.png

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

SurveyInputText.vue

export

default {

extends:

SurveyInputBase,

props: ['placeholder'],

}

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

fa52a98fb925e5de2170a525236b70ed.png

合并策略

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

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

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

扩展的模板

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

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

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

基础组件

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

div.survey-base

h4 {{ question }}

block input

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

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

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

SurveyInputBase.pugdiv.survey-base

h4 {{ question }}

block input

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

SurveyInputBase.vue

include SurveyInputBase.pug

export default { props: [ 'question' ]

}

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

子组件

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

SurveyInputText.vue

extends SurveyInputBase.pug

block input

input(type="text" :placeholder="placeholder")

import SurveyInputBase from './SurveyInputBase.vue';

export default { extends: SurveyInputBase, props: [ 'placeholder' ],

}

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

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

{{ question }}

把所有的东西放在一起

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

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

question="1. What is your name?"

placeholder="e.g. John Smith">

question="2. What is your favorite UI framework?"

:options="['React', 'Vue.js', 'Angular']">

question="3. What backend do you use?"

:options="['Node.js', 'Laravel', 'Ruby']"

name="backend">

下面是呈现的标记:

1. What is your name?
2. What is your favorite UI framework?

React

Vue.js

Angular

3. What backend do you use?
Node.js
Laravel
Ruby
注意:我们也可以实例化SurveyInputBase组件,因为它可以独立工作,但是在这个例子中并不真正需要它。不过,我认为这一点很重要。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值