create-react-app2.1,授權(quán)登陸,( ISO8061時間格式;UTC,GMT時間 ) ,動效,對象數(shù)組去重,字符集,base64轉(zhuǎn)碼,打包去掉.map文件

關(guān)鍵詞:
create-react-app2.1.1重大改變,授權(quán)登陸,( ISO8061時間格式;UTC,GMT時間 ) ,動效,對象數(shù)組去重,字符集,base64轉(zhuǎn)碼,打包去掉.map文件,location, encodeURIComponent,word-wrap, word-break, white-space, text-overflow,onScroll, scrollIntoView,嵌套路由,子路由,滾動平滑css屬性, background, proxy,redux-devtools-extension

(一) create-react-app 2.1

  • 默認支持sass和scss
    只需安裝node-sass即可( yarn add node-sass )

  • 默認支持css-modules
    scss文件命名需要加上module
    比如: login.module.scss

  • 如何開啟絕對路徑
    1.在根目錄下新建名為.env后綴的文件
    2.設(shè)置環(huán)境變量: NODE_PATH=src 即可把src目錄作為根目錄
    create-react-app的配置方式是它的webpack配置會自動選取'.env'文件并讀取'NODE_PATH'環(huán)境變量,然后可用于絕對導(dǎo)入.自定義環(huán)境變量在開發(fā)和生產(chǎn)過程中都可以使用,因為變量是在構(gòu)建時嵌入的,而不是運行時嵌入的,所以你的應(yīng)用程序可以通過'process.env'訪問它的環(huán)境
    https://www.imooc.com/article/37421

  • proxy的修改
    1.新版proxy代理只支持字符串模式了,如果是對象需要下載插件
    2.http-proxy-middleware
    (庫地址) https://github.com/chimurai/http-proxy-middleware
    (教程) https://blog.csdn.net/weixin_36094484/article/details/82968545

  • 如何使用less
    1.安裝less和less-loader
    cnpm install less less-loader --save
    2.修改webpack.config.dev.js和webpack.config.prod.js

在create-react-app中使用less


(1) 定義變量
// style files regexes
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;
const lessRegex = /\.less$/;     ------------------------------- 添加這兩行
const lessModuleRegex = /\.module\.(less)$/; ------------------- 添加這兩行

(2)配置module的rules
         {
            test: lessRegex,
            exclude: lessModuleRegex,
            use: getStyleLoaders({ importLoaders: 2 }, 'less-loader'),
          },
          {
            test: lessModuleRegex,
            use: getStyleLoaders(
              {
                importLoaders: 2,
                modules: true,
                getLocalIdent: getCSSModuleLocalIdent,
              },
              'less-loader'
            ),
          },
  • 如何引入antd,并按需加載
    1.安裝 cnpm install babel-plugin-import ( 用于按需加載組件代碼和樣式的 babel 插件 )
    2.在package.json中
    ------------或者webpack.config.dev,webpack.config.prod 中
    ------------或者自己新建.babelrc文件
如何引入antd,并按需加載


(1) 在package.json中添加:

 "plugins":[["import", {"libraryName": "antd", "style": "css"}]]

 "babel": {
   "presets": [
 "react-app"
     ],
    "plugins":[["import", {"libraryName": "antd", "style": "css"}]]     // 添加插件
 },

------------

(2) 在 webpack.config.dev(開發(fā)環(huán)境)和 webpack.config.prod 中
    {
            test: /\.(js|mjs|jsx|ts|tsx)$/,
            include: paths.appSrc,
            loader: require.resolve('babel-loader'),
            options: {
              customize: require.resolve(
                'babel-preset-react-app/webpack-overrides'
              ),
              plugins: [
                [
                  require.resolve('babel-plugin-named-asset-import'),
                  {
                    loaderMap: {
                      svg: {
                        ReactComponent: '@svgr/webpack?-prettier,-svgo![path]',
                      },
                    },
                  },
                ],
                // ["import", {"libraryName": "antd","libraryDirectory": "es","style": "css" }]  添加!??!
              ],
              // This is a feature of `babel-loader` for webpack (not Babel itself).
              // It enables caching results in ./node_modules/.cache/babel-loader/
              // directory for faster rebuilds.
              cacheDirectory: true,
              // Don't waste time on Gzipping the cache
              cacheCompression: false,
            },
          },
  1. 在package.json中修改 plugin
    "plugins": [
      [
        "import",
        {
          "libraryName": "antd",
          "libraryDirectory": "es",
          "style": true   ------------------------ 這里把css改為true
        }
      ]
    ]
  1. 在webpack.config.dev.js中修改getStyleLoaders()函數(shù)
const getStyleLoaders = (cssOptions, preProcessor) => {
  const loaders = [
    require.resolve('style-loader'),
    {
      loader: require.resolve('css-loader'),
      options: cssOptions,
    },
    {
      // Options for PostCSS as we reference these options twice
      // Adds vendor prefixing based on your specified browser support in
      // package.json
      loader: require.resolve('postcss-loader'),
      options: {
        // Necessary for external CSS imports to work
        // https://github.com/facebook/create-react-app/issues/2677
        ident: 'postcss',
        plugins: () => [
          require('postcss-flexbugs-fixes'),
          require('postcss-preset-env')({
            autoprefixer: {
              flexbox: 'no-2009',
            },
            stage: 3,
          }),
        ],
      },
    },
  ];
  if (preProcessor) {   ---------------------------------- 主要修改這里
    let loader = require.resolve(preProcessor);
    if (preProcessor === "less-loader") {  
      loader = {
        loader,
        options: {
          javascriptEnabled: true,   ------------------- 關(guān)鍵配置這里
        }
      }
      loaders.push(loader);
    }
  }
  return loaders;
};
  1. 新建them.less文件,在them.less中引入@import "~antd/dist/antd.less",再把them.less引入到項目的入口文件index.js中即可
them.less


@import "~antd/dist/antd.less";

@primary-color: #1890ff;                         // 全局主色
@link-color: #1890ff;                            // 鏈接色
@success-color: #52c41a;                         // 成功色
@warning-color: #faad14;                         // 警告色
@error-color: #f5222d;                           // 錯誤色
@font-size-base: 14px;                           // 主字號
@heading-color: rgba(0, 0, 0, .85);              // 標題色
@text-color: rgba(0, 0, 0, .65);                 // 主文本色
@text-color-secondary : rgba(0, 0, 0, .45);      // 次文本色
@disabled-color : rgba(0, 0, 0, .25);            // 失效色
@border-radius-base: 4px;                        // 組件/浮層圓角
@border-color-base: #d9d9d9;                     // 邊框色
@box-shadow-base: 0 2px 8px rgba(0, 0, 0, .15);  // 浮層陰影     
  • 如何開啟cssModules
如何開啟cssModules


import React from 'react';
import { Input, Form, Button  } from 'antd';
import S from './login.module.scss';           --------------------- 引入

const FormItem = Form.Item;


export default class Login extends React.Component {
  render() {
    return (
      <div className={S.login} >   ---------------------------------- 寫成對象的形式
        <Form>
          <FormItem>
            用戶名:<Input></Input>
          </FormItem>
          <FormItem>
            密碼:<Input></Input>
          </FormItem>
          <FormItem>
            <Button type="primary">登陸</Button>
          </FormItem>
        </Form>
      </div> 
    )
  }
}

redux-devtools-extension

import { createStore, combineReducers, applyMiddleware } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';


const totalReducers = {

};

const store = createStore(
    combineReducers({
      ...totalReducers
    }),
    composeWithDevTools(
      applyMiddleware(),
    )
  );

export default store;

(二) 授權(quán)登陸

auth2.0.jpg
QQ截圖20181020161556.png

(教程)http://www.cftea.com/c/2016/11/6703.asp

(豬八戒授權(quán)文檔)http://open.zbj.com/wiki/getWikiCategoryAll?wikiid=8#header

react-facebook-login 和 react-google-login

     <GoogleLogin
            clientId="6099641770..................apps.googleusercontent.com"
            redirectUri="https://tools............app"
            buttonText="LOGIN WITH GOOGLE"
            autoLoad={false}
            onSuccess={this.responseGoogle}
            onFailure={this.responseGoogle}
            // accessType="offline"
            // uxMode="redirect"
            uxMode="popup"
            className="google-content"
            style={{border: 'none'}}
     />

    responseGoogle = async(response) => {
      if (response.error) {
      // message.error(response.error, 2)
      return;
      } else {
      try {
        let accessToken = response.accessToken;
        const params = {
          acToken: accessToken,
          userType: 'STORE',
        }
        const res = await carbonLoginApi(googleGet(params)); // 用google獲取得token,換取本服務(wù)器token
        if ( res.status === 200 ) {
          const token = res.data.token;
          window.localStorage.setItem('token', token);
          // const meRes = await carbonLoginApi(profilesGet()); // 請求me接口,看是否需要修改密碼
          // if ( meRes.status === 200 ) {
          //   if (res.data.isNeedModifyPassword) {
          //     console.log('請重新設(shè)置密碼,')
          //   }
          // }
          this.props.history.push('/request')
        } 
      } catch (err) {
        message.error(err.message)
      }
    }
  }












(二) ISO8601標準時間格式 ---- UTC時間,GMT時間

--------- ISO 8601的標準格式是:YYYY-MM-DDTHH:mm:ss.sssZ
-----------------------------------------: year-month-dateThour:minute:second.millisecondZ
(1) utc時間
'2018-10-30T12:53:19.000Z'-------------這樣的時間符合iso8601時間標準
T:表示UTC時間,UTC時間又叫世界協(xié)調(diào)時間
Z:表示時區(qū)-----如果沒跟任何數(shù)字表示0時區(qū)( Z:時區(qū),可以是:Z(UFC)、+HH:mm、-HH:mm )
T 也可以用空格表示,但是這兩種表示有點不一樣,T 其實表示 UTC,而空格會被認為是本地時區(qū)(前提是不通過 Z 指定時區(qū))

> new Date('1970-01-01 00:00:00')   --------------------- 空格是本地時區(qū)
Thu Jan 01 1970 00:00:00 GMT+0800 (CST)

> new Date('1970-01-01T00:00:00')  ---------------------- T是utc時間
Thu Jan 01 1970 08:00:00 GMT+0800 (CST)

(2) gmt時間
'Thu Nov 01 2018 08:58:27 GMT+0800 '
GMT+0800 : 表示東八區(qū)時區(qū)------- new Date()得到的是GTM本地時間
(3) Date對象最重要的幾個方法

Date.prototype.valueOf() ------- 使用時間戳?xí)r,都用valueOf轉(zhuǎn)成時間戳提交到后端

valueOf方法返回實例對象距離時間零點(1970年1月1日00:00:00 UTC)對應(yīng)的毫秒數(shù),
該方法等同于getTime方法。

new Date( new Date().valueOf() )


new Date().valueOf -------------------------- 返回距離時間零點的毫秒數(shù)
返回:1541035593721


new Date( new Date().valueOf() )------------- 返回對應(yīng)的GMT時間
返回:Thu Nov 01 2018 09:27:02 GMT+0800
var d = new Date();

d.valueOf() // 1362790014817
d.getTime() // 1362790014817
Date.prototype.toString() ------- toString方法返回一個完整的日期字符串。
var d = new Date(2013, 0, 1);

d.toString()
// "Tue Jan 01 2013 00:00:00 GMT+0800 (CST)"
d
// "Tue Jan 01 2013 00:00:00 GMT+0800 (CST)"


d 和 d.toString()返回結(jié)果是一樣的,即 new Date()會自動調(diào)用toString()方法


( 因為toString是默認的調(diào)用方法,所以如果直接讀取Date實例,就相當于調(diào)用這個方法。 )
Date.prototype.toISOString() ------- 返回對應(yīng)的ISO8601格式的時間字符串
Date.prototype.toJSON() ------------- toJSON方法返回一個符合 JSON 格式的 ISO 日期字符串
toISOString() 和 toJSON()方法返回值是相等的

var d = new Date(2013, 0, 1);

d.toISOString()
// "2012-12-31T16:00:00.000Z"

d.toJSON()
// "2012-12-31T16:00:00.000Z"
moment.js
上周的開始時間UTC時間
const lastWeekStart = moment().subtract(1,"w").startOf('isoWeek').toDate().toJSON();
上周的結(jié)束時間UTC時間
const lastWeekEnd = moment().add(-1,"w").endOf('isoWeek').toDate().toJSON();




上個月的開始時間UTC時間
const lastMonthStart = moment().month(moment().month()-1).startOf('month').utc().format();
上個月的結(jié)束時間UTC時間
const lastMonthEnd = moment().month(moment().month()-1).endOf('month').utc().format();



----------
moment().subtract(Number, String); 減法 ---- 返回的是一個moment對象
moment().subtract(Number, String).toDate() ---- 返回get the native Date object,原時間對象
moment().subtract(Number, String).toISOString() ---- 返回ISO8601格式時間字符串
moment().subtract(1, 'days') === moment.add(-1, 'days')  減一天



moment().startOf('isoWeek'); ----- 返回ISO8601格式的moment對象
--- set to the first day of this week according to ISO 8601, 12:00 am







-----------------------------( isBetween )------------------------------------------------

moment().isBetween(moment-like, moment-like);
moment().isBetween(moment-like, moment-like, String);
// where moment-like is Moment|String|Number|Date|Array
// moment-like可以是一個Moment對象,字符串,數(shù)字....

moment('2010-10-20').isBetween('2010-01-01', '2012-01-01', 'year'); // false
moment('2010-10-20').isBetween('2009-12-31', '2012-01-01', 'year'); // true


( isBetween )
?。。。。。。?!
    const todayStart = moment().startOf('day');    -- 返回的是今天的開始時間的moment對象
    const todayEnd = moment().endOf('day');

    if ( moment(item.lastReplyAt).isBetween(todayStart, todayEnd) ) {    -- isBetween
      createTime = moment(item.lastReplyAt).format('h:mm a');
    } else {
      createTime = moment(item.lastReplyAt).format('MM / DD')  // 格式化成月/日
    }
!?。。。。。?!

目錄:

  1. 數(shù)組(對象)去重
    --- (1) 數(shù)組的reduce方法,沒重復(fù)push,重復(fù)不做任何操作
    --- (2) lodash庫的 _.uniqWith(array, _.isEqual);
  2. word-break 屬性
  3. word-wrap 屬性
  4. white-space 屬性
  5. text-overflow 屬性
  6. Element.scrollIntoView
  7. 嵌套路由,子路由
    https://blog.csdn.net/hsany330/article/details/78114805
  8. componentWillReceiveProps
    https://www.cnblogs.com/gdsblog/p/7348375.html
    https://blog.csdn.net/huanghanqian/article/details/80721575
  9. scrollHeight = scrollTop + clientHeight
    http://m.itdecent.cn/p/c14f85f109ee
    https://www.jb51.net/article/58688.htm
    onScroll事件 和 onWheel事件

8.1 scrollIntoView() ------------- 滾動當前元素到瀏覽器的可視區(qū)域
!! scrollIntoView()類似于 window.location.hash

  1. 滾動平滑css屬性
    scroll-behavior: smooth; -- 平滑
el.scrollIntoView(); // 等同于el.scrollIntoView(true)
el.scrollIntoView(false);

方法可以接受一個布爾值作為參數(shù)。
如果為true,表示元素的頂部與當前區(qū)域的可見部分的頂部對齊(前提是當前區(qū)域可滾動);
如果為false,表示元素的底部與當前區(qū)域的可見部分的尾部對齊(前提是當前區(qū)域可滾動)。
如果沒有提供該參數(shù),默認為true。
  1. 偽元素和偽類
    https://www.cnblogs.com/m2maomao/p/7744227.html
  2. 正則對象
  3. background
    background-color
    background-image
    background-image:url()

background-size -----------??!
background-size: cover拉伸圖片,有可能一部分會超出
bckground-size: contain縮放圖片,有可能一部分會出現(xiàn)空白,無法填充滿
http://www.w3school.com.cn/tiy/c.asp?f=css_background-size&p=8

background-position -----------??!
background-position: 第一個參數(shù)是水平位置,第二個參數(shù)垂直位置,如果規(guī)定了一個值,另一個值是50%
background-position: center center = background-position: center 是一樣的
background-position: 50% 50% = 0%表示左上角,100%表示右下角
http://www.w3school.com.cn/cssref/pr_background-position.asp

background-attachment
background-attachment : ( scroll , fixed )元素內(nèi)背景圖片是否隨元素滾動而移動
https://www.cnblogs.com/rain-null/p/7064136.html

background-repeat
background-origin
background-clip

  1. 動效(元素底部,從中間向兩邊組件變長的橫線)
html:
<div className="animate">animate test</div>



css:
.animate {
  position: relative;  // 父元素相對定位,!!偽類就當前元素的子元素
  display: inline-block;
}
.animate::after {     // 偽類相當于當前元素的子元素,只是不在dom中
  content:'';         // 一定要有內(nèi)容,否則偽元素不會被撐開
  position: absolute;
  left:0;             // 定位到父元素的底部
  bottom:0;
  height: 2px;
  background: blue;
  left: 50%;          // left和right都是50%,則偽類被擠壓到寬度是0,看不見了
  right: 50%;
  transition: all 0.5s;
  display: inline-block;
}
.animate:hover::after {
  content: '';
  position: absolute;
  height: 2px;
  background: blue;
  left: 0;
  right: 0;                // hove的時候,還原div的長度,正好是中間向兩邊擴散
  display: inline-block;
}
  1. 全局作用域 , 函數(shù)作用域 ------------------- 鏈式作用域
    函數(shù)內(nèi)部可以直接讀取全局變量
    函數(shù)外部無法讀取函數(shù)內(nèi)部聲明的變量
  2. lodash ----------------- isEqual
_.isEqual(value, other)  -------- 深度比較值是否相等

*值得類型可以是 數(shù)組,對象,等
*值得類型是對象時:不考慮繼承屬性(inherited: inherited是繼承的意思),只比較自身屬性

argument: 需要比較的兩個值
return:   返回一個布爾值

  1. 函數(shù)
    函數(shù)聲明時,如果使用表達式賦值給變量的形式,表達式后需要加分號,表示語句的結(jié)束。
  • 函數(shù)名視同變量名,存在函數(shù)名提升。(注意:是function關(guān)鍵字聲明的函數(shù)存在函數(shù)名提升,而采用變量賦值聲明的函數(shù),不存在函數(shù)名提升,而僅僅是提升變量)
  • 不能在 ( if ) 或者 ( try catch) 語句中聲明函數(shù),因為函數(shù)名存在變量提升,注意是function關(guān)鍵字聲明的函數(shù)
  • 函數(shù)的name屬性, length屬性, toString()方法
  • length屬性返回形參的個數(shù)
  • 函數(shù)的toString返回函數(shù)的源碼的字符串形式
  • 作用域:指變量存在的范圍
  • 對于var命令來說,局部變量只能在函數(shù)內(nèi)部聲明,在其他區(qū)塊中聲明的變量,都是全局變量
  • 函數(shù)本身也是一個值,也有自己的作用域,和變量一樣,函數(shù)的作用域是其聲明時所在的作用域,與其運行時的作用域無關(guān)
  • 函數(shù)執(zhí)行時的作用域,是函數(shù)定義時的作用域,而不是調(diào)用時的作用域
  • 很容易犯錯的一點是,如果函數(shù)A調(diào)用函數(shù)B,卻沒考慮到函數(shù)B不會引用函數(shù)A的內(nèi)部變量。
  • 函數(shù)內(nèi)部聲明的函數(shù),作用域綁定在函數(shù)內(nèi)部
  • 傳遞方式
    1. 傳值傳遞:函數(shù)的參數(shù)是原始類型的值( 數(shù)字,字符串,布爾值 ),是傳值傳遞,在函數(shù)內(nèi)部修改參數(shù)值,不會影響函數(shù)外部---------------------------- 原始值的拷貝
    2. 傳址傳遞:函數(shù)的參數(shù)是復(fù)合類型的值 (數(shù)組,對象,其他函數(shù)),是傳址傳遞,在函數(shù)內(nèi)部修改參數(shù)值,會影響函數(shù)外部---------------------------------- 原始值的地址
    3. 注意:函數(shù)內(nèi)部修改的不是參數(shù)對象的某個屬性,而是替換掉整個參數(shù),這時不會影響原始值
  • IIFE立即執(zhí)行函數(shù)
    function關(guān)鍵字出現(xiàn)在行首,一律解析成語句。所以function關(guān)鍵字出現(xiàn)在行首,認為是函數(shù)聲明語句,不該以()圓括號結(jié)尾。所以function(){}()會報錯
    (function(){}()); 或者(function(){})();----------------------注意分號是必須的
    以圓括號開頭,引擎認為圓括號后面跟的是表達式,就不會報錯
f();
var f = function (){};

---------------------------------- 等同于

var f;
f();
f = function () {};

(1) word-break 屬性

word-break :規(guī)定自動換行的處理方法

  • word-break: break-all 允許在單詞內(nèi)換行
  • word-break: keep-all 只能在半角空格或連字符處換行。

( 文字超出自動換行 ) https://blog.csdn.net/ysynhtt/article/details/44301461
( 文字超出自動換行 ) http://www.cnblogs.com/loya1015/p/5992366.html
中文在div中會自動換行,英文和數(shù)字不會,英文沒空格時會被認為是一個單詞,則不會換行

(2) word-wrap 屬性

word-wrap : 允許( 長單詞 )或者( url地址 )換行到下一行

  • word-wrap: break-word 在長單詞或 URL 地址內(nèi)部進行換行。

對比

word-wrap: break-word ------------------- 整個單詞一起被換行
word-break: break-all ---------------------- 單詞內(nèi)換行,單詞會被分開

(3) white-space 屬性

white-space 設(shè)置如何處理元素內(nèi)的空白

  • white-space: nowrap 文本不換行,文本會在同一行上繼續(xù),直到遇到 br 標簽為止
  • white-space: pre-wrap 保留空白符序列,但是正常地進行換行
  • white-space: pre-line 合并空白符序列,但是保留換行符
  • white-space: inherit 規(guī)定應(yīng)該從父元素繼承 white-space 屬性的值
  • herit: 是繼承的意思

(4) text-overflow 屬性

text-overflow 文本溢出的css

  • text-overflow: ellipsis 顯示省略符號來代表被修剪的文本。
  • text-overflow: string 使用給定的字符串來代表被修剪的文本。
  • text-overflow: clip 修剪文本。
  • clip是修剪得意思

https://blog.csdn.net/lpandeng/article/details/72885811
(顯示x行后,超出顯示...) https://www.cnblogs.com/like-xcm/p/5849630.html

超出設(shè)定大小的div后,文字顯示 省略號


html
<div className="ellipsis">
  sfdsdfasfsdfasdf good welllllllllllllllll hao djfksjdkfs fsadfas sdf sdf s df sdf  
</div>


css
.ellipsis {
  width: 100px;
  height: 60px;
  background: yellow;
  word-break: break-all;   // 單詞內(nèi)換行,會分開單詞
  word-wrap: break-word;  // 整個單詞都會被換行,不會被分開
  text-overflow: ellipsis; // 文字溢出,顯示省略號
  white-space: nowrap; // 不換行
  over-flow: hidden; // 這個一定不能忘了,否則不會顯示省略號  
}

(1) 數(shù)組(對象數(shù)組去重)

采用數(shù)組的reduce方法
Array.reduce((累計變量,當前變量,當前位置,原數(shù)組) => {...}, 累計變量初始值);
Array.reduce((cumulate, current, index) => {...}, initial )
第一個參數(shù)是:函數(shù),該函數(shù)又有4個參數(shù)
第二個參數(shù)是:累計變量的初始值
返回值: 返回值是最后一次的計算結(jié)果?。?!



let _arr = [
 {id:'1', name:'wang'},
 {id:'2', name:'li'},
 {id:'3', name:'zhang'},
 {id:'4', name:'wu'},
 {id:'1', name:'wang'},
];
let _obj = {};
let result = _arr.reduce((cumulate, current) => {
  let _radom = _obj[current.id] ? '' : _ojb[current.id] = true && cumulate.push(current);
  return cumulate
}, [])   // 注意:這里給累計變量的初始值是一個空數(shù)組
         // result就是去重后的數(shù)組 


解析:
(1) 在react中,三元表達式的返回值,需要賦給一個變量,不然此處會報錯

(2) 計算過程:
_ojb['1']不存在,就給_ojb['1']賦值為true (其他值也可以),并且往空數(shù)組中push對象{id:'1', name:'wang'},
...
...
_ojb['1']存在,則不做任何操作 ------------ 則重復(fù)項,并沒有push到累計變量數(shù)組中
最后:返回累積變量數(shù)組



--------------------------------------------

lodash
 
_.uniqWith( 重復(fù)項數(shù)組, _.isEqual) 返回值就是去重的數(shù)組

字符集

javascript使用unicode字符集,javascript內(nèi)部所有字符都使用unicode表示

base64轉(zhuǎn)碼

javascript原生提供兩個base64相關(guān)方法

  • 什么是base64:
    base64是一種編碼方法,可以將任意 轉(zhuǎn)換成 0~9, A~Z, a~z, +, /64個字符組成的可打印字符
  • 作用:
    不出現(xiàn)特殊字符,和加密
  • 使用場景:
  1. 文本包含一些不可打印的符號, 則可以使用base64編碼,轉(zhuǎn)成可打印的字符
  2. 以文本方式轉(zhuǎn)遞二進制數(shù)據(jù),可以使用base64編碼
btoa():任意值轉(zhuǎn)為 Base64 編碼

atob():Base64 編碼轉(zhuǎn)為原來的值


這兩個字符都不適合非 ASCII的字符
如: btoa('您好')會報錯 




function b64Encode(str) {
  return btoa(encodeURIComponent(str));
}
function b64Decode(str) {
  return decodeURIComponent(atob(str));
}
b64Encode('你好') // "JUU0JUJEJUEwJUU1JUE1JUJE"
b64Decode('JUU0JUJEJUEwJUU1JUE1JUJE') // "你好"

var x = '中文';
decodeURIComponent(atob(btoa(encodeURIComponent(x))))    // 輸出中文

react-create-app建立的項目把包去掉.map文件

  • map文件是幫助我們查看報錯的位置的。
  • map文件由devtool屬性控制,如果不想要map,注釋掉就可以,大約webpack.config.prod.js第57行;

一個完整的url地址

http://localhost:8080/a/b/c?a=1&b=2#abc

window.location

( http://localhost:8080/a/b/c?a=1&b=2#abc )

protocol協(xié)議:-------- 'http:'    注意包括:
hostname域名:-------- 'localhost'
host域名+端口:------- 'localhost:8080'      包括主機名,":"和端口號
hash:--------------- '#abc' #號開始的url
search:------------- '?a=1&b=2'  ?開始的部分
pathname: ------------ '/a/b/c'  當前 URL 的路徑部分,注意以 / 開頭
origin: -------------- 'http://localhost:8080'   返回url中完整的協(xié)議和主機地址部分,包括端口
herf:---------------- 'http://localhost:8080/a/b/c?a=1&b=2#abc'    完整的url

// query:-------------- 'a=1&b=2'  window.location中沒有query屬性

proxy

create-react-app中設(shè)置proxy
https://segmentfault.com/q/1010000008508440/a-1020000008516740

"proxy": "http://image.baidu.com"

 getData = async() => {
   const res = await axios.
   get('/channel/listjson?pn=0&rn=30&tag1=明星&tag2=全部&ie=utf8')
    .then(res => console.log(res))
 }

 說明:

(1) 上面訪問'/channel/listjson?pn=0&rn=30...'將被代理到下面的地址:
 ---------- "http://image.baidu.com/channel/listjson?pn=0&rn=30..."

(2) 所以在瀏覽器看來訪問的是'/channel/listjson?pn=0&rn=30...' 所以不會有跨域問題




------------

interceptor

axios中的攔截器

You can intercept requests or responses before they are handled by then or catch.
你可以在請求或者響應(yīng)的中,在then和catch方法前攔截請求



實例:

import axios from 'axios';
import { message } from 'antd';
const isDev = window.location.origin === '............'; 
const isLocalhost = window.location.origin === '.........................'; 
export const hostname = isDev || isLocalhost  ? '................' : '........................' ;


const _axios =  axios.create({
  baseURL: hostname,
  headers: {
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
});

_axios.interceptors.request.use(request => {     // 請求攔截
  const {token} = localStorage;
  if (token) {
    request.headers.token = token;
  }
  return request;
}, error => Promise.reject(error) )

_axios.interceptors.response.use(response => {   // 響應(yīng)攔截
  return response; 
}, error => {
  if (error.response) {
    switch(error.response.status) {
      case 401:
        {
          message.config({
            maxCount: 1,
          });
          message.error('Login expired, please login again');
          window.location.href = '#/login';
          break;
        }
      case 500:
        {
          message.error('Network Error');
          break;
        }  
      default:
        break;  
    }
  }
  return  Promise.reject(error) 
})

export default _axios;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • HTML 5 HTML5概述 因特網(wǎng)上的信息是以網(wǎng)頁的形式展示給用戶的,因此網(wǎng)頁是網(wǎng)絡(luò)信息傳遞的載體。網(wǎng)頁文件是用...
    阿啊阿吖丁閱讀 4,983評論 0 0
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML標準。 注意:講述HT...
    kismetajun閱讀 28,886評論 1 45
  • 老實說,我其實是個完全沒有自信的人。 我們平時見到的那些自信滿滿的人,在我看來,要么從小就在良好的環(huán)境下成長,受到...
    白羽君閱讀 322評論 0 0
  • 燦爛年華里的傷(一) 對于季憶來說,現(xiàn)在的她最渴望不是一份美妙的愛情,而是一份真誠的友情。 ...
    邱蕤閱讀 270評論 0 1

友情鏈接更多精彩內(nèi)容