美文网首页
简书项目相关

简书项目相关

作者: 泡杯感冒灵 | 来源:发表于2022-03-30 18:15 被阅读0次
react项目创建以及运行
  1. 先安装 npm install create-react-app --save
  2. 创建项目 npx create-react-app my-app
  3. cd my-app
  4. npm start
组件里引入的css文件,其他组件是通用的,也就是说,不同组件引入的样式文件,有可能会产生冲突。这个时候需要我们引入第三方工具styled-components
  1. 安装 npm install styled-components --save
  2. 创建style.js文件,里边可以通过createGlobalStyle创建一些全局样式
import { createGlobalStyle } from 'styled-components';
// 比如reset.css可以写在这里 
// 这里用的reset.css是 https://meyerweb.com/eric/tools/css/reset/
export const GlobalStyle  = createGlobalStyle`
  html, body, div, span, applet, object, iframe,
  h1, h2, h3, h4, h5, h6, p, blockquote, pre,
  a, abbr, acronym, address, big, cite, code,
  del, dfn, em, img, ins, kbd, q, s, samp,
  small, strike, strong, sub, sup, tt, var,
  b, u, i, center,
  dl, dt, dd, ol, ul, li,
  fieldset, form, label, legend,
  table, caption, tbody, tfoot, thead, tr, th, td,
  article, aside, canvas, details, embed, 
  figure, figcaption, footer, header, hgroup, 
  menu, nav, output, ruby, section, summary,
  time, mark, audio, video {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
  }
  /* HTML5 display-role reset for older browsers */
  article, aside, details, figcaption, figure, 
  footer, header, hgroup, menu, nav, section {
    display: block;
  }
  body {
    line-height: 1;
  }
  ol, ul {
    list-style: none;
  }
  blockquote, q {
    quotes: none;
  }
  blockquote:before, blockquote:after,
  q:before, q:after {
    content: '';
    content: none;
  }
  table {
    border-collapse: collapse;
    border-spacing: 0;
  }
`;
  • 然后在index.js里引入使用
import {GlobalStyle} from './style.js';

ReactDOM.render(
  <React.StrictMode>
    <GlobalStyle/>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);
用styled-components创建局部样式,需要用styled-components的组件 styled
import styled from 'styled-components';

// 这里的意思是,创建HeaderWrapper这样一个组件
// HeaderWrapper本质是div这样一个标签,下边是标签的样式
// 注意,需要把组件导出
export const HeaderWrapper = styled.div`
    height:56px;
    background:red;
`
  • 使用HeaderWrapper这个组件
import React ,{Component} from 'react';
import {HeaderWrapper} from './style';
class Header extends Component {
    render(){
        return (
            <HeaderWrapper>header</HeaderWrapper>
        )
    }
}

export default Header;
可以在src目录下,创建statics文件夹,用来存放静态资源,比如图片。
  • 存放的图片该怎么用呢?
// 先引入
import logoPic from '../../statics/logo.png';

// style.js
export const Logo = styled.a`
    position:absolute;
    top:0;
    left:0;
    display:block;
    width:100px;
    height:56px;
    background:url(${logoPic});
`
  • 如果这个图片可以跳转,该怎么写跳转地址呢?
// 方法1
<HeaderWrapper>
      <Logo href='/'/>
</HeaderWrapper>

// 方法2 attrs方法,接收一个对象,对象里设置href
export const Logo = styled.a.attrs({
    href:'/'
})`
    position:absolute;
    top:0;
    left:0;
    display:block;
    width:100px;
    height:56px;
    background:url(${logoPic});
    background-size:contain;
`
iconfont引入项目
  • iconfont创建项目,找图标后,下载至本地


    image.png
  • 解压缩后,把iconfont命名的文件,复制到statics文件夹下,最好是statics里再创建一个文件夹,比如iconfont,然后把iconfont.css改为iconfont.js。


    image.png
  • 因为图标是通用的,所以,可以用createGlobalStyle创建为全局样式。特别需要注意,url后边的路径要改为./开头。
import { createGlobalStyle } from 'styled-components';
export const IconStyle  = createGlobalStyle`
  @font-face {
    font-family: "iconfont"; /* Project id 3282899 */
    src: 
        url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAQgAAsAAAAACDQAAAPRAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHFQGYACDHAqDaINEATYCJAMQCwoABCAFhGcHPxtDBxEVnBHJfh7Y4DLlUlc4pBDD8IhG80ed0hKdLn2/g+fRjno/ycxmMwvwLFZgCaADvOiPrpbVqdLc/5y2bOypvqqg62TJswzeD/DPpeAGbtHzc3tVaigDcnJGbWJcvsSBVFoj0zuU3UpaAfr7PNfklaXItwOARSV1PR8e2NkK6EAXWYR7ez7nmW8Yu7iMcxDA0YwuqF59IhIAMYumN1QBMjBoVIGwXBbNL84FWNaKKSkXLIJfd6xBduGB2qx+gJ3u+6WWFmJB4Wm0RYbNCSwAlFR0KrvrjSHQn7ApCLC9AjxAA41mZpd55d4ZaD/RCI3L+46hDWCxKKigok2lbxhC+aq0VveBav3jiY9WGgVAK5jUUIFJQEFFGwIaKrvLT2AtA4AFIoCjHfgA5maxv0Iw0dndETY5mLjJ0pZ1fV9Vz02TjXmwdDeNaXTh2K4S9uzr+dBb396NXhw/v2nlm9z5NF1wiLJykWTtlZB4oDj4/Kgmt5yS19mW5LEW/5KYEuOuUcJjQrzFukUdu0xf2r7+FgvXx433gFg3JmqUWxiMn7DEQx1LS8m9QZfgxJW4LU+6m8Yee925OiVen7DxFpTlXXl8ss+ioSFgwhA5xgl/jmbx1NTRRrWeyeowZXCwMkx9hURIFIiihiv+ryfbZnE7ZucOZYgy2Fucksocjfpdh5WNyy9+i8IcgvV0Lb5/d8DLosymg/7+Gw9Wh0UMyQM9X/inSl8cU9ayXzOn/uClE1jRQ9K4cHGAD1O9ILg9taWktiql0tleYhendLB7jZ2SOX11il66wpjQnJvLukQlgXrMKPWyQP50Wdnw5tJUvO5NqpVJpdjJwcBubr9ZYxt+mMl/Moq/F+ewDICw7qG+QUij3gSgS/SrbkfDNXM/Wmyn3zY4zKov8+/nuoGQ6dSXviqZJH2xukk1SY0cBGPylKb8Z9F1j+SgAKc74E1mIIEvffgTIXQLlpVBKCLIhMZSwDCcBvAIaAEfS2c4GtJ7ckCikJQ+YiKBOjwBCHHcoIjhLjRxvDMMp4VHCn/wieMfjjESPV9AHbHmHA1CG8wreFYSM8NALt0NOkVo8KzoAXnuwTDIgpRMrzFG3sWA/OQoRAwYTyJY0c0wDBNIeeKjRYJLlM5EkeW9RLCSqDOHgxgQiA1gcgXwsEiIYTY5xT9vA+JQEGLAazIOCU6OB+kDMgJSDcZaG9eqOJNFck44KBAEA2BwkIoAVqwbCaVEApDmt/JBLAgBt0UsZYaok7G6WmF8fXR5mwCHdqQRJVqMePgr0eCWO16VxM7ViHvdjU4HAAAA') format('woff2'),
        url('./iconfont.woff?t=1648626401195') format('woff'),
        url('./iconfont.ttf?t=1648626401195') format('truetype'),
        url('./iconfont.svg?t=1648626401195#iconfont') format('svg');
  }

  .iconfont {
    font-family: "iconfont" !important;
    font-size: 16px;
    font-style: normal;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }
`;
  • 然后,就可以通过各种方式展示了,比如Unicode 、Fontclass、Symbol
<i className="iconfont">&#xe636;</i>
经过拆分后,Header组件就变得非常明晰了。
image.png
  • 首先style.js里放的是组件里所有的样式。
import styled from 'styled-components';
import logoPic from '../../statics/logo.png';

// 这里的意思是,创建HeaderWrapper这样一个组件
// HeaderWrapper本质是div这样一个标签,下边是标签的样式
export const HeaderWrapper = styled.div`
    height:56px;
    border-bottom:1px solid #f0f0f0;
    position:relative;
`

export const Logo = styled.a.attrs({
    href:'/'
})`
    position:absolute;
    top:0;
    left:0;
    display:block;
    width:100px;
    height:56px;
    background:url(${logoPic});
    background-size:contain;
`
export const Nav = styled.div`
   width:960px;
   height:100%;
   padding-right:50px;
   margin:0 auto;
   box-sizing:border-box;
`

export const NavItem = styled.div`
  line-height:56px;
  padding:0 15px;
  font-size:17px;
  color:#333;
  &.left{
      float:left;
  }
  &.right{
      float:right;
      color:#969696;
  }
  &.active{
      color:#ea6f5a;
  }
`
export const NavSearch = styled.input.attrs({
    placeholder:'搜索'
})`
    width:160px;
    height:38px;
    padding:0 30px 0 20px;
    margin-top:9px;
    margin-left:20px;
    box-sizing:border-box;
    border:none;
    outline:none;
    border-radius:19px;
    background:#eee;
    font-size:14px;
    color:#666;
    &::placeholder{
        color:#999;
    }
    &.focused{
        width:240px;
    }
    &.slide-enter{
        transition:all .2s ease-out;
    }
    &.slide-enter-active{
        width:240px;
    }
    &.slide-exit{
        transition:all .2s ease-out;
    }
    &.slide-exit-active{
        width:160px;
    }
`

export const Addition = styled.div`
    position:absolute;
    right:0;
    top:0;
    height:56px;
`

export const Button = styled.div`
    float:right;
    line-height:38px;
    border-radius:19px;
    margin-right:20px;
    padding:0 20px;
    margin-top:9px;
    border:1px solid #ec6149;
    font-size:14px;
    &.reg{
        color:#ec6149;
    }
    &.writting{
        color:#fff;
        background:#ec6149;
    }
`

export const SearchWrapper = styled.div`
    position:relative;
    float:left;
    .iconfont{
        position:absolute;
        right:5px;
        bottom:5px;
        width:30px;
        line-height:30px;
        border-radius:15px;
        text-align:center;
        &.focused{
            background:#777;
            color:#fff;
        }
    }
    
`
  • index.js是Header组件的整体的内容,里边包含了一个UI组件(负责渲染页面上的样式),和一个容器组件(负责处理页面上的数据和逻辑)。


    image.png
    image.png
  • 组件里要存放是内容(这里是focused),都是放在store下的reducer里
import * as constants from './constants';

const defaultState = {
    focused:false
};

export default (state = defaultState,action) => {
    if(action.type === constants.SEARCH_FOCUS){
        const newState = JSON.parse(JSON.stringify(state));
        newState.focused = true;
        return newState;
    }
    if(action.type === constants.SEARCH_BLUR){
        const newState = JSON.parse(JSON.stringify(state));
        newState.focused =false;
        return newState;
    }
    return state
}
  • 所以,一个组件和它相关的页面展示的内容,包括数据的内容,都统一放在Header文件夹下,以后拆分和管理会更方便。出了什么BUG,定位问题也更便捷。
利用create-react-app的特性,来创建模拟数据
  • 在public文件夹下创建一个api文件夹,里边先创建一个headerList.json

  • 我们通过http://localhost:3000/api/headerList.json可以访问到headerList.json里的内容。原理是利用create-react-app的特性。

    image.png
  • create-react-app的底层也是一个node的服务器,当我们去访问api下边的headerList.json的时候,它会先到工程目录下有没有对应的路由,如果找不到,它还会到public目录下去找这个路由,如果它发现public下有api这个目录,同时api这个目录下有headerList.json这个文件,它就会把api这个目录下headerList.json这个文件的内容输出出来。通过这个特性,我们可以在public这个目录下,写一些假的数据。

  • 常见的做法就是,后端接口开发出来之前,可以先在public目录下创建一个API目录,里边放一些假数据,然后上线之前,再把API这个文件夹删除掉,然后当上线或者跟后端联调的时候,因为API这个文件夹已经不存在了,请求的时候,就会以接口的内容为主了。

注意,如果我们通过fromJS方法把一个JS对象转换为immutable对象后,那么这个immutable对象里的属性如果也是immutable对象,比如defaultState的list数组。当我们在改变list的时候,就要注意,不要用普通对象去赋值list了,同样要用immutable对象给它赋值。
const defaultState = fromJS({
    focused:false,
    list:[]
});

  • changelist 接收data后,创建一个action,这个action的data属性的值也是一个immutable对象

const changelist = (data) => ({
    type:constants.CHNAGE_LIST,
    data:fromJS(data)
})
  • dispatch把changelist创建的action,派发给store,store结合原来的数据和这个action传给reducer.
export const getList = () => {
    return (dispatch) => {
        axios.get('/api/headerList.json').then((res)=>{
            const data = res.data;
            dispatch(changelist(data.data));
        }).catch(()=>{
            console.log('error')
        })
    }
}
  • reducer里state通过set方法修改list的时候,action.data也是一个immutable对象
export default (state = defaultState,action) => {
    if(action.type === constants.SEARCH_FOCUS){
        return state.set('focused',true);
    }
    if(action.type === constants.SEARCH_BLUR){
        return state.set('focused',false);
    }
    if(action.type === constants.CHNAGE_LIST){
        return state.set('list',action.data);
    }
    return state
}
如果我在组件上传一个url,然后想把这个url用到background的url里怎么办?这个时候需要借助styled-components的一个props语法
            // 组件上定义imgUrl并赋值
            <RecommendWrapper>
               <RecommendItem imgUrl="https://test.png"/>
            </RecommendWrapper>

            // styled.js
            export const RecommendItem = styled.div`
                  width:280px;
                  height:50px;
                  background:url(${(props)=>props.imgUrl});
                  background-size:contain;
            `
                      

相关文章

  • 简书项目相关

    react项目创建以及运行 先安装 npm install create-react-app --save 创建项...

  • 初次使用Markdown

    标签(空格分隔): markdown、简书 ---yiweiwoshiniya 最近项目需要授权时候跳转到相关的设...

  • 简书相关

    1-31新增: 编辑器好像对markdown的无序列表和有序列表混排识别有些问题? 1. 2. 3. 4. - -...

  • 预热 | 「风语」

    一个简书相关的新项目即将进入内测阶段,名为「风语」,Slogan 未定。 目前暂不透露项目具体领域。

  • 最全的简书贝疑问收集-持续更新(非官方)

    为了方便大家了解简书贝,解答简书贝的相关疑惑,将简书贝相关的问题收集于此。大家可以将简书贝的相关问题在评论中写下来...

  • Fountain社群 Q&A

    项目信息相关 1.简书也做区块链平台了? Fountain并不是简书做的区块链平台,Fountain是一个开放的共...

  • 简书更新计划

    计划将简书更新的内容分为 1.项目管理相关内容 2.一建考试相关内容 3.品牌追溯相关内容 4.其它学习相关内容 ...

  • 简书,一股情爱风弥漫

    最近项目没那么忙,打开简书,发现好多标题都是和爱情、出轨相关的文章,难道简书不是不是一个学习知识、提高技能的地方吗...

  • Android—RecyclerView进阶(1)—Layout

    我的CSDN: ListerCi我的简书: 东方未曦 RecyclerView是项目中使用最为频繁的控件之一,相关...

  • 给Java开发者的Flutter开发基础---Dart语言

    接近半年没有在简书冒泡了。这段时间一是忙于使用云信IM开发相应项目,二是整理和收集相关Flutter的相关资料进行...

网友评论

      本文标题:简书项目相关

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