react-问卷星项目(4)

[复制链接]
发表于 2026-1-14 14:34:50 | 显示全部楼层 |阅读模式
项目实战

利用CSS

只管不要利用内联CSS


  • 内联style代码多,性能差,扩展性差
  • 外链css文件可复用代码,可单独缓存文件
元素内联style



  • 和HTMl元素的style相似
  • 必须用JS写法,不能是字符串,内里必须是对象
  1. <span style={{ color: "green" }}>已发布</span>
复制代码


  • 驼峰写法

利用css文件



  • 引入css文件
  • JSX中利用className
  1. <div key={id} className="list-item">
复制代码
  1.   let itemClassName = "list-item";
  2.   if (isPublished) itemClassName += " published";
  3.   <div key={id} className={itemClassName}>
复制代码


  • 可利用clsx或classnames做条件判定,两个功能相近,都是判定class条件的聚集,好比当判定的条件多了,利用上面的if无法满足的时间就须要借用到工具。在这个项目中用classnames做例子,通过下列步调利用
  • classnames堆栈地点
  下载指令
  npm install classnames
  1. import classnames from "classnames";
  2. const itemClassName = classnames("list-item", { published: isPublished });
  3.   // 上下两种含义一致,只是不同的写法
  4.   const itemClassName = classnames({
  5.     "list-item": true,
  6.     published: isPublished,
  7.   });
复制代码

CSS Module

平凡CSS的题目,React利用组件化开发,多个组件就须要多个CSS文件,多个CSS文件很容易造成className重复。在没有相应的工具前利用的是BEM,一种软性规范。主观性过强而不保举。以下是CSS module的特点


  • 每个CSS文件都当作单独的模块,下令xxx.module.css
  • 为每个className增长后缀名,不重复
  • Create- React-App原生支持CSS Module
将文件名更改为xxx.module.css的格式,样式的格式稳定
  1. // QuestionCard.module.css 文件中
  2. .list-item{
  3.   border: 1px solid black;
  4.   padding: 10px;
  5.   margin-bottom: 16px;
  6. }
  7. .published{
  8.   border: 1px solid greenyellow;
  9. }
复制代码
引入和利用,这一部分和原来的差别比力大
  1. // import classnames from "classnames";
  2. // 上面是原来的,下面是module的引入
  3. import styles from "./QuestionCard.module.css";
  4. // 使用格式,其中list-item因为有-符号,如果直接styles.list-item会报错,下面这个js写法就可以
  5. <div key={id} className={styles["list-item"]}>
复制代码

Sass

CSS语法比力原始,不能嵌套。当代开发一样平常利用less sass等预处置处罚语言。CRA原生支持Sass Module,后缀直接改为.scss即可
   下载指令
  npm install sass --save
  接下来将想要利用的文件格式改为xxx.scss,记得后缀为scss。
  1. import styles from "./QuestionCard.module.scss";
  2. const itemClassName = classnames({
  3.     [styles["list-item"]]: true,
  4.     [styles["published"]]: isPublished,
  5.   });
  6. <div key={id} className={itemClassName}>
复制代码
此中对于itemClassName的中括号的表明如下,在这段代码中,中括号([])用于在JavaScript对象字面量中动态地设置属性名。这种语法是ES6)中引入的盘算属性名的一个特性,其键为变量y而不是固定字符好比a时,这个写法实际上是将这个变量的引用值转达进去


CSS-in-JS



  • 一种办理方案(而非工具名称),有好几个工具
  • 在JS中写CSS,带来极大的机动性
  • 它和内联style完全不一样,也不会有内联style的题目和className的题目(会自行天生class)
Style-components

官网  大概是外网的链接,打开的时间速率有点慢
   下载指令
  npm install styled-components
  引入代码如下,视频中老师的引入爆红线,须要额外下载东西,我这边没有,不外也趁便下载了。下面这个组件可以测试引入是否乐成
   下载指令
  npm i --save-dev @types/styled-components
  1. import React, { FC } from "react";
  2. import styled, { css } from "styled-components";
  3. const Button = styled.button<{ $primary?: boolean }>`
  4.   background: transparent;
  5.   border-radius: 3px;
  6.   border: 2px solid #bf4f74;
  7.   color: "#BF4F74";
  8.   margin: 0 1em;
  9.   padding: 0.25em 1em;
  10.   ${(props) =>
  11.     props.$primary &&
  12.     css`
  13.       background: blue;
  14.       color: white;
  15.     `};
  16. `;
  17. const Container = styled.div`
  18.   text-align: center;
  19. `;
  20. const Demo: FC = () => {
  21.   return (
  22.     <div>
  23.       <p>styled-components demo</p>
  24.       <Container>
  25.         <Button>normal button</Button>
  26.         <Button $primary>primary 按钮</Button>
  27.       </Container>
  28.     </div>
  29.   );
  30. };
  31. export default Demo;
复制代码
大概表明一下上述代码中的逻辑,此中styled可以明白为一个类,而styled.button和styled.div小数点后的两个属性 都可以明白为方法,包罗css反面加字符串,css也是个函数,反引号可以明白为传参如下图所示,多一层括号显得贫困,以是不消括号的情势


styled-jsx

堆栈地点
项目中倒霉用这个,由于ts情况中对标签的属性比力敏感,而这个工具插入了一些非标准的属性,导致须要额外扩展比力多的功能,用于js没题目,可以选择性的利用。

emotion

官网地点
利用起来的情势和前面的components比力雷同,但是同样有个题目,就是这个工具在标签中添加了css属性,在ts中这么设置会报错,以是ts情况中同样不举行利用.

重构列表页,增长css样式

选择CSS-Module


  • 简单易用,学习资源较低
  • 性能更好,利用CSS-in-JS会增长编译时间
  • 不须要机动变更样式

新建React项目,具体过程参考这一章,原来有很多个Demo的也举行保存,两个都会讲。以下几个文件直接复制粘贴可以用

App.tsx
  1. import React from "react";
  2. import logo from "./logo.svg";
  3. import "./App.css";
  4. import List from "./pages/list";
  5. function App() {
  6.   return (
  7.     <div>
  8.       <h1>问卷F1</h1>
  9.       <List />
  10.     </div>
  11.   );
  12. }
  13. export default App;
复制代码
list.tsx
  1. import React, { FC, useState } from "react";
  2. import QuestionCard from "../components/QuestionCard";
  3. import styled from "./list.module.scss";
  4. const rawQuestionList = [
  5.   {
  6.     _id: "q1",
  7.     title: "问卷1",
  8.     isPublished: true,
  9.     isStar: false,
  10.     answerCount: 5,
  11.     createAt: "3月10日 13:23",
  12.   },
  13.   {
  14.     _id: "q2",
  15.     title: "问卷2",
  16.     isPublished: false,
  17.     isStar: true,
  18.     answerCount: 15,
  19.     createAt: "3月22日 13:23",
  20.   },
  21.   {
  22.     _id: "q3",
  23.     title: "问卷3",
  24.     isPublished: true,
  25.     isStar: true,
  26.     answerCount: 100,
  27.     createAt: "4月10日 13:23",
  28.   },
  29.   {
  30.     _id: "q4",
  31.     title: "问卷4",
  32.     isPublished: false,
  33.     isStar: false,
  34.     answerCount: 98,
  35.     createAt: "3月23日 13:23",
  36.   },
  37. ];
  38. const List: FC = () => {
  39.   const [questionList, setQuestionList] = useState(rawQuestionList);
  40.   return (
  41.     <>
  42.       <div className={styled.header}>
  43.         <div className={styled.left}>
  44.           <h3>我的问卷</h3>
  45.         </div>
  46.         <div className={styled.right}>搜索</div>
  47.       </div>
  48.       <div className={styled.content}>
  49.         {questionList.map((q) => {
  50.           const { _id } = q;
  51.           return <QuestionCard key={_id} {...q} />;
  52.         })}
  53.       </div>
  54.       <div className={styled.footer}>footer</div>
  55.     </>
  56.   );
  57. };
  58. export default List;
复制代码
list.module.scss
  1. .header{
  2.   display: flex;
  3.   .left{
  4.     flex: 1;
  5.   }
  6.   .right{
  7.     flex: 1;
  8.     text-align: right;
  9.   }
  10. }
  11. .content{
  12.   margin-bottom: 20px;
  13. }
  14. .footer{
  15.   text-align: center;
  16. }
  17. body{
  18.   background-color: #f1f1f1;
  19. }
复制代码
QuestionCard.module,scss
  1. .container{
  2.   margin-bottom: 20px;
  3.   padding: 12px;
  4.   border-radius: 3px;
  5.   background-color: white;
  6.   &:hover{
  7.     box-shadow: 0 4px 10px lightgray;
  8.   }
  9. }
  10. .title{
  11.   display: flex;
  12.   .left{
  13.     flex: 1;
  14.   }
  15.   .right{
  16.     flex: 1;
  17.     text-align: right;
  18.   }
  19. }
  20. .button-container{
  21.   display: flex;
  22.   .left{
  23.     flex: 1;
  24.   }
  25.   .right{
  26.     flex: 1;
  27.     text-align: right;
  28.     button{
  29.       color: #999;
  30.     }
  31.   }
  32. }
复制代码
QuestionCard.tsx
  1. import React, { FC, useEffect } from "react";// import "./QuestionCard.css";import styled from "./QuestionCard.module.scss";import classnames from "classnames";type PropsType = {  _id: string;  title: string;  isPublished: boolean;  isStar: boolean;  answerCount: number;  createAt: string;  // 问号是可写可不写,跟flutter语法相似  deletQuestion?: (id: string) => void;  pubQuestion?: (id: string) => void;};const QuestionCard: FC<PropsType> = (props: PropsType) => {  const { _id, title, createAt, answerCount, isPublished } = props;  return (    <div className={styled.container}>      <div className={styled.title}>        <div className={styled.left}>          <a href="#">{title}</a>        </div>        <div className={styled.right}>          {isPublished ? (            <span style={{ color: "green" }}>已发布</span>          ) : (            <span>未发布</span>          )}                     <span>答卷:{answerCount}</span>                     <span>{createAt}</span>        </div>      </div>      <div className={styled["button-container"]}>        <div className={styled.left}>          <button>编辑问卷</button>          <button>数据统计</button>        </div>        <div className={styled.right}>          <button>标星</button>          <button>复制</button>          <button>删除</button>        </div>      </div>    </div>  );};export default QuestionCard;
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表