01-React(脚手架+MVC/MVVM+JSX)

news2024/10/7 6:41:16

使用 create-react-app 构建React工程化项目


安装 create-react-app

$ npm i create-react-app -g 「mac需要加sudo」

基于脚手架创建项目「项目名称需要符合npm包规范」

$ create-react-app xxx

目录结构:

|- node_modules 包含安装的模块

|- public 页面模板和IconLogo

|- favicon.ico

|- index.html

|- src 我们编写的程序

|- index.jsx 程序入口「jsx后缀名可以让文件支持jsx语法」

|- package.json

|- ...

package.json

{

...

"dependencies": {

...

"react": "^18.2.0", //核心

"react-dom": "^18.2.0", //视图编译

"react-scripts": "5.0.1", //对打包命令的集成

"web-vitals": "^2.1.4" //性能检测工具

},

"scripts": {

"start": "react-scripts start", //开发环境启动web服务进行预览

"build": "react-scripts build", //生产环境打包部署

"test": "react-scripts test", //单元测试

"eject": "react-scripts eject" //暴露配置项

},

"eslintConfig": { //ESLint词法检测

"extends": [

"react-app",

"react-app/jest"

]

},

"browserslist": { //浏览器兼容列表

"production": [

">0.2%",

"not dead",

"not op_mini all"

],

"development": [

"last 1 chrome version",

"last 1 firefox version",

"last 1 safari version"

]

}

}
默认情况下,会把webpack配置项隐藏到node_modules中,如果想修改,则需要暴露配置项:
$ yarn eject
/* package.json中的变化 */

{

"dependencies":{ //暴露后,webpack中需要的模块都会列在这

...

},

"scripts": {

"start": "node scripts/start.js",

"build": "node scripts/build.js",

"test": "node scripts/test.js"

//不在基于react-scripts处理命令,而是直接基于node去执行对应的文件

//已经没有eject命令了

},

"jest": {

//单元测试配置

},

"babel": { //关于babel-loader的额外配置

"presets": [

"react-app"

]

}

}


/* 新增的内容 */

|- scripts

|- start.js

|- build.js

|- ...

|- config

|- webpack.config.js

|- paths.js

|- ...

真实项目中常用的一些修改操作
配置less

*

默认安装和配置的是sass,如果需要使用less,则需要:

1. 安装

$ yarn add less less-loader@8

$ yarn remove sass-loader

2. 修改webpack.config.js

*/

// 72~73

const lessRegex = /\.less$/;

const lessModuleRegex = /\.module\.less$/;


//507~545

{

test: lessRegex,

exclude: lessModuleRegex,

use: getStyleLoaders(

...

'less-loader'

)

},

{

test: lessModuleRegex,

use: getStyleLoaders(

...

'less-loader'

),

}

配置别名

//313

resolve: {

...

alias: {

'@': path.appSrc,

...

}

}

配置预览域名

// scripts/start.js

// 48

const HOST = process.env.HOST || '127.0.0.1';

// 也可以基于 cross-env 设置环境变量

配置跨域代理

再src下新建 setupProxy.js文件

/*

安装 http-proxy-middleware

$ yarn add http-proxy-middleware

src/setupProxy.js

*/

const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {
    app.use(
        createProxyMiddleware("/jian", {
            target: "https://www.jianshu.com/asimov",
            changeOrigin: true,
            ws: true,
            pathRewrite: { "^/jian": "" }
        })
    );

    app.use(
        createProxyMiddleware("/zhi", {
            target: "https://news-at.zhihu.com/api/4",
            changeOrigin: true,
            ws: true,
            pathRewrite: { "^/zhi": "" }
        })
    );
};

//测试地址:

//https://www.jianshu.com/asimov/subscriptions/recommended_collections

//https://news-at.zhihu.com/api/4/news/latest

配置浏览器兼容

//package.json

//https://github.com/browserslist/browserslist

"browserslist": {

"production": [

">0.2%",

"not dead",

"not op_mini all"

],

"development": [

"last 1 chrome version",

"last 1 firefox version",

"last 1 safari version"

]

}


/*

CSS兼容处理:设置前缀

autoprefixer + postcss-loader + browserslist

JS兼容处理:ES6语法转换为ES5语法

babel-loader + babel-preset-react-app(@babel/preset-env) + browserslist

JS兼容处理:内置API

入口配置react-app-polyfill

*/

import 'react-app-polyfill/ie9';

import 'react-app-polyfill/ie11';

import 'react-app-polyfill/stable';

其余的一些优化配置、响应式布局的配置等,实战中再去处理!!

MVC/MVVM


笔记总结:

当前以及未来的前端开发,一定是:组件化/模块化
  @1 有利于团队协作开发
  @2 便于组件的复用:提高开发效率、方便后期维护、减少页面中的冗余代码
  ...

如何划分组件
  业务组件:针对项目需求封装的
    @1 普通业务组件「没有啥复用性,只是单独拆出来的一个模块」
    @2 通用业务组件「具备复用性」
  功能组件:适用于多个项目「例如:UI组件库中的组件」
    @1 通用功能组件

因为组件化开发,必然会带来“工程化”的处理
  也就是基于webpack等工具「vite/rollup/turbopack...」
  + 实现组件的合并、压缩、打包等
  + 代码编译、兼容、校验等
  + ...

==================
React的工程化/组件化开发
  我们可以基于webpack自己去搭建一套工程化打包的架子,但是这样非常的麻烦/复杂;React官方,为我们提供了一个脚手架:create-react-app!!
    + 脚手架:基于它创建项目,默认就把webpack的打包规则已经处理好了,把一些项目需要的基本文件也都创建好了!!

1. create-react-app基础运用
  安装脚手架 
    $ npm i create-react-app -g  「mac前面要设置sudo」
    检查安装情况 
    $ create-react-app --version
  
  基于脚手架创建React工程化的项目
    $ create-react-app 项目名称
      + 项目名称要遵循npm包命名规范:使用“数字、小写字母、_”命名
    项目目录
      |- node_modules
      |- src:所以后续编写的代码,几乎都放在SRC下「打包的时候,一般只对这个目录下的代码进行处理」
         |- index.js
      |- public:放页面模板
         |- index.html
      |- package.json
      |- ...
    
  一个React项目中,默认会安装:
    react:React框架的核心
    react-dom:React视图渲染的核心「基于React构建WebApp(HTML页面)」
         ---> react-native:构建和渲染App的
    react-scripts:脚手架为了让项目目录看起来干净一些,把webpack打包的规则及相关的插件/LOADER等都隐藏到了node_modules目录下,react-scripts就是脚手架中自己对打包命令的一种封装,基于它打包,会调用node_modules中的webpack等进行处理!!

==================
React是Web前端框架
  1.目前市面上比较主流的前端框架
    + React
    + Vue
    + Angular「NG」
    + ...
    主流的思想:不在直接去操作DOM,而是改为“数据驱动思想”
    操作DOM思想:
      + 操作DOM比较消耗性能「主要原因就是:可能会导致DOM重排(回流)/重绘」
      + 操作起来也相对来讲麻烦一些
      + ...
    数据驱动思想:
      + 我们不会在直接操作DOM
      + 我们去操作数据「当我们修改了数据,框架会按照相关的数据,让页面重新渲染」
      + 框架底层实现视图的渲染,也是基于操作DOM完成的
        + 构建了一套 虚拟DOM->真实DOM 的渲染体系
        + 有效避免了DOM的重排/重绘
      + 开发效率更高、最后的性能也相对较好

  2. React框架采用的是MVC体系;Vue框架采用的是MVVM体系;
    MVC:model数据层 + view视图层 + controller控制层
      @1 我们需要按照专业的语法去构建视图(页面):React中是基于jsx语法来构建视图的
      @2 构建数据层:但凡在视图中,需要“动态”处理的(需要变化的,不论是样式还是内容),我们都要有对应的数据模型
      @3 控制层:当我们在视图中(或者根据业务需求)进行某些操作的时候,都是去修改相关的数据,然后React框架会按照最新的数据,重新渲染视图,以此让用户看到最新的效果!
      数据驱动视图的渲染!!
      视图中的表单内容改变,想要修改数据,需要开发者自己去写代码实现!!
      “单向驱动”
    MVVM:model数据层 + view视图层 + viewModel数据/视图监听层
      @1 数据驱动视图的渲染:监听数据的更新,让视图重新渲染
      @2 视图驱动数据的更改:监听页面中表单元素内容改变,自动去修改相关的数据
      “双向驱动”

==================
JSX构建视图的基础知识
  JSX:javascript and xml(html) 把JS和HTML标签混合在了一起「并不是我们之前玩的字符串拼接」
  @1 vscode如何支持JSX语法「格式化、快捷提示...」
    + 创建的js文件,我们把后缀名设置为jsx即可,这样js文件中就可以支持JSX语法了
    + webpack打包的规则中,也是会对.jsx这种文件,按照JS的方式进行处理的
  @2 在HTML中嵌入“JS表达式”,需要基于“{} 胡子语法”
    + JS表达式:执行有结果的
  @3 在ReactDOM.createRoot()的时候,不能直接把HTML/BODY做为根容器,需要指定一个额外的盒子「例如:#root」
  @4 每一个构建的视图,只能有一个“根节点”
    + 出现多个根节点则报错 Adjacent JSX elements must be wrapped in an enclosing tag.
    + React给我们提供了一个特殊的节点(标签):React.Fragment 空文档标记标签
      <></>
      既保证了可以只有一个根节点,又不新增一个HTML层级结构!!
  @5 {}胡子语法中嵌入不同的值,所呈现出来的特点
    + number/string:值是啥,就渲染出来啥
    + boolean/null/undefined/Symbol/BigInt:渲染的内容是空
    + 除数组对象外,其余对象一般都不支持在{}中进行渲染,但是也有特殊情况:
      + JSX虚拟DOM对象
      + 给元素设置style行内样式,要求必须写成一个对象格式
    + 数组对象:把数组的每一项都分别拿出来渲染「并不是变为字符串渲染,中间没有逗号」
    + 函数对象:不支持在{}中渲染,但是可以作为函数组件,用<Component/>方式渲染!!
    + ...
  @6 给元素设置样式
    + 行内样式:需要基于对象的格式处理,直接写样式字符串会报错
      <h2 style={{
        color: 'red',
        fontSize: '18px' //样式属性要基于驼峰命名法处理
      }}>
    + 设置样式类名:需要把class替换为className
      <h2 className="box">

==================
import React from 'react'; //React语法核心
import ReactDOM from 'react-dom/client'; //构建HTML(WebApp)的核心

//获取页面中#root的容器,作为“根”容器
const root = ReactDOM.createRoot(document.getElementById('root'));

//基于render方法渲染我们编写的视图,把渲染后的内容,全部插入到#root中进行渲染
root.render(
    ....
);

 

React起步式:MVC & JSX


MVC VS MVVM

JSX基础知识

/*

* JSX:javascript and xml(html)

* 1.最外层只能有一个根元素节点

* 2.<></> fragment空标记,即能作为容器把一堆内容包裹起来,还不占层级结构

* 3.动态绑定数据使用{},大括号中存放的是JS表达式

* => 可以直接放数组:把数组中的每一项都呈现出来

* => 一般情况下不能直接渲染对象

* => 但是如果是JSX的虚拟DOM对象,是直接可以渲染的

* 4.设置行内样式,必须是 style={{color:'red'...}};

* 设置样式类名需要使用的是className;

* 5.JSX中进行的判断一般都要基于三元运算符来完成

* 6.JSX中遍历数组中的每一项,动态绑定多个JSX元素,一般都是基于数组中的map来实现的

* =>和vue一样,循环绑定的元素要设置key值(作用:用于DOM-DIFF差异化对比)

* JSX语法具备过滤效果(过滤非法内容),有效防止XSS攻击(扩展思考:总结常见的XSS攻击和预防方案?)

*/

JSX底层渲染机制

createElement
const createElement = function createElement(type, props, ...children) {

// virtual:[ˈvɜːtʃuəl]

let len = children.length;

let virtualDOM = {

type,

props: {}

};

if (props !== null) virtualDOM.props = { ...props };

if (len === 1) virtualDOM.props.children = children[0];

if (len > 1) virtualDOM.props.children = children;

return virtualDOM;

};

render

const render = function render(virtualDOM, container) {

let { type, props } = virtualDOM;

if (typeof type === "string") {

let element = document.createElement(type);

for (let key in props) {

if (!props.hasOwnProperty(key)) break;

if (key === 'className') {

element.setAttribute('class', props[key]);

continue;

}

if (key === 'style') {

let styOBJ = props['style'];

for (let attr in styOBJ) {

if (!styOBJ.hasOwnProperty(attr)) break;

element.style[attr] = styOBJ[attr];

}

continue;

}

if (key === 'children') {

let children = props['children'];

if (!Array.isArray(children)) children = [children];

children.forEach(item => {

if (typeof item === "string") {

element.appendChild(document.createTextNode(item));

return;

}

render(item, element);

});

continue;

}

element.setAttribute(key, props[key]);

}

container.appendChild(element);

}

};

JSX使用:

import React from 'react';
import ReactDOM from 'react-dom/client';

const root = ReactDOM.createRoot(document.getElementById('root'));

/* 需求二:从服务器获取了一组列表数据,循环动态绑定相关的内容 */
let data = [{
    id: 1,
    title: '欢迎大家学习'
}, {
    id: 2,
    title: '期望大家可以把React学好'
}, {
    id: 3,
    title: '大家有问题可以随时找我'
}];

root.render(
    <>
        <h2 className="title">今日新闻</h2>
        <ul className="news-box">
            {data.map((item, index) => {
                /* 循环创建的元素一定设置key属性,属性值是本次循环中的“唯一值”「优化DOM-DIFF」 */
                return <li key={item.id}>
                    <em>{index + 1}</em>
                    &nbsp;&nbsp;
                    <span>{item.title}</span>
                </li>;
            })}
        </ul>

        <br />

        {/* 扩展需求:没有数组,就是想单独循环五次 */}
        {new Array(5).fill(null).map((_, index) => {
            return <button key={index}>
                按钮{index + 1}
            </button>;
        })}
    </>
);


/* 需求一:基于数据的值,来判断元素的显示隐藏 */
/* let flag = false,
    isRun = false;

root.render(
    <>
        {/!* 控制元素的display样式:不论显示还是隐藏,元素本身都渲染出来了 *!/}
        <button style={{
            display: flag ? 'block' : 'none'
        }}>按钮1</button>

        <br />

        {/!* 控制元素渲染或者不渲染 *!/}
        {flag ? <button>按钮2</button> : null}

        <br />

        <button>{isRun ? '正在处理中...' : '立即提交注册'}</button>
    </>
); */

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/169539.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

79.循环神经网络的从零开始实现

从头开始基于循环神经网络实现字符级语言模型。 这样的模型将在H.G.Wells的时光机器数据集上训练。 和之前一样&#xff0c; 我们先读取数据集。 %matplotlib inline import math import torch from torch import nn from torch.nn import functional as F from d2l import to…

Rockchip开发系列 - 9.watchdog看门狗

By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! 目录 dts中的watchdog节点watchdog驱动文件TRM watchdog:WDT框图功能描述计数器中断系统复位复位脉冲长度操作流程图寄存器描述寄存器设置…

Nessus Host Discovery

系列文章 Nessus介绍与安装 Nessus Host Discovery 1.启动nessus cd nessus sh qd_nessus.sh2.进入nessus网站 https://192.168.3.47:8834/3.点击【New Scan】 4.选择【Host Discovery】 5.输入name【主机发现】&#xff0c;Description【主机发现】&#xff0c;Targets【…

Android 蓝牙开发——服务启动流程(二)

首先我们要知道&#xff0c;主要系统服务都是在 SystemServer 启动的&#xff0c;蓝牙也是如此&#xff1a; 1、SystemServer 源码路径&#xff1a;/frameworks/base/services/java/com/android/server/SystemServer.java private void startOtherServices(NonNull TimingsT…

labelme(2)json文件转类别灰度图

首先感谢大佬&#xff1a;https://blog.csdn.net/tzwsg/article/details/114653071一、上代码&#xff0c;json2gray.py&#xff1a;#!/usr/bin/python # -*- coding: UTF-8 -*- # !H:\Anaconda3\envs\new_labelme\python.exe import argparse import json import os import os…

go语言中变量和常量的注意点

1、类型转换&#xff1a;大类型可以转换成小类型但是精度丢失&#xff1b;小类型不能转换成大类型。例如&#xff1a; package mainimport "fmt"//golang中使用" var "关键字来定义变量 //定义变量的语法&#xff1a;1、var var_name1[,var_name2,...] va…

day16|654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树

654.最大二叉树 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点&#xff0c;其值为 nums 中的最大值。递归地在最大值 左边 的 子数组前缀上 构建左子树。递归地在最大值 右边 的 子数组后缀上 构建右子树。 返回 nums 构…

深度学习入门基础CNN系列——填充(padding)与步幅(stride)

填充&#xff08;padding&#xff09; 在上图中&#xff0c;输入图片尺寸为333\times333&#xff0c;输出图片尺寸为222\times222&#xff0c;经过一次卷积之后&#xff0c;图片尺寸为222\times222&#xff0c;经过一次卷积之后&#xff0c;图片尺寸变小。卷积输出特征图的尺寸…

el-table表头添加勾选框

el-table表头添加勾选框嘚吧嘚实现嘚吧嘚 table的行勾选是比较常规的操作&#xff0c;但是有的时候就有各种奇葩的需求蹦出来。&#x1f62d; 比如最近有一个需求&#xff0c;不仅需要勾选行&#xff0c;还需要勾选列&#xff0c;其实我心中有了一万头可爱的小羊驼&#xff0c…

NISP三级证书含金量如何

国家信息安全水平测试&#xff08;NationalInformationSecurityTestProgram&#xff0c;通称NISP&#xff09;&#xff0c;是通过中国信息安全测评中心执行塑造我国网络空间安全优秀人才的一个项目。 为培养大量出色的实践型网络安全人才&#xff0c;中国信息安全测评中心上线…

SpringCloud Alibaba微服务 -- Seata的原理和使用

文章目录一、认识Seata1.1 Seata 是什么?1.2 了解AT、TCC、SAGA事务模式?AT 模式前提整体机制如何实现写隔离如何实现读隔离TCC 模式Saga 模式Saga 模式适用场景Saga 模式优势Saga 模式缺点二、Seata安装2.1 下载2.2 创建所需数据表2.2.1 创建 分支表、全局表、锁表2.2.2 创建…

Qt OpenGL(10)光照模型基础

文章目录物体的光照模型立方体坐标构建立方体的6个面代码框架widget.cpp顶点着色器片元着色器Ambient 环境光Diffuse 漫反色法向量计算漫反射分量Specular Highlight镜面高光计算镜面反射分量补充&#xff1a;半程向量的使用物体的光照模型 出于性能的原因&#xff0c;一般使用…

思科Cisco交换机的基本命令

一、设备的工作模式1、用户模式Switch>可以查看交换机的基本简单信息&#xff0c;且不能做任何修改配置&#xff01;2、特权模式Switch> enable Switch#可以查看所有配置&#xff0c;且不能修改配置&#xff01;3、全局配置模式switch# configure terminal switch(config…

Redis基础——SpringDataRedis快速入门

文章目录1. SpringDataRedis介绍2. SpringDataRedis快速入门2.1 SpringDataRedis的使用步骤1. SpringDataRedis介绍 SpringData是Spring中数据操作的模块&#xff0c;包含对各种数据库的集成&#xff0c;其中对Redis的集成模块就叫做SpringDataRedis 官方网址 提供了对不同Redi…

参加猿代码超算实习生计划靠谱吗?

猿代码近期推出了超级实习生计划&#xff0c;相比市面上同类型实习类产品&#xff0c;超算实习生计划服务群体范围更小一些&#xff0c;主要服务于有志于从事芯片行业的大学生们&#xff0c;专做芯片赛道实习就业产品。那么至今为止有人参加过猿代码超算实习生计划吗?这个产品…

〖产品思维训练白宝书 - 核心竞争力篇①〗- 产品经理 的核心竞争力解读

大家好&#xff0c;我是 哈士奇 &#xff0c;一位工作了十年的"技术混子"&#xff0c; 致力于为开发者赋能的UP主, 目前正在运营着 TFS_CLUB社区。 &#x1f4ac; 人生格言&#xff1a;优于别人,并不高贵,真正的高贵应该是优于过去的自己。&#x1f4ac; &#x1f4e…

Top 命令中的 Irix 模式与 Solaris 模式(解释单个进程cpu占比为何会超过100%?)

文章目录 背景top cpu 栏位说明Solaris 模式Irix ModeTOP -H切换线程总结背景 关于top命令用了很久了,但是一直对单进程占用cpu占比为何会超过100%认识不够深刻。 top cpu 栏位说明 1. %CPU -- CPU UsageThe tasks share of the elapsed CPU time since the last screen…

深度学习入门基础CNN系列——卷积计算

卷积计算 卷积是数学分析中的一种积分变换的方法&#xff0c;在图像处理中采用的是卷积的离散形式。这里需要说明的是&#xff0c;在卷积神经网络中&#xff0c;卷积层的实现方式实际上是数学中定义的互相关 &#xff08;cross-correlation&#xff09;运算&#xff0c;与数学…

【项目实战】package.json你需要了解内容

package.json文件^和~区别 在项目开发中常引用npm包&#xff0c;那么package.json文件^和~区别是什么&#xff1f; ^意思是将当前库的版本更新到第一个数字&#xff0c; 例&#xff1a;"^4.1.0"是库会更新到4.X.X的最新版本&#xff0c;但不会更新到5.X.X版本。~意…

基于卷积深度神经网络的句子单子关系分类(附完整版代码)

基于卷积深度神经网络的关系分类 直接先上结果: 用于关系分类的最先进的方法主要基于统计机器学习,并且它们的性能很大程度上取决于提取的特征的质量。提取的特征通常来自预先存在的自然语言处理(NLP)系统的输出,这导致错误在现有工具中的传播和阻碍这些系统的性能。在本文…