vue如何编写可复用的组件步骤,vuejs 组件与复用

  vue如何编写可复用的组件步骤,vuejs 组件与复用

  本文主要介绍Vue组件的复用和扩展。对vue感兴趣的同学可以参考一下。

  

目录

  是否需要扩展组件概述slot JavaScript工具功能扩展组件组合的几种模式APImixin高级组件无渲染组件模板扩展

  

概述

  软件编程的一个重要原则是D.R.Y(不要重复自己),就是尽可能的重用代码和逻辑,减少重复。组件扩展可以避免代码重复,更易于快速开发和维护。那么,扩展Vue组件的最好方法是什么呢?

  Vue提供了许多API和模式来支持组件重用和扩展,您可以根据自己的目的和偏好进行选择。

  本文介绍几种常见的方法和模式,希望对你有所帮助。

  

扩展组件是否必要

  要知道,所有的组件扩展方法都会增加复杂度,额外的代码,有时还会增加性能消耗。

  因此,在决定扩展组件之前,最好看看是否有其他更简单的设计模式可以完成目标。

  以下组件设计模式通常足以替换扩展组件:

  道具协调模板逻辑

  插槽插槽

  JavaScript工具函数

  道具协调模板逻辑

  最简单的方法就是通过道具结合模板条件渲染实现组件的多功能。

  例如,通过类型属性:MyVersatileComponent.vue

  模板

  div class=wrapper

  div v-if=type===a ./div

  div v-else-if=type===b ./div

  !等等等等

  /div

  /模板

  脚本

  导出默认值{

  道具:{ type: String },

  .

  }

  /脚本

  使用组件时,通过传递不同的类型值可以获得不同的结果。

  //*ParentComponent.vue*

  模板

  MyVersatileComponent type=a /

  MyVersatileComponent type=b /

  /模板

  如果出现以下两种情况,说明该模式不适用,或者用法不正确:

  组件模式将状态和逻辑分解成原子部分,从而使应用程序具有可扩展性。如果组件中有大量的条件判断,可读性和可维护性就会变差。

  Props和模板逻辑旨在使组件动态化,但也存在运行时资源消耗。如果您使用这种机制来解决运行时的代码合成问题,它就是一种反模式。

  

slot(插槽)

  另一种避免组件扩展的方法是使用插槽,即让父组件在子组件中设置自定义内容。

  //*MyVersatileComponent.vue*

  模板

  div class=wrapper

  H3通用标记/div

  插槽/

  /div

  /模板

  //*ParentComponent.vue*

  模板

  MyVersatileComponent组件

  h4插入插槽/h4

  /MyVersatileComponent

  /模板

  渲染结果:

  div class=wrapper

  H3通用标记/div

  h4插入插槽/h4

  /div

  这种模式有一个潜在的约束,因为槽中的元素从属于父组件的上下文,所以分离逻辑和状态可能不自然。作用域slot将更加灵活,这将在后面不呈现组件的部分中提到。

  

JavaScript 工具函数

  如果只需要复用组件间的独立函数,只需要提取这些JavaScript模块,根本不需要使用组件扩展模式。

  JavaScript的模块系统是一种非常灵活和健壮的代码共享方式,所以你应该尽可能地依赖它。MyUtilityFunction.js

  导出默认函数(){

  .

  }

  我的组件. vue

  从“”导入MyUtilityFunction。/MyUtilityFunction ;

  导出默认值{

  方法:{

  我的效用函数

  }

  }

  

扩展组件的几种模式

  如果你考虑过以上简单的模型,但是这些模型不够灵活,无法满足需求。然后可以考虑扩展组件。

  有四种最流行的方法来扩展Vue组件:

  合成函数

  混入类

  高阶分量

  没有渲染组件

  每种方式都有其优缺点,根据使用场景也有或多或少的适用部分。

  

Composition API

  组件间共享状态和逻辑的最新方案是组合API。这是Vue 3推出的API,在Vue 2中也可以作为插件使用。

  与以前在组件定义配置对象中声明数据、计算、方法和其他属性的方式不同,组合API通过设置函数来声明和返回这些配置。

  例如,计数器组件是以Vue 2配置属性的方式声明的:Counter.vue

  模板

  按钮@click=增量

  计数为:{{ count }},双精度为:{{ double }}

  /按钮

  模板

  脚本

  导出默认值{

  数据:()=({

  计数:0

  }),

  方法:{

  增量(){

  this.count

  }

  },

  计算值:{

  double () {

  返回this . count * 2;

  }

  }

  }

  /脚本

  用Composition API重构这个组件有一模一样的功能:Counter.vue

  模板!-如上-模板

  脚本

  从“vue”导入{ reactive,computed };

  导出默认值{

  setup() {

  恒定状态=反应({

  计数:0,

  double:computed(()=state . count * 2)

  });

  函数增量(){

  状态.计数

  }

  返回{

  数数,

  双倍,

  增量

  }

  }

  }

  /脚本

  用Composition API声明组件的主要好处之一是逻辑重用和提取变得非常容易。

  进一步重构,将计数器的功能移到JavaScript模块useCounter.js: usecounter.js中。

  从“vue”导入{ reactive,computed };

  导出默认函数{

  恒定状态=反应({

  计数:0,

  double:computed(()=state . count * 2)

  });

  函数增量(){

  状态.计数

  }

  返回{

  数数,

  双倍,

  增量

  }

  }

  现在,计数器函数可以通过setup函数无缝地引入到任何Vue组件中:MyComponent.vue

  模板!-如上-/模板

  脚本

  从导入useCounter。/use counter ;

  导出默认值{

  setup() {

  const { count,double,increment }=use counter();

  返回{

  数数,

  双倍,

  增量

  }

  }

  }

  /脚本

  组合功能使功能模块化、可重用,是组件扩展最直接、成本最低的方式。

  组合API的缺点

  Composition API的缺点其实不算什么。3354可能看起来有点冗长,新用法对一些Vue开发者来说有点陌生。

  关于组合API优缺点的讨论,推荐阅读:何时使用新的vue组合API(以及何时不使用)

  

mixin

  如果你还在用Vue 2,或者只是喜欢通过配置对象来定义组件功能,可以使用mixin模式。Mixin将公共逻辑和状态提取到单独的对象中,并使用mixin将它们与组件的内部定义对象合并。

  让我们继续使用前面的Counter组件示例,将常见的逻辑和状态放入CounterMixin.js模块中。CounterMixin.js

  导出默认值{

  数据:()=({

  计数:0

  }),

  方法:{

  增量(){

  this.count

  }

  },

  计算值:{

  double () {

  返回this . count * 2;

  }

  }

  }

  使用mixins也很简单,只需要导入相应的模块,在mixins数组中添加变量即可。当组件初始化时,mixin对象将与组件的内部定义对象合并。我的组件. vue

  从导入计数器。/counter mixin ;

  导出默认值{

  米辛:[反米辛],

  方法:{

  减量(){

  this . count-;

  }

  }

  }

  选项合并

  组件中的选项和mixin冲突怎么办?

  比如给一个组件定义一个内置的增量方法,哪个优先级更高?我的组件. vue

  从导入计数器。/counter mixin ;

  导出默认值{

  米辛:[反米辛],

  方法:{

  //内置的increment `方法会覆盖mixin的增量吗?

  增量(){.}

  }

  }

  这是谈论Vue合并策略的时候了。Vue有一系列的规则来决定如何处理同名的选项。

  通常,组件附带的选项会覆盖mixin提供的选项。但是也有例外,比如同类型的生命周期挂钩。不是直接覆盖它们,而是全部放入一个数组,按顺序执行。

  您还可以通过自定义合并策略来更改默认行为。

  mixin的缺点

  作为一种扩展组件的模式,mixin非常适合简单的场景。一旦规模扩大,问题就来了。不仅要注意命名冲突(尤其是第三方mixin),而且很难搞清楚某个函数是从哪里来的,也很难定位问题。

  

高阶组件

  高阶分量(HOC)是从React借来的概念,Vue也可以用。

  为了理解这个概念,让我们抛开组件,看看两个简单的JavaScript函数,increment和double。

  函数增量(x) {

  返回x;

  }

  双(x)函数{

  返回x * 2;

  }

  假设我们想给这两个函数都添加一个函数:在控制台中输出结果。

  所以我们可以利用高阶函数模式创建一个新的addLogging函数,接受函数作为参数,返回一个有新函数的函数。

  函数添加日志记录(fn) {

  返回函数(x) {

  const结果=fn(x);

  console.log(结果为: ,result);

  返回结果;

  };

  }

  const incrementwithloging=add logging(increment);

  const doublewithloging=add logging(double);

  组件如何利用这种模式?类似地,我们创建一个高级组件来呈现计数器组件,并添加一个减量方法作为实例属性。

  实际代码相当复杂,所以这里只给出伪代码作为说明:

  从导入计数器。/Counter ;

  //伪代码

  const CounterWithDecrement=({

  渲染(createElement) {

  常量选项={

  减量(){

  this . count-;

  }

  }

  返回createElement(计数器,选项);

  }

  });

  HOC模式比mixin更简洁,可扩展性更强,但代价是增加了一个包组件,实现起来也需要技巧。

  

无渲染组件

  如果您需要在多个组件上使用相同的逻辑和状态,但以不同的方式显示,那么您可以考虑非呈现组件模式。

  该模式需要两种组件:声明逻辑和状态的逻辑组件,以及显示数据的表示组件。

  逻辑模块

  让我们回到计数器的例子。假设我们需要在多个地方重用这个组件,但是以不同的方式显示它。

  创建一个CounterRenderless.js来定义逻辑组件,包括逻辑和状态,但不包括模板。相反,通过render函数声明作用域槽。

  作用域slot向父组件公开了三个属性:状态计数、方法增量和计算属性double。CounterRenderless.js

  导出默认值{

  数据:()=({

  计数:0

  }),

  方法:{

  增量(){

  this.count

  }

  },

  计算值:{

  double () {

  返回this . count * 2;

  }

  },

  render() {

  归还这个。$scopedSlots.default({

  伯爵:这个.伯爵,

  double: this.double,

  increment: this.toggleState,

  })

  }

  }

  这里的作用域槽是这个模式中逻辑组件的关键。

  显示组件

  接下来,作为非呈现组件的用户,显示组件提供特定的显示模式。

  的所有元素标记都包含在作用域槽中。正如您所看到的,这些属性在使用中与直接放在逻辑组件中的模板没有什么不同。CounterWithButton.vue

  模板

  反渲染slot-scope=“{ count,double,increment }”

  divCount是:{{ count }}/div

  divDouble是:{{ double }}/div

  按钮@click=increment 增量/按钮

  /无反渲染

  /模板

  脚本

  从导入无反渲染器。/count renderless ;

  导出默认值{

  组件:{

  无反渲染

  }

  }

  /脚本

  无组件渲染模式非常灵活且易于理解。但是没有前面的方法普遍,应用场景可能只有一个,就是用来开发组件库。

  

模板扩展

  上面的API或者设计模式有一个限制,就是不能扩展组件的模板。Vue有办法重用逻辑和状态,但是对模板标签无能为力。

  比较hack的一种方法是使用HTML预处理程序,比如Pug,来处理模板扩展。

  第一步是创建一个基本模板。包含公共页面元素的pug文件。还包括一个块输入作为模板扩展的占位符。

  BaseTemplate.pug

  分区包装器

  h3 {{ myCommonProp }}!-通用标记-

  阻止输入!-扩展标记出口-

  要扩展这个模板,需要安装Vue Loader的Pug插件。然后您可以引入基本模板并用块输入语法替换占位符:MyComponent.vue

  模板语言=帕格

  扩展BaseTemplate.pug

  块输入

  h4 {{ myLocalProp }}!-包含在基本模板中-

  /模板

  起初,你可能会认为它和slot是同一个概念,但有一点不同。这里的基本模板不属于任何单独的组件。它在编译时与当前组件合并,而不是像slot一样在运行时被替换。

  以上是复用和扩展Vue组件方式的详细说明。更多关于Vue组件复用和扩展的信息,请关注我们的其他相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: