美文网首页我爱编程
现代前端框架常见应用模式

现代前端框架常见应用模式

作者: linc2046 | 来源:发表于2018-06-01 16:27 被阅读73次
现代前端框架常见应用模式

引言

任何一种框架的诞生和流行都意味要学习框架内部本身实现所提倡的应用模式,如jQuery时代,立即执行表达式(IIFE), 深浅拷贝, 无new实例化(通过精巧原型链设计实现), 各种钩子函数(用于磨平不同浏览器兼容性差异),多种插件扩展方式(拷贝、原型)等等应用技巧或模式,无不深受前端工程师学习或面试题首选。MVVM时代亦然,当前流行的React、Vue、Angular三巨头无不深谙此道,引入或自创各种技巧或模式。

本文综合编译各类模式文章,学习并总结常见应用模式,以飨读者。

React篇

无状态组件和有状态组件

组件只接收输入props属性,最后返回视图内容,称之为无状态组件或纯组件。

示例:

简单的无状态按钮组件,只接受onClick一个属性

const Button = props =>
  <button onClick={props.onClick}>
    {props.text}
  </button>

应用运行过程中,React组件维持并管理内部状态,称之为状态组件。

示例:

按钮容器组件,内部定义点击次数状态。

class ButtonCounter extends React.Component {
  constructor() {
    super()
    this.state = { clicks: 0 }
    this.handleClick = this.handleClick.bind(this)
  }

  handleClick() {
    this.setState({ clicks: this.state.clicks + 1 })
  }

  render() {
    return (
      <Button
        onClick={this.handleClick}
        text={`You've clicked me ${this.state.clicks} times!`}
      />
    )
  }
}

容器和展示组件

当和外部数据进行交互时,我们会把组件分成两类,容器负责接触React作用域外部的数据,如,连接ReduxRelay

展示组件不依赖应用的任何部分,仅仅依赖其内部状态或接收属性。

示例:

接收属性的用户列表展示组件

const UserList = props =>
  <ul>
    {props.users.map(u => (
      <li>{u.name} — {u.age} years old</li>
    ))}
  </ul>

可以通过容器组件更新用户列表组件

class UserListContainer extends React.Component {
  constructor() {
    super()
    this.state = { users: [] }
  }

  componentDidMount() {
    fetchUsers(users => this.setState({ users }))
  }

  render() {
    return <UserList users={this.state.users} />
  }
}

高阶组件

高阶组件,简称为HOC, 在需要重用组件逻辑时很有用。

HOC是能够接收组件入参并且出参为新组件的JS函数。

举例,有一个可伸展的菜单组件,当用户点击菜单时显示其子代内容。

除了直接控制其父组件状态实现外,还可以创建一个简单通用HOC实现:

function makeToggleable(Clickable) {
  return class extends React.Component {
    constructor() {
      super()
      this.toggle = this.toggle.bind(this)
      this.state = { show: false }
    }

    // 將切换显示逻辑抽象为HOC实现
    toggle() {
      this.setState(prevState => ({ show: !prevState.show }))
    }

    // 返回带切换逻辑的新组件
    render() {
      return (
        <div>
          <Clickable
            {...this.props}
            onClick={this.toggle}
          />
          {this.state.show && this.props.children}
        </div>
      )
    }
  }
}

使用JS装饰器可以將HOC逻辑应用到其他需要的组件上。

@makeToggleable
class ToggleableMenu extends React.Component {
  render() {
    return (
      <div onClick={this.props.onClick}>
        <h1>{this.props.title}</h1>
      </div>
    )
  }
}

组件被装饰后可以接收任何子组件:

class Menu extends React.Component {
  render() {
    return (
      <div>
        <ToggleableMenu title="First Menu">
          <p>Some content</p>
        </ToggleableMenu>
        <ToggleableMenu title="Second Menu">
          <p>Another content</p>
        </ToggleableMenu>
        <ToggleableMenu title="Third Menu">
          <p>More content</p>
        </ToggleableMenu>
      </div>
    )
  }
}

组成:

  • 高阶函数组件, 接受被装饰组件,在返回新组件中维持通用抽象状态,新组件render渲染逻辑中执行状态判断

  • 被修饰具体组件,显示最外层具体渲染组件

层次:

高阶函数组件(被修饰具体组件Class)

高阶组件的本质是將抽象状态逻辑维护至新组件中,具体组件作为新组件执行状态逻辑的最终返回值。

Redux的connect方法和React Router的withRouter函数,都是使用高阶组件实现。

渲染回调函数(函数子组件)

另一种实现复用组件逻辑的方法是將子组件变成函数,也被成为渲染回调函数。

这里以可伸展菜单为例使用此方法重写。

class Toggleable extends React.Component {
  constructor() {
    super()
    this.toggle = this.toggle.bind(this)
    this.state = { show: false }
  }

  toggle() {
    this.setState(prevState => ({ show: !prevState.show }))
  }

  render() {
    return this.props.children(this.state.show, this.toggle)
  }
}

调用时传递函数作为Toggleable组件的子组件:

<Toggleable>
  {(show, onClick) => (
    <div>
      <div onClick={onClick}>
        <h1>First Menu</h1>
      </div>
      {show ?
        <p>Some content</p>
        : null
      }
    </div>
  )}
</Toggleable>

如果想像HOC那样复用函数逻辑支持多个菜单,可以创建一个新组件使用Toggleable逻辑:

const ToggleableMenu = props =>
  <Toggleable>
    {(show, onClick) => (
      <div>
        <div onClick={onClick}>
          <h1>{props.title}</h1>
        </div>
        {show && props.children}
      </div>
    )}
  </Toggleable>

最终的Menu组件和HOC版本一样:

class Menu extends React.Component {
  render() {
    return (
      <div>
        <ToggleableMenu title="First Menu">
          <p>Some content</p>
        </ToggleableMenu>
        <ToggleableMenu title="Second Menu">
          <p>Another content</p>
        </ToggleableMenu>
        <ToggleableMenu title="Third Menu">
          <p>More content</p>
        </ToggleableMenu>
      </div>
    )
  }
}

当我们在不考虑管理状态事,要改变渲染内容时,渲染回调很有用。

上例中,我们將渲染逻辑迁移成ToggleableMenu子函数组件, 但仍然在抽象组件Toggleable实现状态逻辑(维护show状态)。

渲染函数组成:

  • 抽象组件,用于维护通用抽象状态,渲染方法调用子函数组件,生成最终渲染逻辑

  • 子函数组件,接收抽象组件的状态或变量,实现真正渲染逻辑,渲染可从最外部传入

  • 具体组件,调用抽象组件, 可传入最外部具体渲染组件

渲染函数组件层次:

<具体组件函数 传入具体渲染组件>
<抽象组件>
<子函数 />
</抽象组件>
</具体组件函数>

渲染函数的本质是抽象组件维护自身通用状态,同时隔离渲染逻辑(可能有很多判断或不同组件展示逻辑)到子函数中,子函数组件会接收抽象组件的部分状态或私有数据

,將抽象通用状态与组件渲染进行剥离,实现最大化组合复用。

译者注

相关文章

  • 现代前端框架常见应用模式

    引言 任何一种框架的诞生和流行都意味要学习框架内部本身实现所提倡的应用模式,如jQuery时代,立即执行表达式(I...

  • j2ee框架介绍

    1. 无框架传统开发模式&为什么要用框架 传统web应用开发模式:jsp,包含前端代码,业务处理逻辑 javaBe...

  • web前端开发高级

    前端高效开发框架技术与应用 Vue 基础Vue 框架简介 MVX 模式介绍Vue 框架概述如何使用 Vue.js ...

  • 关于封装框架总结

    关于封装框架总结 常见的框架 1、常见的框架学习前端的都知道,前端有很多的丰富的框架。例如:通用框架:jQuery...

  • Vue.js起步

    Vue前端框架 MVVM模式view和view-model之间通过双向绑定data-binding建立联系 现代的...

  • Vue 路由模式切换

    路由切换模式:{hash/ history} 对于Vue 这类渐进式前端开发框架,为了构建SPA(单页面应用),...

  • HybridStart发布v1.0测试版

    HybridStart是一款多webview模式的混合应用前端开发框架,本来只是作者自用的一套混合应用开发模板,为...

  • 前端微应用化

    微应用与微前端 微应用框架是一种类微前端框架; 相比与微前端,微应用实施成本低、技术难度小、维护成本低; 微应用化...

  • vue ssr

    SSR (同构应用)的意义 SEO 首屏直出,减少白屏 更多的前端自由度和控制力 前端SSR的优势 利用现代框架v...

  • 移动无线测试技能树

    移动无线测试技能树 -常用IDE -基础知识 -常见应用模式 -常用工具 -常用UI Automation框架 -...

网友评论

    本文标题:现代前端框架常见应用模式

    本文链接:https://www.haomeiwen.com/subject/vijksftx.html