node 简介与安装

简介

  • node.js是浏览器的 js 引擎
  • 浏览器中有一个 js 引擎来解析 js 代码,只能解析 js 代码中的 ECMAScript,dom 和 bom 的解析依赖的是浏览器本身
  • 将整个 js 引擎单独拿出来,就是 node
    要让整这个引擎运行起来,有人将他做成了一个软件,安装在电脑上,js 代码就不用依赖浏览器运行了,在电脑的命令行也能运行 js 代码,这样 js 就能写后台了

image.png

下载安装

  • 我们的电脑是没有自带 node 环境的
  • 需要我们手动下载一个 node 安装包 ,安装node 环境
  • 有了 node 环境以后,我们就可以运行 node 了
  • 下载方式:
  • 官网:https://nodejs.org/en
  • 中文网:http://nodejs.cn(推荐)
下载

image.png

  • 在 node 中文网下载的时候,选择安装包,不要选择 二进制文件
  • 因为 二进制文件 是一个简单版,我们需要自己配置 环境变量 才可以使用
安装
  • 下载好以后,我们直接把下载好的文件双击运行就行
  • 找到 node-v10.16.2-x64.msi 对应的文件

image.png

image.png

image.png

image.png

image.png

image.png

image.png

  • 总结:傻瓜式的点下一步就行了

检测安装环境

  • 我们打开运行窗口 (win + r)
  • 写入 cmd 然后按下回车,来到我们的命令行

image.png

  • 然后再命令行写入一个指令:node -v
  • 然后按下回车,会得到一个 node 的版本号
  • 能看到版本号表示 node 环境安装成功

image.png

配置 vscode(win10)

  1. 右击VSCode图标,选择属性,选择兼容性,勾选以管理员身份运行此程序,最后点击确定

image.png
2. vscode 中 调出终端
3. 输入命令:get-ExecutionPolicy
4. 输入命令:set-ExecutionPolicy RemoteSigned
5. 输入命令:get-ExecutionPolicy

  • Restricted:表示禁止终端使用命令的
  • RemoteSigned:表示可以使用终端命令了

image.png

全局安装脚手架

React团队推荐使用create-react-app(相当于vue的vue-cli)来创建React新的单页应用项目,它提供了一个零配置的现代构建设置。

React脚手架(create-react-app)意义:

脚手架是官方提供,零配置,无需手动配置繁琐的工具即可使用
充分利用Webpack,Babel,ESLint等工具辅助项目开发
关注业务,而不是工具配置

  1. create-react-app会配置我们的开发环境,以便使我们能够使用最新的 JavaScript特性,
  2. 提供良好的开发体验,并为生产环境优化你的应用程序。
  3. 为了能够顺利的使用create-react-app脚手架,
    我们需要在我们的机器上安装:
  4. Node >= 8.10 和 npm >= 5.6。
  • 在终端输入命令:npm install -g create-react-app

image.png

  • 这需要等待一段时间,这个过程在安装三个东西
  • react: react的顶级库
  • react-dom: react在web段的运行环境
  • react-scripts: 包含运行和打包react应用程序的所有脚本及配置

创建项目

  • 先创建一个放置项目的文件夹www
  • 在终端中使用cd指令跳转到这个文件夹
  • 创建项目指令:create-react-app your-app(your-app是项目名,可以自己取)

image.png

  • 出现下面的界面,表示创建项目成功:

image.png

  • 通过cd your-app命令进入目录
  • 运行npm start即可运行项目

自定义React空项目

  • 上面创建的项目是一个例程项目,有自带的代码文件,若想编写自定义的React程序则需要先删除src目录中的所有文件,这样该项目就是一个空项目了
  • 重新创建一个index.js文件

JSX 语法

JSXReact中使用的一种语法,其建立在JS的基础之上,可以直接在JavaScript 中插入HTML,极大方便了前端页面的构建。

如下图所示,APP函数直接返回了一个HTML的标签:
image.png

React快速入门

例程

index.js

// 从 react 的包当中引入了 React。
//只要你要写 React.js 组件就必须引入React, 
//因为react里有一种语法叫JSX,要写JSX,就必须引入React
import React from 'react'


//ReactDOM 可以帮助我们把 React 组件渲染到页面上去,
//没有其它的作用了。它是从 react-dom 中引入的,
//而不是从 react 引入。
import ReactDOM from 'react-dom'


//从APP.js中引入函数APP
import APP from './APP'


//通过构建DOM树
const root=ReactDOM.createRoot(
document.getElementById('root'))


root.render(   //render 对根组件(DOM树)进行渲染

// <React.StrictMode></React.StrictMode> 该标签是
//React中一种标准的模式,用于排错,可以省略
<React.StrictMode>  

    <h1>欢迎进入React的世界</h1>
    <APP />                     

</React.StrictMode>

//<APP />  该标签用于调用APP.js中的APP函数
  
)

APP.js

//构建函数,该函数用于页面渲染
function APP()
{
    const divContent="标题内容"
    const divTitle="标题"
    return(
        <div title={divTitle}>{divContent}</div>
       //{divContent}在标签div内容中的插值
       //{divTitle}在标签div属性中的插值
    )
    
    //当返回多行内容时,return后面必须加()
    
    //return 后面只能返回一个标签,若有多个标签要返回,
    //需要在最外面套一个共同的父标签
    
    //也可以采用下面两种方法:
    //1.<></>在外面套一个空标签
    //2.<Fragment></Fragment> 在外面套一个Fragment标签
}

export default APP;

map 循环遍历

render() {
  const data = ['apple', 'banana', 'orange'];
 
  const componentList = data.map((item, index) => {
    return <Component key={index} data={item} />;
  });
 
  return (
    <div>
      {componentList}
    </div>
  );
}

在这个例子中,data数组包含了三个水果名称,我们使用map()方法遍历data数组,并针对每个元素创建一个<Component>组件,通过key属性来唯一标识每个组件(下标index标识),同时将当前元素作为data属性传递给组件。最后,将生成的组件列表放在<div>容器中进行渲染。

需要注意的是,使用map()方法时,需要给每个生成的元素指定一个唯一的key属性,以便React能够准确地进行组件的识别和更新

事件

React 事件的命名采用小驼峰式(camelCase),而不是纯小写。如点击事件onClick

使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串

  function hello (e) {    //事件函数
    console.log("哈喽我是点击事件",e);
  }
  //e 中存放的是该事件的一些信息,如鼠标坐标
  
  function A () {
    
    return (
      <div>
        <button onClick={this.hello}>你好</button>
      </div>
      //onClick后面跟上事件对应的方法名 
    )}

React Hooks(钩子函数)

useState 状态处理

useState 设置出的变量,叫状态变量,该变量的改变会引起页面的自动刷新

//构建函数,该函数用于页面渲染
function APP()
{

    const [content,setcontent]=useState("当前内容")   
    //设置状态变量,并设置其初始值,返回值为两个变量,
    //一个用于读取,一个用于修改
    //参数content用来读取该状态变量的当前值,参数setcontent
    //用来修改值

    function handle(e)   //事件函数
    {
        setcontent("修改后的新内容"); 
        //将setcontent对应的状态变量值进行修改
        //修改方式:用传入的值来替换原来的值
        //因此,若状态变量是一个对象,则修改时需要将所有成员
        //变量都书写出来
        
        //若成员变量太多,可以将对象展开
        //展开的代码属性形式:   `...读取状态变量值的参数名,`
        //在这后面再对其中部分数据进行修改
        //(重复声明的变量,后面值会覆盖前面值)
        
        console.log("点击了按钮",e);
         //e 中存放的是该事件的一些信息,如鼠标坐标
    }
    

    return(
        <Fragment>
            <div >{content}</div>
            <button onClick={handle}>按钮</button>
        </Fragment>
        
    );
}
useContext逐层传递

CreateContext 设置出的变量,该变量能够逐层传递,从而由此可以改变每一层的Props(属性)

const levelContent=CreateContent(5)
//使用CreateContent()设置了一个Context变量,并为其设初值

//………………
const level=useContext(levelContent)
//获取对应Content变量的值,该值由上层组件中距离当前组件最近的 
//`<MyContext.Provider>` 的 `value prop(属性)` 决定。
//若已经是最高层了,则对应的Context变量值由其初值决定

<levelContext.Provider value={level+1}>
…………
</levelContext.Provider>
useReducer统一管理

useReducer 是一个 React hooks,它允许你在组件中使用状态管理。useReducer 接受两个参数:一个函数作为计算状态的 reducer(状态管理函数),以及初始状态(初始值)。reducer 函数接收 state(状态变量)action(对该状态变量进行什么操作) 作为参数,并返回一个新的 state(状态变量)

useReducer 还提供了一个函数 useReducerPayload,它可以直接在组件中获取由 action 传递的属性。

定义一个 reducer 函数,它接收 stateaction 作为参数:

const counterReducer = (state = 0, action) => {
//action.type 表示对state状态变量操作的类型
  switch (action.type) {
    case 'INCREMENT':
      return state + 1;
    case 'DECREMENT':
      return state - 1;
    default:
      return state;
  }
};

在组件中使用 useReduceruseReducerPayload

const Counter = () => {
  const [state, setState] = useReducer(counterReducer,0);
  //useReducer()参数1是该状态变量对应的状态管理函数,
  //参数2是状态变量的初始值
  
  //返回值为 state 状态变量,setState 状态管理函数触发函数
  const increment = () => {
    setState({ type: 'INCREMENT' });
    //传入操作类型
  };
  const decrement = () => {
    setState({ type: 'DECREMENT' });
  };
  const getPayload = () => {
    return state;
  };

  return (
    <div>
      <button onClick={increment}>Increment</button>
      <button onClick={decrement}>Decrement</button>
      <p>Counter: {getPayload()}</p>
    </div>
  );
};

在这个示例中,我们定义了一个简单的计数器组件,它使用了 useReducer 来管理状态。我们定义了一个名为 counterReducer 的 reducer 函数,它根据 action 的类型来更新 state。然后,我们使用 useReducer 获取 state 并将其传递给组件。我们还定义了两个函数 incrementdecrement,它们分别用于增加和减少计数。最后,我们使用 useReducerPayload 函数直接获取 state,并在组件中显示它。

useRef获取状态

useRef 是一个 React hook,它允许你在函数组件中创建一个 ref。ref 是一个指向 DOM 元素的引用,你可以使用它来记录 DOM 元素的状态。ref 不会被渲染,所以它们不会出现在最终的 DOM 结构中。

在组件中使用 useRef

const Counter = () => {
  const [state,setstate]=useState(2)
  
  const count = useRef();
  //设置一个叫count的ref
  
  count.current=state;
  //将当前状态变量的值赋值给count
  
  const increment = () => {
    state++;
  };

  const decrement = () => {
    state--;
  };

//最终结果是点击按钮,状态变量state不断在改变,但count的值
//不变,想要改变count的值需要操作count.current


  return (
    <div>
      <button onClick={increment}>Increment</button>
      <button onClick={decrement}>Decrement</button>
      <p>Counter: {count.current}</p>
    </div>
  );
};

注意,useRef 仅在函数组件中有效

Ref不仅可以获取值,还可以获取标签:


   const inputEl = useRef(null)
   //设置Ref变量并与input标签关联
   
   const handleFocus = () => {
       inputEl.current.focus()
       //获取input标签,并调用其focus()方法,使其获得焦点
       //(即选中输入框)
   }
   return (
       <p>
           <input ref={inputEl} type="text" />
           
           {/*将ref变量inputEl与该输入框关联*/}
           
           <button onClick={handleFocus}>按钮</button>
       </p>
   )

Ref还可以获取一个组件:

image.png
image.png
如上图所示,组件APP中有一个子组件Child, 设置一个ref 变量childRef与其关联,同时,子组件Child函数需要使用forwardRef()来处理,以方便子组件与Ref变量关联,这样在父组件中就可以通过操作childRef来直接使用该子组件了

父组件还可以通过Ref变量使用子组件中的部分方法:
image.png
如上图所示,子组件可以通过参数ref来接收与之关联的Ref变量,通过useImperativeHandle()将其中的子组件方法提供给父组件使用

  • 参数1是与该组件关联的Ref变量
  • 参数2是一个函数,该函数返回值必须是一个对象,因此才会有{}的出现

下图是父组件App使用子组件Child中的方法myFn:
image.png

useEffect 副作用函数

useEffect()设置的函数可以在非用户触发时自动执行,默认是在组件渲染开始时进行,每刷新页面一次,执行一次

image.png

useEffect():

  • 参数1是要执行的函数

  • 参数2是个数组,其中存放触发函数执行的变量(变量改变,函数执行),若数组为空,则没有变量能促发函数执行(页面刷新除外),该参数可以缺省,缺省则页面刷新一次,执行一次

useMemo 数据缓存

image.png
如上图所示,通过useMemo可以将函数对应的返回值进行缓存。

  • 参数1 函数,该函数的返回值会进行缓存,result中存放着函数的返回值
  • 参数2 是个数组,当其中对应的变量发生变化时,缓存中的值才会更新,即函数会重新执行
useCallback函数缓存

image.png
如上图所示,Button是一个子组件,传入的参数onClick是一个函数,该组件通过memo()变为了一个记忆组件,即只要传入的Props不变,子组件就不会重新执行

image.png

image.png
如上图所示,通过useCallback()将对应函数进行缓存,只有参数2([])中的变量改变时,对应的函数才会重新执行

展开语法

通过...参数名可以将对象性质的变量展开

const value={
    title:"标题",
    content:"内容",
    id:1
};

...value   //将变量value展开
//
//   等价于(不再有大括号)  
//    title:"标题",
//    content:"内容",
//    id:1

组件间通信与插槽

React中组件分两种类型,一种是React DOM组件,一种是React组件DOM组件是指所有React支持的HTML和SVG标签,React组件表示用户自定义标签

React组件中的所有的标签属性统称为Props,并通过Props来管理。

DOM组件中CSS的写法

CSS中的标签类名属性class在React中要改为className,以防止与js中的类class重名。

 return(
        <Fragment>
            
            <button 
            onClick={handle} 
            className="button" 
            style={{
                width:200,
                height:200,
                backgroundColor:"red"
            }}>
                按钮
                </button>
                
        </Fragment>
        //CSS中的类名class改为了className
        //style属性中第一对{}为React中的插值功能,
        //第二对{}及其中内容表明这是CSS属性,是CSS属性的常规写法
    );

也可以采用展开语法,其效果与上述代码等价:

const imgData={
   className:"button" 
   style:{
           width:200,
           height:200,
           backgroundColor:"red"
         }
}


return(
        <Fragment>
            <button 
            onClick={handle} 
            
            {...imgData}  
            >
                按钮
                </button>  
        </Fragment>
        //{...imgData} 外面{}是插值语法,里面就是展开语法
    );
自定义标签中的Props(属性)设置

image.png
如上图所示,自定义标签Article传入的自定义的标签属性titlecontent,由props来接收与管理。也可以直接设置参数来接收属性,而不用props,如下图

image.png
在函数Article中设置了参数title,content来接收对应的标签属性

自定义标签的属性多级传递

image.png
image.png
image.png
如上面所示,函数Article(自定义标签Article)中又嵌套了一个子组件Detail,当标签Article传入参数时,将子组件的属性单独封装一下(如 detailData),将参数传入Article后,将子组件属性detailData原封不动的传入子组件Detail中,子组件Detail接收属性。

插槽

自定义组件不仅可以传递一些普通的自定义属性值,也可以直接传递JSX标签,这就叫插槽

image.png
如上图所示,自定义标签<List></List>直接存在子标签<li></li>,这些标签在函数List(自定义标签List)中,用children来接收,其用来接收和管理该标签下的所有子标签

子组件向父组件传递

image.png

image.png
如上图所示,父组件App中设置了一个事件函数handleActive(),将该事件函数作为属性Props传入子组件Detail中,并在子组件中触发该事件。

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐