iView 是一款基于 Vue.js 的 UI 组件库,在 Vue 项目中使用非常方便。但在使用 Next.js 开发 SSR(Server Side Rendering)应用时,需要一些特殊的配置来兼容 iView。
本文将介绍如何在 Next.js 中使用 iView,避免常见的错误和坑点,并提供详细的示例代码和指导意义。
安装 iView
首先,在 Next.js 项目中安装 iView:
npm install iview --save
配置 CSS
由于 Next.js 使用了基于文件系统的路由,而 iView 使用全局 CSS 样式,因此需要额外处理 CSS 样式,以避免 iView 样式被全局覆盖,或者在某些组件中无法使用。
使用 CSS Modules
一种可行的方案是使用 CSS Modules,让样式只对当前组件生效,而不影响全局样式和其他组件中的样式。
这里以 Next.js 9.0 或以上版本为例,使用 postcss-modules 处理 CSS 样式:
- 安装依赖:
npm install postcss-modules --save-dev
- 创建
postcss.config.js
文件:
module.exports = { plugins: { 'postcss-modules': { generateScopedName: '[local]-[hash:base64:5]', camelCase: true, }, }, };
这里使用了 generateScopedName
来保证唯一性,并启用了 camelCase
格式来方便 JS 的使用。
- 配置 Next.js:
-- -------------------- ---- ------- -- -------------- ----- ------- - -------------------------- ----- ----------- - ------------------------------ -------------- - -------- ------------- ----------- ----- ----------------- - -------------- -- --------------- -------------------------- -- --------------------- --- --------------- - ------ ------- -- -- --
这里使用了 Next.js 自带的 @zeit/next-css
和 @zeit/next-postcss
插件,同时打开了 CSS 模块化选项,并配置了 postcss-loader 的选项,保证样式被正确处理。
- 重启应用,进行测试:
-- -------------------- ---- ------- ------ ----- ---- -------- ------ ------ ---- ---------------------- ------ - ------ - ---- -------- ------ ------- -- -- - ---- --------------------------- ------- -------------------- ----------- ------ --
可以看到,样式被正确注册,不与全局样式或其他组件样式冲突。
使用 Server-side Rendering Inline Styles
另一种方案是使用 Server-side Rendering Inline Styles。
这里介绍如何在 Next.js 中使用 next-style-loader,以实现 SSR 时样式的正确展示。
该方法适用于没有使用 styled-jsx
的情况。
- 安装依赖:
npm install --save @zeit/next-css next-style-loader
- 配置 Next.js:
-- -------------------- ---- ------- -- -------------- -------------- - - -------- -------- - -------- -- -- - -- ---------- - ----- ------------- - ------------- ------------ - ----- -- -- - ----- ------- - - --------- ---------------- -- -- ---- ------ ------- ---------- ---- -- --- --------------- ------ ------------------------- - ---------- ------ -------- -- - ------ ------- -- --
这里做了一个额外处理,将 iView 组件库中的所有组件打包在 ./iview
文件夹中,并将其传递给服务器端进行渲染。
- 创建
./iview/index.js
:
import 'iview/dist/styles/iview.css'; export * from 'iview';
这里使用 iview/dist/styles/iview.css
的默认样式,并使用了 ES6 的 export * from 'iview'
来实现全部组件的导出。
- 重启应用,在前端组件中使用 iView:
import React from 'react'; import { Button } from 'iview'; export default () => ( <div> <Button type="primary">Click me</Button> </div> );
可以看到,iView 组件能够正确渲染,并且与全局样式隔离。此时,如果在浏览器中查看页面源代码,可以看到样式已经通过 style
标签嵌入到页面中。
使用 iView 的坑点与指导
SSR 中的组件重复渲染
在 Next.js 中,SSR 会注入一些生命周期钩子,如 componentDidMount
和 componentWillUnmount
。而 iView 中的某些组件(如 Carousel
)中也自带了生命周期钩子,可能会导致出现错误。
一种解决方案是使用 React.useEffect
来模拟 componentDidMount
和 componentWillUnmount
,并清除组件中的定时器。
例如,在 Carousel
组件中:
-- -------------------- ---- ------- ------ - ------- - ---- ----------------- ------ ------- - ----- ----------- ------ - --------- - ----- -------- -------- ----- -- -- --------- - ------------------ - ------ --------------------- -- ----- -- -- --------- - ---------- - ----- -------------- - -- -- --------- - -- --------------- - --------------------- - -- --------------- - -- ------------ - -------------------------- - ---------- - ----- -- -------- - --------------- - -- ------------ - -------------------------- - ---------- - -------------- -- - ------------------------------ -- - - - - ---- -- ----------------------- -- ---------------- - -- --- -- -- --- -- --
应该改为:
-- -------------------- ---- ------- ------ - ------- - ---- ----------------- -------- --------------------- - ----- ------- --------- - --------------------- ----- ----------- ------------- - ------------------ ------------------ -- - -------- --------------- - -- ------- - --------------------- - ----- -------- - -------------- -- - -------------------- -- - - - - ---- -- --------------------------- ------------------- - -------- ---------------- - -- --- - -- ------------------- - ---------------- - ------ -- -- - -- ------- - --------------------- - -- -- ------------------- ------ ------------ ------ - ------ --------- ---------- ------------ -- - ------ ------- - ----- ----------- ------ - --------- - ----- -------- -------- ----- -- -- --------- - ------------------ - ------ --------------------- -- ----- -- -- --------- - -------------- - -- -- -------- - ---------------- - -- --- -- -- --- --------------------- -- --
这里使用了 useEffect
来处理生命周期,并使用了 useState
来处理组件中的字段。同时,将 startAutoplay
和 prevOrNext
提取出来,避免了生命周期函数中函数的嵌套定义。
组件导出不一致
由于 iView 的一些组件导出不一致,可能导致类型错误或编译错误。
例如,在 Spin
组件中,有时需要使用 iview/src/components/spin
导入,有时则需要使用 iview
导入。
一种解决方案是使用 export *
来导入全部组件:
import { Spin as IVSpin } from 'iview'; import 'iview/dist/styles/iview.css'; // 将 Spin 重命名为 iViewSpin,避免与 React 冲突 export const Spin = IVSpin; // 导出全部组件 export * from 'iview';
这样可以保证组件导入的一致性,并确保组件能够正常使用。
示例代码
下面是一个简单的 Next.js 应用,演示了如何在 Next.js 中使用 iView:
-- -------------------- ---- ------- -- -------------- ------ ----- ---- -------- ------ ---------- ---- --------------------------- ------ ------ ---- ---------------------- ------ - ------- ----- ------- ----- ----- - ---- -------- ------ ------- -- -- - -------- ---- --------------------------- ----------- ------------ -- -------- --- ------ ----- -- --- ------------ ------- -------------- ----------- -- ------------ ---------- ----- ------------------------------- -- ----------- ---------- --------- ------ ----------- ------ ----------- ---------------------- -- ------------ ----------- ------ --------------- ---------------------- -- ------------ ----------- ------- -------------- ------------------ --- -- --------- ------------ ------- ------ --------- --
结论
在 Next.js 中使用 iView 需要一定的额外处理,但只要正确配置 CSS 样式和组件导入,就能够实现完整的 iView UI 组件库的支持,为开发带来更加便捷的体验。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/66ff689467736bdc72ecd041