亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

react搭建后臺(tái)管理(react初窺)

wangjuntytl / 766人閱讀

摘要:前言以前一直是用進(jìn)行的開發(fā)于是決定年后弄一弄所以年后這段時(shí)間也就一直瞎弄可算是看到成果了本來(lái)是想寫一個(gè)類似仿今日頭條那樣的項(xiàng)目來(lái)入手后來(lái)又尋思還不如寫個(gè)后臺(tái)管理呢。于是乎自己便著手簡(jiǎn)單的搭建了一個(gè)集中設(shè)置的版本。

前言

以前一直是用vue進(jìn)行的開發(fā), 于是決定年后弄一弄react, 所以年后這段時(shí)間也就一直瞎弄react, 可算是看到成果了

本來(lái)是想寫一個(gè) 類似 Vue仿今日頭條 那樣的項(xiàng)目來(lái)入手, 后來(lái)又尋思還不如寫個(gè)后臺(tái)管理呢。
于是乎便開始搗鼓起來(lái)了。

用到react相關(guān)的生態(tài)鏈模塊:

react

react-dom

react-router-dom: react-router4以后 好像都是用這個(gè)東西了

react-transition-group: 用來(lái)做動(dòng)畫的

redux: 用來(lái)管理全局狀態(tài)

react-redux: 用來(lái)管理全局狀態(tài)

redux-actions: 用來(lái)創(chuàng)建action的,而且生成相關(guān)reducers的時(shí)候也不要寫 switch/case 或 if/else 了,主要是方便。

redux-thunk: redux的中間件, 用來(lái)處理我們異步action

antd: 隨便找的一個(gè)比較常用的react-UI庫(kù)

跟react相關(guān)的主要就是這個(gè)幾個(gè)了
至于webpack 配置,基本跟以前配置vue的基本沒(méi)多大區(qū)別。

文件目錄講解:

build: 用來(lái)放置關(guān)于webpack的配置

config: 項(xiàng)目配置

src: 源碼

static: 靜態(tài)資源

.babelrc: babel配置

postcss.config.js: css配置

別的目錄就不說(shuō)了,主要介紹一個(gè)src下的目錄結(jié)構(gòu)

actions: 放redux中action相關(guān)的地方

reducers: 放redux中reducer相關(guān)的地方

assets: 項(xiàng)目靜態(tài)資源

components: 常用的公共組件

router: 路由相關(guān)的配置

store: redux的配置

styles: 公共樣式文件

utils: 工具類的封裝

view: 所有頁(yè)面的主體結(jié)構(gòu)

main.js: 項(xiàng)目入口文件

config.js: 公共屬性配置

1. react 的 幾種書寫方式

React.createClass

import React from "react"
const MyComponent = React.createClass({
   render () {
       return (
           

我是React.createClass生成的組件

) } })

React.createClass會(huì)自綁定函數(shù)方法(不像React.Component只綁定需要關(guān)心的函數(shù))導(dǎo)致不必要的性能開銷,增加代碼過(guò)時(shí)的可能性

React.createClass的mixins不夠自然、直觀;

React.Component

import React from "react"
class MyComponent from React.Component {
    render () {
        return (
            

我是React.Component生成的組件

) } }

需要手動(dòng)綁定this指向

React.Component形式非常適合高階組件(Higher Order Components--HOC),它以更直觀的形式展示了比mixins更強(qiáng)大的功能,并且HOC是純凈的JavaScript,不用擔(dān)心他們會(huì)被廢棄

無(wú)狀態(tài)函數(shù)式組件

import React from "react"
 const MyComponent = (props) => (
     

我是無(wú)狀態(tài)函數(shù)式組件

) ReactDOM.render(, mountNode)

無(wú)狀態(tài)組件的創(chuàng)建形式使代碼的可讀性更好,并且減少了大量冗余的代碼,精簡(jiǎn)至只有一個(gè)render方法,大大的增強(qiáng)了編寫一個(gè)組件的便利

組件不會(huì)被實(shí)例化,整體渲染性能得到提升

組件不能訪問(wèn)this對(duì)象

組件無(wú)法訪問(wèn)生命周期的方法

無(wú)狀態(tài)組件只能訪問(wèn)輸入的props,同樣的props會(huì)得到同樣的渲染結(jié)果,不會(huì)有副作用

2. 路由攔截

路由攔截這塊費(fèi)了挺長(zhǎng)時(shí)間,本來(lái)是想找個(gè)類似vue的beforeRouter這個(gè)種鉤子函數(shù),發(fā)現(xiàn)沒(méi)有。

然后后面找到history模塊,發(fā)現(xiàn)有個(gè)這東西有個(gè)監(jiān)聽路由的方法,最開始就用這它,但是我突然切成hash模式進(jìn)行開發(fā)的時(shí)候,發(fā)現(xiàn)通過(guò)history.push(path, [state])設(shè)置state屬性的時(shí)候出了問(wèn)題,這東西好像只能給history模式設(shè)置state屬性,但是我有部分東西是通過(guò)設(shè)置state屬性來(lái)進(jìn)來(lái)的,于是便放棄了這個(gè)方法尋找新的方法。

后面發(fā)現(xiàn)可以通過(guò)監(jiān)聽根路徑的 componentWillReceiveProps 鉤子函數(shù) 便可以達(dá)到監(jiān)聽的效果。

這鉤子函數(shù)只要props改變便會(huì)觸發(fā),因?yàn)槊看吻袚Q路由 locationpathname總是不同的,所有只要切換路徑便會(huì)觸發(fā)這個(gè)這個(gè)鉤子函數(shù)。這東西容易觸發(fā)死循環(huán),所以記得做好判斷。

class MainComponents extends React.Component {
    componentWillMount () { // 第一次進(jìn)來(lái)觸發(fā)
        this.dataInit(this.props)
    }
    componentWillReceiveProps(nextProps){ // 以后每次變化props都會(huì)觸發(fā)
        // 如果死循環(huán)了 可能是某個(gè)屬性設(shè)置會(huì)更新props上屬性,所以導(dǎo)致一直循環(huán),這個(gè)時(shí)候記得做好判斷
        this.dataInit(nextProps)
    }
    render () {
        // 404
        if (!isExistPath(allRoutes, pathname)) return 
        
        //當(dāng)前路徑路由信息
        let currRoute = getRoute(allRoutes, pathname)

        // 非白名單驗(yàn)證
        if (!whiteList.some(path => path === pathname)) {

            // 登錄驗(yàn)證
            if (!Cookie.get("Auth_Token")) {
                return 
            }
            
            // 獲取用戶信息
            if (!user) {
                this.getUserInfo(() => {
                    this.setRoutesByRole(this.props.user.roles)
                })
            }
        }
        // 401
        if (user && currRoute) {
            if (!isAuth(currRoute.role, user)) return 
        }

        // 網(wǎng)頁(yè)title
        document.title = currRoute.name
    }
}
3. 路由集中設(shè)置

用過(guò)vue的都知道我們一般都是通過(guò)new Router({routes}) 來(lái)集中管理路由表。但是react-router好像不能這么設(shè)置。最新的版本好像連嵌套都不行。
于是乎自己便著手簡(jiǎn)單的搭建了一個(gè)集中設(shè)置的版本 。不過(guò)后面我看到個(gè)插件好像是可以管理的 react-router-config,不過(guò)我也還沒(méi)試過(guò),也不知道可不可行。

// 路由表
const allRoutes = [
  {
    path: "/auth",
    login: true,
    layout: true,
    icon: "user",
    name: "權(quán)限管理",
    role: ["admin"],
    component: _import_views("Auth")
  },
  {
    path: "/error",
    login: true,
    layout: true,
    icon: "user",
    name: "ErrorPage",
    redirect: "/error/404",
    children: [
        { path: "/error/404", component: _import_views("Error/NotFound"), name: "404"},
        { path: "/error/401", component: _import_views("Error/NotAuth"), name: "401"}
    ]
  }
  ...
]


// 根目錄

    


// MainComponents
class MainComponents extends React.Component {
  render () {
    return (
      
          {renderRouteComponent(allRoutes.filter(route => !route.layout))} //不需要側(cè)邊欄等公共部分的路由頁(yè)面
          
      
    )
  }
}

// ComponentByLayout
const ComponentByLayout = ({history}) => (
  
      
          {renderRouteComponent(allRoutes.filter(route => route.layout))}
      
     
)


// 路由渲染
const RouteComponent = route =>  
const renderRouteComponent = routes => routes.map((route, index) => {
    return route.children ? route.children.map(route => RouteComponent(route)) : RouteComponent(route)
})
4. 根據(jù)用戶權(quán)限動(dòng)態(tài)生成路由

我想根據(jù)用戶不同的權(quán)限生成不同的側(cè)邊欄。

{
  path: "/auth",
  login: true,
  layout: true,
  icon: "user",
  name: "權(quán)限管理",
  role: ["admin"],
  component: _import_views("Auth")
}

根據(jù)這個(gè)路由role信息 跟用戶的role信息匹配進(jìn)行顯示跟隱藏

這樣來(lái)篩選出符合這個(gè)用戶的路由表以及側(cè)邊欄(側(cè)邊欄根據(jù)路由表生成)

但是有個(gè)問(wèn)題,因?yàn)槲覀兪切枰卿洸拍艿弥脩舻臋?quán)限信息,所以我們得那個(gè)時(shí)候才能確定路由是哪些。

但是那個(gè)時(shí)候路由已經(jīng)設(shè)置完畢了。vue里面的提供了 router.addRoutes這個(gè)方法來(lái)供我們動(dòng)態(tài)設(shè)置路由,react里面我也沒(méi)找到關(guān)于這個(gè)api的,于是我便采取所有的路由都注冊(cè)一遍,但是這樣便產(chǎn)生一個(gè)問(wèn)題。

/auth 為例,我本身是沒(méi)有訪問(wèn)/auth的權(quán)限,所以我側(cè)邊欄不會(huì)生成 /auth這個(gè)列表選項(xiàng)。但是我們?cè)诘刂窓诶锩?訪問(wèn) /auth 是能進(jìn)入這個(gè)頁(yè)面的的 (最好的辦法就是壓根就不生成這個(gè)路由)。所以這個(gè)設(shè)置其實(shí)是有問(wèn)題,目前我也沒(méi)知道怎么動(dòng)態(tài)生成路由的辦法,暫時(shí)也只是在根目錄 做了權(quán)限處理

5. 按需加載

按需加載的方法也不少,目前只嘗試了第一種,因?yàn)槲覍慥ue也是用import實(shí)現(xiàn)按需加載的,所以也就沒(méi)去折騰了。

1. import方法
//asyncComponent.js
import React from "react"
export default loadComponent => (
    class AsyncComponent extends React.Component {
        state = {
            Component: null,
        }
        async componentDidMount() {
            if (this.state.Component !== null) return

            try {
                const {default: Component} = await loadComponent()
                this.setState({ Component })
            }catch (err) {
                console.error("Cannot load component in ");
                throw err
            }
        }

        render() {
            const { Component } = this.state
            return (Component) ?  : null
        }
    }
)


// index.js
import asyncComponent from "./asyncComponent.js"
const _import_ = file => asyncComponent(() => import(file))
_import_("components/Home/index.js")

原理很簡(jiǎn)單:

import()接受相應(yīng)的模塊然后返回Promise對(duì)象

asyncComponent 接收一個(gè)函數(shù),且這個(gè)函數(shù)返回promise對(duì)象

在componentDidMount鉤子函數(shù)通過(guò) async/await 執(zhí)行接受進(jìn)來(lái)的loadComponent方法,得到import返回的結(jié)果,賦值給state.Component,

因?yàn)槲覀僫mport的是一個(gè)React組件,所以我們得到的也是React組件,到時(shí)候只需要把該組件 render出去就行了

2. Bundle組件 + import(跟第一種感覺差不多) 3. react-loadable 4. bundle-loader 6. request

我這里用到的是axios, 用axios做了個(gè)簡(jiǎn)單的攔截器

import axios from "axios"
import qs from "qs"


axios.defaults.withCredentials = true 

// 發(fā)送時(shí)
axios.interceptors.request.use(config => {
    // 發(fā)起請(qǐng)求,可以進(jìn)行動(dòng)畫啥的
    return config
}, err => {
    return Promise.reject(err)
})

// 響應(yīng)時(shí)
axios.interceptors.response.use(response => response, err => Promise.resolve(err.response))

// 檢查狀態(tài)碼
function checkStatus(res) { 
    // 得到返回結(jié)果,結(jié)束動(dòng)畫啥的
    if (res.status === 200 || res.status === 304) {
        return res.data
    }
    return {
        code: 0,
        msg: res.data.msg || res.statusText,
        data: res.statusText
    }
    return res
}


// 檢查CODE值
function checkCode(res) {
    if (res.code === 0) {
        throw new Error(res.msg)
    }
    
    return res
}

export default {
    get(url, params) {
        if (!url) return
        return axios({
            method: "get",
            url: url,
            params,
            timeout: 30000
        }).then(checkStatus).then(checkCode)
    },
    post(url, data) {
        if (!url) return
        return axios({
            method: "post",
            url: url,
            data: qs.stringify(data),
            timeout: 30000
        }).then(checkStatus).then(checkCode)
    }
}
7. redux

這里主要用了 redux-actions 來(lái)創(chuàng)建action的 ,
原生寫法

// action
const addTodo = text => ({
    type: "ADD_TODO",
    payload: {
      text,
      completed: false
    }
})

// reducer
const todos = (state = [], action) => {
    switch(action.type) {
        case "ADD_TODO":
            return [...state, action.payload]
        ...
        default:
            return state
    }
}

用了 redux-actions的寫法

import { createAction, handleActions } from "redux-actions"

// action
const addTodo = createAction("ADD_TODO")

// reducer
const todos = handleActions({
    ADD_TODO: (state, action) => {
        return [...state, action.payload]
    }
    ...
}, [])

// 用redux-actions簡(jiǎn)單明了

8. connect

用了redux,這東西基本就不能少了, connect主要是用來(lái) 連接 組件redux store的, 就是讓組件能獲取redux store里面的 方法
connect([mapStateToProps], [mapDispatchToProps], [mergeProps],[options])

一般只用到前兩個(gè)參數(shù)

mapStateToProps(state, ownProps): 獲取store里面state指定數(shù)據(jù),然后傳遞到指定組件, ownProps 組件本身的 props

mapDispatchToProps: 這個(gè)是獲取store里面的action方法, 然后傳入指定組件

用法

import toggleTodo from "actions/todo"
const mapStateToProps = state => ({
    active: state.active
})
const mapDispatchToProps = {
    onTodoClick: toggleTodo
}
connect(mapStateToProps, mapDispatchToProps)(Component)
// 在Component組件中, 便能在 props 里面獲取到 active 數(shù)據(jù), 跟 onTodoClick 這個(gè)方法了

connect很多地方基本都要用到
所以也進(jìn)行了封裝

// connect.js
import actions from "src/actions" // 所有action
import {connect} from "react-redux" 
import {bindActionCreators} from "redux"
export default connect(
    state => ({state}), // 偷懶了, 每次把state里面所有的數(shù)據(jù)都返回了
    dispatch => bindActionCreators(actions, dispatch) //合并所有action,并且傳入dispatch, 那樣我們?cè)诮M件里面調(diào)用action,就不在需要dispatch了
)

bindActionCreators

然后我們把 connect.js 文件通過(guò) webpack 的alias屬性來(lái)進(jìn)行配置

//配置別名映射
alias: {
    "src": resolve("src"),
    "connect": resolve("src/utils/connect")
}

然后我們就可以在文件中如下引用

import React from "react"
import connect from "connect"

@connect // 通過(guò)裝飾器調(diào)用
class Component extends React.Component {
  componentWillMount () {
    const {state, onTodoClick} = this.props
    console.log(state, onTodoClick)
  }
}

為了省事,我把store里面所有的數(shù)據(jù) 和 action都返回了。

9. cssModules

vue 中 我們一般都是通過(guò)設(shè)置 style標(biāo)簽的 scoped 屬性來(lái)做到css模塊化
但是在 react 中,我采用的 cssModules 來(lái)做css模塊化

通過(guò)webpack設(shè)置 css-loadermodules來(lái)開啟css的模塊化

{
    loader: "css-loader",
    options: {
      modules: true, //是否開啟
      localIdentName: "[name]__[local]___[hash:base64:5]"  // 轉(zhuǎn)化出來(lái)的class名字結(jié)構(gòu)
    }
},

引入css, 并通過(guò)對(duì)象的賦值方式添加className

import styles from "./styles.css"

export default () => (
  
) //styles.css .a { color: #ff4747; }

或者可以通過(guò) react-css-modules 來(lái)更方便的控制class類名

import styles from "./styles.css"
import CSSModules from "react-css-modules"

class Component extends React.Component {
  render () {
    return (
      
) } } export default CSSModules(Component, styles, { allowMultiple: true //允許多個(gè)class一起使用 }) //styles.css .a { color: #ff4747; } .b { background: #f00; }

這樣我們就可以通過(guò)字符串的方式傳入 class類名. 注意: 我們添加時(shí) 不再使用 className 了, 而是使用 styleName

10. 雙向綁定的實(shí)現(xiàn)
class Bingding extends React.Component {
  state = {
    value: ""
  }
  handleInput = value => {
    this.setState({
      value
    })
  }
  render () {
    return (
       {this.handleInput(e.target.value)}}/>
      
{this.state.value}
) } }

就是通過(guò) onChange 事件 來(lái)觸發(fā) this.setState 重新渲染 render 方法

還有一些知識(shí)點(diǎn)
包括 動(dòng)畫,生命周期 等等
就不過(guò)多介紹了。這些項(xiàng)目中基本多多少少都參和了一點(diǎn)。
開發(fā)中遇到的問(wèn)題挺多的,最主要是react-router配置的問(wèn)題,怎么配置都感覺不太好。
也同時(shí)希望有人推薦幾個(gè)全面的尤其是最新版本的react開源項(xiàng)目。

項(xiàng)目啟動(dòng)步驟

npm/yarn run dll (DllPlugin打包,只需打包一次就夠了)

npm/yarn run dev (開發(fā)模式)

npm/yarn run build (生產(chǎn)模式)

小結(jié)

國(guó)內(nèi)比較火的兩個(gè)框架,也勉強(qiáng)算是都接觸了下,vue我是一直在用的,react算是年后剛接觸的。
從我目前來(lái)看,vuereact開發(fā)起來(lái)確實(shí)要方便很多(可能用的比較多吧)。
因?yàn)?b>vue很多常用的都是內(nèi)置的。而react基本都要自己去尋找對(duì)應(yīng)的模塊。本身就只提供UI, 其他基本得自力更生。
主要是你經(jīng)常一找能找著多個(gè)模塊,你就不知道用哪個(gè),還得一個(gè)個(gè)試水。當(dāng)然,react的社區(qū)強(qiáng)大,這么都不是什么大問(wèn)題。

在線觀看地址

博客地址

github

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/93427.html

相關(guān)文章

  • 初窺基于 react-art 庫(kù)的 React Native SVG

    摘要:語(yǔ)法更近似于移動(dòng)端。當(dāng)參數(shù)為兩個(gè)時(shí),等同于,繪制光滑二次貝塞爾曲線。有些精通的同學(xué)這時(shí)候可能就要問(wèn)我了,不對(duì)啊,二次貝塞爾曲線和光滑三次貝塞爾曲線的參數(shù)都是個(gè),你這里沒(méi)有光滑三次啊因?yàn)殚_發(fā)的同學(xué)留坑沒(méi)寫了呀微笑。和則是用于指定旋轉(zhuǎn)的原點(diǎn)。 技術(shù)背景 在移動(dòng)應(yīng)用的開發(fā)過(guò)程中,繪制基本的二維圖形或動(dòng)畫是必不可少的。然而,考慮到Android和iOS均有一套各自的API方案,因此采用一種更普...

    xiaowugui666 評(píng)論0 收藏0
  • 好程序員React精品項(xiàng)目全集:商城管理后臺(tái)(視頻+源碼+筆記)

    摘要:今天給大家?guī)?lái)了好程序員實(shí)戰(zhàn)項(xiàng)目商城管理后臺(tái)。配合項(xiàng)目學(xué)習(xí)會(huì)讓你更快掌握它的使用方法下面就來(lái)看看好程序員這套實(shí)戰(zhàn)項(xiàng)目課程介紹好程序員項(xiàng)目本項(xiàng)目是一個(gè)使用開發(fā)的商城系統(tǒng)的管理后臺(tái),里面登錄判斷,接口調(diào)用,數(shù)據(jù)展示和編輯,文件上傳等后臺(tái)功能。 眾所周知,項(xiàng)目經(jīng)驗(yàn)對(duì)于一個(gè)程序員變得越來(lái)越重要。在面...

    李世贊 評(píng)論0 收藏0
  • React項(xiàng)目實(shí)踐系列一

    摘要:在此我們選用用友的公共靜態(tài)資源庫(kù)。因此打算建立遠(yuǎn)程的其實(shí)還有個(gè)關(guān)鍵是我使用用友配的電腦開發(fā),在本地部署的話電腦配置。。。不過(guò)此步驟我們也可以省略了,用友的大前端技術(shù)團(tuán)隊(duì)提供了平臺(tái)。 數(shù)據(jù)分析平臺(tái)-實(shí)踐系列一 項(xiàng)目創(chuàng)建于2018年1月底,到現(xiàn)在已經(jīng)接近半年,在此寫下半年來(lái)項(xiàng)目的實(shí)踐過(guò)程以及自己對(duì)前端的學(xué)習(xí)與體悟。 技術(shù)選型 框架: React 路由: React-Router 4 狀態(tài)管...

    DC_er 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<