从零开始构建react和vue项目工程总结

647 阅读5分钟

前端开发无论选择哪个框架,项目开始初始化之前,要先安装node,安装完成后通过node -v 来检查版本号,如果正确显示,就意味着安装成功。即可往下看。。。

1.react从零开始配置项目结构

项目开始初始化:(极简版)

第一步:安装create-react-app

npm install -g create-react-app

第二步:安装结束后,创建一个项目工程

create-react-app react-app

第三步:打开目录

cd react-app

第四步:安装依赖

npm install

第五步:npm start

npm start

第六步:配置路由

npm i react-router-dom --save

在src创建一个文件夹router/index.js

  • 1.由于项目的react-router为 "react-router-dom": "^5.2.0", 因此使用 hashHistory, 从react-router-dom 会报错Attempted import error: 'hashHistory' is not exported from 'react-router'. 于是,请注意 4.0版本后应如下写法
  • 2.Router组件的history属性,用来监听浏览器地址栏的变化,并将URL解析成一个地址对象,供 React Router 匹配。

1》hashHistory,路由将通过URL的hash部分(#)切换,URL的形式类似example.com/#/some/path

2》如果设为browserHistory,浏览器的路由就不再通过Hash完成了,而显示正常的路径example.com/some/path,背后调用的是浏览器的History API。

3》createMemoryHistory主要用于服务器渲染。它创建一个内存中的history对象,不与浏览器URL互动 const history = createMemoryHistory(location)

配置内容如下

import React from 'react';
import {HashRouter, Route, Switch} from 'react-router-dom';
import Home from '../views/home/index';
import Family from '../views/family/index';
import { createHashHistory } from 'history';
const hashHistory = createHashHistory();

const BasicRoute = () => (
    <HashRouter history={hashHistory}>
        <Switch>
            <Route exact path="/" component={Home}/>
            <Route exact path="/family" component={Family}/>
        </Switch>
    </HashRouter>
);


export default BasicRoute;

第七步:修改默认配置 we npm install react-app-rewired customize-cra --save

  • 修改package.json
/* package.json */
"scripts": {
-   "start": "react-scripts start",
+   "start": "react-app-rewired start",
-   "build": "react-scripts build",
+   "build": "react-app-rewired build",
-   "test": "react-scripts test",
+   "test": "react-app-rewired test",
}
  • 然后在项目根目录创建一个 config-overrides.js 用于修改默认配置
module.exports = function override(config, env){
  // do staff with the webpack config...
  return config
}

第八步:配置按需加载

npm install babel-plugin-import --save

  • babel-plugin-import 是一个用于按需加载组件代码和样式的 babel 插件(原理),现在我们尝试安装它并修改 config-overrides.js 文件。

  • 修改config-overrides.js文件:

const { override, fixBabelImports } = require('customize-cra')
module.exports = override(
  fixBabelImports('import',{
    libraryName: 'antd', // 或其他第三方组件库名称
    libiaryDirectory: 'es', // 组件位置
    style: 'css',
  })
)

第九步:配置less

npm install less less-loader --save

const { override, fixBabelImports, addLessLoader } = require('customize-cra')
module.exports = override(
  fixBabelImports('import',{
    libraryName: 'antd', // 或其他第三方组件库名称
    libiaryDirectory: 'es', // 组件位置
    style: true,
  }),
  addLessLoader({
    javascriptEnabled: true,
  })
)
  • 注意:若提示this.getOptions is not a function
  • 解决方案:1. npm uninstall less-loader 命令卸载原版本的 less-loader,然后 通过 npm install less-loader@5.0.0 命令下载降级版本的 less-loader

第十步:配置 UI 库-antd

npm install antd --save

在文件中引入

import React from 'react';
import { Button } from 'antd';
import "./index.less";

export default class Home extends React.Component {
    constructor(props) {
        super(props);
    }
    
    render() {
        return (
            <div className="home-pages">
                home
                <Button type="primary">Button</Button>
                <button onClick={() => this.props.history.push('family')}>
                通过函数跳转</button>
            </div>
        )
    }
}

第十一步:配置axios 及跨域问题

  • 配置axios 在src目录下建立文件 services /index.js
import axios from "axios";

const instance = axios.create({
  
})

// 请求拦截
// 所有的网络请求都会先走这个方法,我们可以在它里面添加一些自定义内容
instance.interceptors.request.use(function (config) {
    config.headers.token = '111111';
    return config;
}, function (err) {
    return Promise.reject(err);
});

// 响应拦截
// 所有的网络请求返回数据之后都会先执行此方法
// 此处可以根据服务器的返回状态码作相应的数据 404 401 500
instance.interceptors.response.use(function (response) {
 
    return response;
}, function (err) {
    return Promise.reject(err);
});


export function get(url, params) {
    return instance.get(url, { params });

}

export function post(url, data) {
    return instance.post(url, data);
}

export function del(url, data) {
    return instance.delete(url, data);
}

export function put(url, data) {
    return instance.put(url, data)
}


在项目中使用home/index.js

import React from 'react';
import { Button } from 'antd';
import * as Api from "../../services/index";

import "./index.less";

export default class Home extends React.Component {
    constructor(props) {
        super(props);
    }
    
    componentDidMount(){
        this.queryUser();
    }
    async queryUser() {
        const res=await Api.get('/by-api/bd/fam/list',{type:'1',userId:'111'})
        console.log('res',res);        
      }
    
  
    render() {
        return (
            <div className="home-pages">
                home
                <Button type="primary">Button</Button>
                <button onClick={() => this.props.history.push('family')}>通过函数跳转</button>
            </div>
        )
    }
}
  • 2.跨域问题 在package.json 中添加如下写法,配置自己的后端地址 "proxy": "http://111.33.34.45:8080"

参考访问 blog.csdn.net/DengZY926/a…

第十二步:配置 redux 安装react-redux redux redux-thunk src下新建文件夹 store/index.js

import { createStore ,combineReducers,compose,applyMiddleware} from "redux";

import thunk from "redux-thunk";
import product from "./reducers/notice"
import notice from "./reducers/product";

const rootReducer = combineReducers({product,notice});

const store = createStore(rootReducer,applyMiddleware(thunk))
export default store;

app.js中添加如下

import { BrowserRouter, Route,Navigate,Routes,Outlet } from 'react-router-dom';
import './App.css';
import 'antd/dist/antd.css';
import { Provider } from 'react-redux';
import {mainRouters,adminRouters} from "routers/index"
import Layout from 'components/Layout/index'
import store from 'store/index';
function App() {
 const routerRender=(routers)=>{
  return routers?.map((item)=>{
    return <Route key={item.path} {...item}>{item.children&&item.children.length>0? routerRender(item.children):null}</Route>
  })
 }

  return (
    <Provider store={store}>
        <BrowserRouter>
            <Routes>    
              {/* 渲染登陆路由 */}
              {adminRouters.map((item)=>{
                  return <Route key={item.path} {...item}></Route>
              })} 
              <Route path="/" element={<Layout><Outlet /></Layout>}>
              {routerRender(mainRouters)}
              </Route> 
               <Route path="*" element={<Navigate to="/404"/>} /> 
            </Routes>
        </BrowserRouter>
    </Provider>
  );
}

export default App;

store中 reducers中的notice.js中添加如下

const notices = (state={isAllRead:false,count:0},anction)=>{
    switch(anction.type){
        case "Read_All":
        return {...state,isAllRead:true};
        default:
        return{state};

    }
}
export default notices;

此方案能实现 但是和以前用过的方式不一样 记录一下

参考访问:segmentfault.com/a/119000002…

第十三步:使用 localStorage

如果是json
存:localStorage.setItem("list",JSON.stringify(res.data)) 
取:JSON.parse(localStorage.getItem("list")

如果不是json 则不需要 JSON.stringifyJSON.parse 

最后生成目录如下:

具体github地址如下:https://github.com/zhangqiqi-engineer/react-redux-demo

2.vue从零开始配置项目结构

项目开始初始化:

第一步:安装vue-cli

   npm install vue-cli -g     
   // 全局安装 vue-cli
   vue list   
   // 检查 vue-cli安装是否成功 ,需要检查vue 
   

第二步: 创建一个新项目工程,

   vue create vue-demo1 

第三步:切换到vue-demo1目录

    cd vue-demo1 

第四步:安装依赖

    npm install 
   

第五步:运行项目

    npm run serve

第六步:安装路由

    npm install vue-router
    

在src目录下建立router文件夹,建立index.js文件并在目录下书写

    import Vue from 'vue'
    import Router from 'vue-router'
    import Index from '../components/Index'
    import Login from '../components/Login'
    
    const originalPush = Router.prototype.push
    Router.prototype.push = function push(location) {
        return originalPush.call(this, location).catch(err => err)
    }
    
    Vue.use(Router)
    
    export default new Router({
        routes: [
            {
                path: '/',
                name: 'Index',
                component: Index
            },
            {
                path: "/login",
                component: Login,
                name: 'Login',
            },
        ]
    })

在app.vue中引入

        <template>
          <div id="app">
            <!-- <router-link to="/">home</router-link>
            <router-link to="/login">Login</router-link>-->
            <v-container>
              <router-view></router-view>
            </v-container>
          </div>
        </template>
        
        <script>
        export default {
          name: "App"
        };
        </script>
        
        <style>
        #app {
          font-family: Avenir, Helvetica, Arial, sans-serif;
          -webkit-font-smoothing: antialiased;
          -moz-osx-font-smoothing: grayscale;
          color: #2c3e50;
        }
        </style>


第七步: 安装vuex (根据自身需要)

    vue add vuex
    

在 store中会生成如下文件

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    export default new Vuex.Store({
      state: {
        count: 0,
      },
      mutations: {
        // 同步
      },
      actions: {
        // 异步
      },
      modules: {
      }
    })

第八步:引入 ant-design-vue (根据自身需要)

    npm install ant-design-vue --save
    
    

在main.js中添加

    import Vue from 'vue'
    import App from './App.vue'
    import Antd from 'ant-design-vue'
    import router from './router/index'
    
    import 'ant-design-vue/dist/antd.css'
    Vue.use(Antd)
    
    Vue.config.productionTip = false
    
    new Vue({
      router,
      render: h => h(App),
    }).$mount('#app')
    

生成如下项目结构

项目结构中文件解释:

1.项目工程名字

2.依赖包

3.页面title图标

4.打包后生成文件的入口

5.图片资源存放该文件下

6.所有组件存放在components

7.store状态管理

8.所有组件的汇集

9.整个工程的入口

10.描述文件

11.项目工程说明

12..gitignore 默认集成git 可以忽略上传文件

13.babel.config.js 语法版本的控制