Vue中的受控与非受控组件的实现

  

<强>
  

  

<强>什么是受控组件?
  

  

其值由反应控制的输入表单元素称为“受控组件”。

  

受控组件有两个特点:1。设置值值值由国家控制,2。值值一般在onChange事件中通过设置状态进行修改

  

<强>什么时候使用受控组件?
  

  

需要对组件的价值值进行修改时,使用受控组件。比如:页面中有一个按钮,每点击一次按钮受控组件的值加1。

  


  

  

什么是非受控组件?
  

  

表单数据由DOM处理的组件非受控组件。

  

非受控组件有两个特点:1。不设置值值,2。通过裁判获取dom节点然后再取价值值

        & lt;输入类型=拔谋尽闭嘉环?扒胧淙胄彰皀ame=坝没眗ef={(输入)=比;这一点。usernameElem=输入}/祝辞      

取值方法:this.usernameElem。值
  

  

<强>什么时候使用非受控组件?
  

  

任何时候都不需要改变组件的价值值,这时候可以使用非受控组件。

  


  

  

熟悉的反应的开发者应该对“受控组件”的概念并不陌生,实际上对于任何组件化开发框架而言,都可以实现所谓的受控与非受控,Vue当然也不例外,并且理解受控与非受控对应的需求场景,可以让我们在设计一些基础组件时思路更加清晰,暴露出来的组件API也更加合理,统一。

  

<强>需求
  

  

许多用户界面组件都是有状态(状态)的,而这个状态是由组件外部控制还是组件内部维护,也就对应了受控与非受控两种模式。

  

例如标签组件是很常见的一种UI组件,它的核心状态就是记录当前活跃的选项卡,并且允许用户切换。

  

很多时候我们只希望标签可以正确的展示活跃的内容,并在用户操作时正常切换,不需要进行任何干预,那么就希望只需要传入所有的选项卡内容,不需要再做额外的配置。

  

但有的时候我们又希望对标签的状态有很强的控制能力,例如多个关联的标签、子级标签的内容需要根据父级标签的活动选项卡动态切换,这时候就会希望选项卡组件可以暴露足够充分的API,来实现业务的需求。

  

因此我们可以用一种通用的模式,来让任意组件的任意状态同时兼容受控与非受控两种模式,让不同需求场景下都可以使用最合理的API。

  

<强>简化示例
  

  

我们用一个简单的标签实现来演示这种通用的组件API设计模式,简化的部分包括:

  
      <李>用指数来作为标签的唯一标识李   <李>选项卡内容只支持字符串李   
  

可以打开>   {   道具:{   defaultActiveIdx: {   类型:数字,   默认值:0   }   },   数据(){   返回{   localActiveIdx: this.defaultActiveIdx   }   },   方法:{   handleActiveIdxChange (idx) {   这一点。localActiveIdx=idx;   这一点。美元发出(“active-idx-change”, idx);   }   }   }   之前      

localActiveIdx是我们用来存放活跃指数的组件内数据,对于非受控模式而言,虽然不希望在外部维护状态,但是仍有可能希望在外部决定初始状态,所以我们用defaultActiveIdx这个道具决定localActiveIdx的初始值。

  

之后当我们用v=北昵?标签,idx)”指令生成所有的标签时,就可以通过idx===localActiveIdx的方式判断当前标签是否活跃,再通过@click=癶andleActiveIdxChange (idx)”就可以实现对localActiveIdx的更新。

  

同样的,我们也可以通过{{标签(localActiveIdx)。内容}}展示有源标签的内容。

  

需要注意的是在handleActiveIdxChange的事件处理中,我们也发出了active-idx-change这一事件,这样可以方便外部在不需要管理组件状态的同时也可以与组件状态保持同步。例如我们希望将有源标签反映在URL中,就可以在外部监听active-idx-change这一事件,并将当前指数同步到路由中,在将路由中获取到的指数作为defaultActiveIdx传入,就可以实现URL和标签的同步。

  

<>强受控模式
  

  

对于受控模式来说,我们可以理解为活跃指数是外部传入的道具、由外部自行维护其状态。

  

因此我们只需要添加如下道具:

        道具:{   activeIdx:数量   }   之前      

由于我们已经有对外发出的事件active-idx-change,所以外部用以下方式就可以用一个数据属性externalActiveIdx维护对应状态:

Vue中的受控与非受控组件的实现