最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 我是如何在 Nextjs 项目中使用Storybook驱动组件开发的?

    正文概述 掘金(Ywhoo)   2021-01-12   673

    在使用 React开发组件时经常会有一些苦恼,比如当一个组件的复杂度逐步上升时,它所拥有的状态不容易追溯;当需要查看某种状态的组件时,可能需要手动更改组件的属性或是更改接口返回的数据(数据驱动的组件)等等。于是我就去了解并学习 Storybook,然后组织了一次分享会,这也是我们团队的第一次技术分享。

    关于 Storybook,我在一两年前有接触并尝试使用,当时对组件化开发的理解可能有限,只是为了用而用,并未感受到它的实用之处;加上经过多次的迭代,Storybook已经到了 6.0 版本,可以说是更易用、更优雅了。

    我是如何在 Nextjs 项目中使用Storybook驱动组件开发的?

    上图是分享会 ppt 的封面,感兴趣的同学可以私信我,接下来进入正题。

    动机

    • 新项目的 UI 系统需要重新设计
    • 项目迭代,组件复杂度逐步变高,组件状态不容易追溯
    • 追求更优雅、更具维护性的编码方式

    目标

    这篇文章主要给大家分享一下几点:

    • 介绍 Storybook
    • 通过一个小例子展示如何在 Next.js 中使用 Storybook
    • 我的代码编写习惯

    要求

    因为包含了实践,可能有以下几点要求,不过不用担心,只要你能看懂就行:

    • 示例是基于 Next.js 的,这个我在上一篇文章中有讲到如何搭建 Next.js 项目,可以点击这里把我搭建的脚手架克隆到本地,以便可以跟着动手。
    • 因为是基于上一篇文章所搭建的脚手架,所以它所拥有的特性也需要了解,比如 Typescriptstyled-component

    介绍 Storybook

    storybook是一个开源工具,为React、Vue、Angular等框架提供一个沙箱环境,可独立地开发UI组件;它更有组织和高效地构建出令人惊叹的 UIs。

    我是如何在 Nextjs 项目中使用Storybook驱动组件开发的?

    提供强大的 UIs

    • 独立构建组件

      创建组件时不需要竖起屏幕,不需要处理数据,也不需要构建业务逻辑。 我是如何在 Nextjs 项目中使用Storybook驱动组件开发的?

    • 模拟难以达到的用例

      在一个应用中渲染关键状态是不容易的 我是如何在 Nextjs 项目中使用Storybook驱动组件开发的?

    • 用例作为一个故事

      将用例保存为 Javascript 中的故事,以便在开发、测试和QA期间重新访问。 我是如何在 Nextjs 项目中使用Storybook驱动组件开发的?

    • 使用插件减少工作流程

      使用插件可以更快地构建UI,组件文档化,并简化工作流程。

    我是如何在 Nextjs 项目中使用Storybook驱动组件开发的?

    组件更具可靠性

    • 确保一致的用户体验

      每当写一个故事,就得到一种状态的视觉效果。快速地浏览故事,检查最贱 UI 的正确性。 我是如何在 Nextjs 项目中使用Storybook驱动组件开发的?

    • 自动回归测试代码

      使用官方插件 Storyshots 启动代码快照。 我是如何在 Nextjs 项目中使用Storybook驱动组件开发的?

    • 单元测试组件

      对组件进行单元测试确保组件能正常工作。 我是如何在 Nextjs 项目中使用Storybook驱动组件开发的?

    • 基于每次提交像素级地捕获UI变化

      用视觉测试工具查明UI的变化。 我是如何在 Nextjs 项目中使用Storybook驱动组件开发的?

    分享和重用所有东西

    • 在项目中查找任何组件

      Storybook 可搜索编写的任何组件,为你的UI组件提供真实信息的单一来源。 我是如何在 Nextjs 项目中使用Storybook驱动组件开发的?

    • 开发过程中获得及时反馈

      通过 Storybook 部署到云端,与团队协作实现UI。 我是如何在 Nextjs 项目中使用Storybook驱动组件开发的?

    • 跨端跨应用共享组件

      每个故事都是一个用例,团队成员可以找到它并决定是否重用。 我是如何在 Nextjs 项目中使用Storybook驱动组件开发的?

    • 生成文档

      编写 markdown/MDX,为组件库和设计系统生成可定制化的文档。 我是如何在 Nextjs 项目中使用Storybook驱动组件开发的?

    使用 Storybook

    下面我会通过一个示例想大家展示 Storybook 是如何工作的,期间也能看到我是如何使用结合 Typescript、styled-components以及我的编码习惯。

    安装

    假设你已经克隆了这个仓库,首先在项目中安装 storybook

    # 安装 storybook
    yarn add storybook
    # 初始化 storybook 项目,会根据项目类型自动地进行配置
    npx sb init
    # 启动 storybook 服务
    yarn storybook
    

    以上几部没问题之后,现在就可以在 http://localhost:6006/ 访问 Storybook 提供的 UIs 了:

    我是如何在 Nextjs 项目中使用Storybook驱动组件开发的?

    它默认提供了几个例子,如 ButtonHeader等,例子代码在 src/pages/stories 中:

    我是如何在 Nextjs 项目中使用Storybook驱动组件开发的?

    后缀名为 stories.tsx 的文件就是一个故事,它定义了我们想要定义的组件的表现状态;大家可能不是很理解一个故事是什么,后面大家看了示例之后就会理解了,我先打个比方,一个人就好比一个故事,当他有不同的心情时,就会表现出不同的表情,同一时间只能看到它的一种表情,但我现在用照片记录他所表现的一个个不同的表情,这有利于我去分析这个人的性格;Storybook 就像是照相机,可以记录组件的不同状态,便于我们去追溯。

    设计 ProductOptimCard 组件

    接下来设计并实现 ProductOptimCard 组件,这个组件是数据驱动的,也就是内容是根据数据的变化而变化的,为了方便,我只定义了标题、是否必做、是否完成这三个属性,它们的变化会展示不同状态下的视图,默认的效果如下:

    我是如何在 Nextjs 项目中使用Storybook驱动组件开发的?

    以下是组件实现代码:

    // src/components/towone/ProductOptim/ProductOptimCard/index.tsx
    import React from 'react';
    import styled from 'styled-components';
    
    interface IProductOptimCardProps {
      data: {
        isMustDo: boolean;
        isFinish: boolean;
        title: string;
      };
    }
    
    const Container = styled.div`
      width: 452px;
      height: 276px;
      background: #fefeff;
      border: 1px solid #edf0fa;
      box-shadow: 0px 4px 14px 0px rgba(0, 10, 71, 0.07);
    `;
    const Content = styled.div`
      height: 225px;
      background: #fff;
      padding-top: 21px;
      padding-left: 20px;
      position: relative;
    `;
    const Footer = styled.div`
      height: 50px;
      background: #f7f8fa;
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding-right: 10px;
      padding-left: 20px;
    `;
    const Title = styled.div`
      font-size: 16px;
      font-weight: bold;
      color: #333;
      margin-bottom: 14px;
    `;
    const Badge = styled.div<{ isMustDo: boolean }>`
      width: 37px;
      height: 21px;
      background: ${({ isMustDo }) => (isMustDo ? '#0af' : '#999999')};
      font-weight: bold;
      color: #fefeff;
      font-size: 12px;
      border-radius: 11px 2px 11px 11px;
      position: absolute;
      top: 10px;
      right: 10px;
      display: flex;
      align-items: center;
      justify-content: center;
    `;
    const Text = styled.div`
      font-size: 14px;
      color: #666666;
      margin-bottom: 14px;
    `;
    const MoreText = styled.a`
      font-size: 14px;
      color: #333333;
    `;
    const FinishButton = styled.div<{ isFinish: boolean }>`
      width: 60px;
      height: 28px;
      background: ${({ isFinish }) => (isFinish ? '#999' : '#046eff')};
      color: #fefeff;
      font-size: 12px;
      display: flex;
      justify-content: center;
      align-items: center;
      cursor: pointer;
    `;
    
    const ProductOptimCard: React.FC<IProductOptimCardProps> = ({ data }) => {
      const { isMustDo, isFinish, title } = data;
    
      return (
        <Container>
          <Content>
            <Title>{title}</Title>
            <Text>1、尺寸:800 x 800px</Text>
            <Text>2、卖点提炼文字展示(针对同款多、标品类目)</Text>
            <Text>3、产品占图片三分之二</Text>
            <Text>4、参考五家淘宝以及阿里优秀类似款主图(按成交金额排序)</Text>
            <Badge isMustDo={isMustDo}>必做</Badge>
          </Content>
          <Footer>
            <MoreText>更多教程</MoreText>
            <FinishButton isFinish={isFinish}>完成了</FinishButton>
          </Footer>
        </Container>
      );
    };
    
    export default ProductOptimCard;
    

    然后在首页引入它:

    // src/pages/index.tsx
    
    //...
    
    export default function Home() {
      return (
        <Conotainer>
           <ProductOptimCard
              data={{ isMustDo: false, isFinish: false, title: '单品标题优化' }}
            />
        </Conotainer>
      );
    }
    

    执行 yarn dev 启动项目,然后打开 http://localhost:3000/ 查看:

    我是如何在 Nextjs 项目中使用Storybook驱动组件开发的?

    图中红框中的组件就是 ProductOptimCard 的默认样式,组件本身已经实现了不同状态:如必做、不必做、已完成、未完成;但我想查看某个状态,将不得不更改 src/pages/index.tsx 中传给 ProductOptimCarddata 属性,而这个通常是根据接口返回的数据,要去该代码就显得麻烦不优雅了,不过不用担心,我们现在有 Storybook了,请往下看。

    在同级目录新建一个 ProductOptimCard.stories.tsx 文件,为 ProductOptimCard 编写故事,代码如下:

    import React, { ComponentProps } from 'react';
    import { Story, Meta } from '@storybook/react/types-6-0';
    
    import ProductOptimCard from './';
    
    export default {
      title: 'TWOONE/ProductOptim/ProductOptimCard',
      component: ProductOptimCard,
    } as Meta;
    
    const Template: Story<ComponentProps<typeof ProductOptimCard>> = (args) => (
      <ProductOptimCard {...args} />
    );
    
    export const DefaultCard = Template.bind({});
    DefaultCard.args = {
      data: {
        isMustDo: false,
        isFinish: false,
        title: '单品标题优化',
      },
    };
    
    export const MustDoCard = Template.bind({});
    MustDoCard.args = {
      data: {
        isMustDo: true,
        isFinish: false,
        title: '单品标题优化',
      },
    };
    
    export const FinishCard = Template.bind({});
    FinishCard.args = {
      data: {
        isMustDo: false,
        isFinish: true,
        title: '单品标题优化',
      },
    };
    
    export const UnFinishCard = Template.bind({});
    UnFinishCard.args = {
      data: {
        isMustDo: false,
        isFinish: false,
        title: '单品标题优化',
      },
    };
    

    我们引入了 ProductOptimCard,并为其编写了四种状态,分别是 DefaultCardMustDoCardFinishCardUnFinishCard,传入不同的data,自然会表现出不同的状态。然后打开 http://localhost:6006/:

    我是如何在 Nextjs 项目中使用Storybook驱动组件开发的?

    红框是我们为 ProductOptimCard 编写的故事,点击不同状态以查看 UI 效果:

    我是如何在 Nextjs 项目中使用Storybook驱动组件开发的?

    可以看到,我们很容易就知道并查看这个组件的不同状态,是不是有点跃跃欲试了呢,点击 Docs 可查看文档,其它操作就大家课后自己尝试:

    我是如何在 Nextjs 项目中使用Storybook驱动组件开发的?

    // .storybook/main.js
    const path = require('path');
    
    module.exports = {
      // ...
      webpackFinal: async (config, { configType }) => {
        config.resolve.alias['@'] = path.resolve(__dirname, '../src');
        
        return config;
      },
    };
    

    到这里我们已经通过一个示例来了解如何使用 Storybook 了,接下来会简单聊聊我的一些编码心得。

    我的编码习惯与心得

    分类

    从数据获取的层面看,我将组件分为容器组件和内容组件:

    **容器组件:**从接口获取数据。

    **内容组件:**接收 props 数据、可编写 story 组件驱动开发。

    story组件编写的大致顺序

    • Typescript 定义组件接收的参数
    • 为可选的类型设置默认值
    • 编写 story 描述不同状态的组件

    组件编写顺序

    通常一个组件引入的三方库在最顶部,其次是自定义组件,所以我这里的顺序值得是组件中变量定义的位置,以下是我所习惯的定义顺序(从上往下),每个区域隔一行:

    • 三方库

    • 自定义组件

    • 图片常量

    • Typescript 接口

    • 样式组件

    • 组件区

    一个最小化的示例代码:

    import React from 'react';
    import styled from 'styled-components';
    
    import { MySelfComp } from '@/components';
    
    import ICON_LOGO from '@/assets/images/icon.logo.png';
    
    interface IProps {}
    
    const Container = styled.div``;
    
    const DemoComp: React.FC<IProps> = () => {
      return <Container></Container>
    }
    
    export default DemoComp;
    

    总结

    目前带大家认识了 Storybook,并且介绍了如何使用,当然这只是基础用法,在项目中大家可能也会遇到不同的场景,如遇到问题可以查看官方文档,还是写的挺详细的;本来想将测试流程也写进去,不过感觉会有不小的篇幅,以后可以另起一篇文章,我可以先简单介绍一个我觉得比较理想的组件开发流程:组件设计并编写 -> 编写 story -> Jest 测试 -> Enzyme 测试,对于后面两个测试库,确实进一步地提升了组件的健壮性,但是会增加很多的工作量,一般的小公司确实用不着,感兴趣的可以课下自行研究。

    附录

    Storybook 6.0

    examples

    Marketing and docs

    BBC Psammead?

    GitLab UI?


    起源地下载网 » 我是如何在 Nextjs 项目中使用Storybook驱动组件开发的?

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元