react入门学习

初始配置

$ 1 建立基本的webpack项目

建立目录

  • npm init -y 建立package.json
  • cnpm i webpack webpack-cli -D 安装webpack webpack-cli
  • 在根目录建立webpack.config.js并写入相应代码module.exports={mode:'development'}
    css

  • 终端里输入webpack进行打包,以后dist文件夹里多出个main.js,打包成功html

    配置实时打包编译
  • cnpm i webpack-dev-server -D
    package.jsonscripts里写入"dev": "webpack-dev-server --open --port 3000 --hot --host 127.0.0.1 --progress --compress"webpack-dev-server以后的如--open,--hot等代码是功能性代码,可选择性写
`--open` 设置自动打开默认浏览器 `--oprn chrome`设置自动打开google浏览器
`--port 3000` 设置端口号为3000,若不写则默认是8080
`--host 127.0.0.1`设置域名为127.0.0.1
`--compress` 压缩
`http://loaclhost:8080/`
  • npm run dev 运行,文件可在http://localhost:8080打开(ctrl+c能够终止npm run dev)
    index.html 中<script src="../dist/main.js"></script> 路径改成/main.js
由于webpack-dev-server打包好的main.js是托管到内存中的,在内存中是看不到的,
但却实实在在的存在于根目录中,因此用/main.js引入根目录中的main.js
解决常常访问磁盘目录问题——将index页面也放入内存中便可
  • cnpm i html-webpack-plugin -D 安装在内存中自动生成html页面的插件,解决每保存一次就调用代码消耗磁盘性能的问题
  • webpack.config.js写入以下代码(dirname前是两个 _ )--注意,代码千万不要敲错

const path=require('path')
const HtmlWebPackPlugin = require('html-webpack-plugin')

const htmlPlugin = new HtmlWebPackPlugin({
  template: path.join(__dirname,'./src/index.html'),
  filename:'index.html'
})

module.exports = {
  mode: 'development',
  plugins:[
    htmlPlugin
  ]
}

在这运行以后,系统会自动把打包好的js注入到页面中去(以下图蓝色部分是系统自动注入的)。因此<script src="/main.js"></script>能够省去了!vue

  • npm run dev便可(注,不要cnpm run dev, cnpm通常只用来装包)

———————————————以上,初步配置完成———————————————node

$ 2 react起步(react中,一切都是用js来表现的)

安装react react-dom包
  • cnpm i react react-dom -S
  • 在index.js里导入包
    import React from 'react'
    import ReactDOM from 'react-dom'
  • 接下来能够根据格式来写代码了,在index.js里写
建立虚拟DOM元素: const myh1 = React.createElement("h1",{id:"myh1",title:"thish1"},"这是一个h1标签及其内容")
`参数1:标签类型:div,h1,input等:
参数2:标签属性,{attr:"aa",attr:"bb"},不设置就写null`
`参数3:标签子节点,或者说内容
参数n:其余更多子节点`
调用render函数渲染: ReactDOM.render(myh1,document.getElementById("list1"))
`参数1:要渲染的那个虚拟DOM元素,如myh1;
参数2:指定html页面上的一个容器(必须写成dom元素的形式,就是这里的document.getElementById)
如<div id="list1"></div>`

标签嵌套写法
react

JSX
  • React.createElement形式写起来太繁琐
  • 因而react开发出了在js中,混合写入相似于html的语法,咱们称之为JSX
  • 写好以后经过babel转换成React.createElement形式执行即可
  • jsx 语法的本质:并非直接把 jsx 渲染到页面上,而是内部先转换成了 createElement 形式,再渲染的
配置babel

(版本配置问题,避免踩坑从我作起 https://blog.csdn.net/tj310/article/details/88134512 )webpack

  • 安装 babel插件
    • 运行cnpm i babel-loader @babel/core @babel/plugin-transform-runtime @babel/runtime -D
    • 运行 cnpm i @babel/preset-env @babel/plugin-proposal-class-properties -D
  • 安装可以识别转换jsx语法的包,就是将jsx转化为js @babel/preset-react
    • 运行cnpm i @babel/preset-react -D
  • 在根目录添加.babelrc 配置文件
{
  "presets": ["@babel/preset-env", "@babel/preset-react"],
  "plugins": ["@babel/plugin-transform-runtime", "@babel/plugin-proposal-class-properties"]
}
  • 在webpack.config.js的module.exports中添加babel-loader配置项:
module: { //要打包的第三方模块
    rules: [
      { test: /\.js|jsx$/, use: 'babel-loader', exclude: /node_modules/ }  //exclude必定不能丢
    ]
}
  • 后缀名的省略及改变路径
在以上,在webpack.config.js之中的module下方添加以下代码
 resolve: {
    extensions: ['.js', '.jsx', '.json', '.vue'], // 表示,这几个文件的后缀名,能够省略不写
    alias: { // 表示别名
      '@': path.join(__dirname, './src') // 这样,@ 就表示 项目根目录中 src 的这一层路径
    }
  }
建立组件(两种方法,本质区别是有无state属性)

方法1:普通function模式建立组件(用的很少)ios

一、 src目录下建立components文件夹,里面建立组件文件(如comp1.jsx),在里面写入组件
    `如`
        import React from "react"     `*****必须引入React包*****`
        function Hello(props) {          `***组件名称首字母大写***`
          return <div>这是一个Hello组件----{props.name}----{props.age}----{props.weight}</div>
        }
        export default Hello           `*****必须暴露组件*****`

二、在index.js文件里引入组件
        import Hello(组件名称) from "./components/comp1.jsx"   `*****必须引入组件*****`

        const arrStr = ["haha", "heihei", "hehe", "xixi"]

        const dog={
            name:"金毛",
            age:"2",
            sex:"公",
            weight:"50kg"
        }

        ReactDOM.render(<div>

          <Hello {...dog}></Hello>      `***使用组件,以组件作标签名来使用,记住要和组件名如出一辙***`
                                                      `{...dog}`,es6语法---展开运算符

          {arrStr.map(item => < div key = {item.id}><h3>{item}</h3></div > )}   //map方法映射数组,箭头函数,key

         </div>, document.getElementById("list1"))
方法2:class关键字建立组件
  • 先了解什么是class关键字
建立一个动物类
//在class的{}区间内只能写构造器(内部包含实例属性),静态属性,实例方法,静态方法
//class关键字内部,仍是原来的js方法来写,只不过更方便了,所以把class关键字称做 语法糖
const Animal {    // 这是class关键字
构造器://class关键字内必需要有。每当执行new这个类的时候,会优先执行构造器中的代码
    constructor("name","age"){
        this.name=name      
        this.age=age
    }
静态属性://在class内部,经过static修饰的属性
    static info = "aaaaa"
实例方法(常常用到)
    yaoweiba(){
        console.log("这是一个实例方法")
    }
静态方法(用的很少)
    static yaoweiba(){
        console.log("这是Animal的静态方法")
    }
}

    const a1 = new Animal("金毛", 2)
    console.log(a1)
    a1.yaoweiba()   这是实例方法的调用
    Animal.yaoweiba()   这是静态方法的调用
  • class关键字的继承
class Person{     //父类
    constructor(name,age){     //这里是公用样式
        this.name=name
        this.age=age
       }
    sayHello(){
        console.log("你们好")
        }
  }

class American extends Person{    `// class 子类名 extends 父类名`
    constructor(name,age){
    super(name,age)                 `//若是写构造器了,则super()必需要有,并且必须放在构造器里的第一行`
        }
  }
const am1 = new American("jack",20)
console.log(am1)
am1.sayHello()

class Chinese extends Person{
     constructor(name,age,IdNumber){
        super(name,age)   
        this.IdNumber = IdNumber
      }
  }
const ch1  = new Chinese("张三",22,"342422************")
console.log(ch1)
ch1.sayHello()
  • class关键字建立组件
// 若是要使用 class 定义组件,必须 让本身的组件,继承自 React.Component
class Person extends React.Component {
   constructor() {   //给class建立的组件绑定私有数据(普通建立不支持)
      super()
      // 只有调用了 super() 之后,才能使用 this 关键字
      this.state = { // 这个 this.state = {} 就至关于 Vue 中的 data() { return { } }
        msg: '你们好,我是 class 建立的 Person组件'
      }
    }
      // 在 组件内部,必须有 render 函数,做用:渲染当前组件对应的 虚拟DOM结构
      render(){
          // render 函数中,必须 返回合法的 JSX 虚拟DOM结构
        this.state.msg="msg的值被我修改了"   //state私有数据的值是能够修改的,而props是不可修改的
        return <div>
        <h5>这是 class 建立的组件---{this.props.name}---{this.props.age}---{this.props.wife}</h5>
        <h2>{this.state.msg}</h2></div>
//在 class 关键字建立的组件中,若是想使用外界传递过来的 props 参数,不需接收,直接经过 this.props.属性名 访问
     }
}

const person={
    name:"林子闲",
    age:22,
    wife:"乔韵"
 }

ReactDOM.render(<div>
  <Person name={person.name} age={person.age} wife={person.wife}></Person>     
 //必须用组件名以标签的形式调用
   <Person {...person}></Person>
</div>,document.getElementById("list1"))
使用CSS样式美化组件

详细教程请看 https://www.bilibili.com/video/av25294556/?p=42 (第42集)git

一、先下载相关包
      cnpm i style-loader css-loader -D
二、在webpack.config.js内的rules里配置以下代码
     { test: /\.css$/, use: ['style-loader', 'css-loader']} 
三、在src文件夹下建立css文件夹,再在里面建立css文件,而后写样式
      如 src > css > style1.css
      在style1.css里写样式
         .mystyle{
              color:red;
              font-size: 14px;
          }
四、在相关文件中引入css文件
      import cssobj from "@/css/style1.css"    //这里固定写法cssobj,而非css
五、接下来能够在相关文件中经过className给定样式了
      如<div className="mystyle">哈哈</div>
CSS模块化——避免css样式污染全局代码问题,让其只在当前区域生效
* css模块化只针对 `类选择器` 和 `id选择器` 生效
一、 将webpack.config.js内的rules里的如下代码
     { test: /\.css$/, use: ['style-loader', 'css-loader']} 改成
     { test: /\.css$/, use: ['style-loader', 'css-loader?modules']} 
二、 给定样式的方式改为
   如  <div className={cssobj.mystyle} id={css.obj.mystyle2}>哈哈</div>
若是有某些css元素不想被模块化,想全局生效
一、将webpack.config.js内的rules里的一下代码
     { test: /\.css$/, use: ['style-loader', 'css-loader?modules']} 改成
     { test: /\.css$/, use: ['style-loader', 'css-loader?modules&localIdentName=[path][name]-[local]-[hash:5]'] }
//[path]  表示样式表 相对于项目根目录 所在路径
//[name]  表示 样式表文件名称
//[local]  表示样式的类名定义名称
//[hash:length]  表示最多32位的hash值,length能够指定具体数值  
二、  :global(.allstyle){    //这样写就不会被模块化了 :local(属性名)
      font-size: 12px;
      padding: 0;
  }
三、而后在相关文件里引用
  <div className={cssobj.mystyle} className={.allstyle}>哈哈</div>
也能够这么写
<div className={cssobj.mystyle+" allstyle"}>哈哈</div>   //allstyle前面有空格哦
也能够这么写
<div className={[cssobj.mystyle,"allstyle"].join(" ")}>哈哈</div>   //空格哦
在项目中启用模块化并同时使用bootstrap

原理:第三方的样式表是以.css为后缀名,而咱们将本身的样式用scss或less来作后缀名, 这样就能够区分开来本身的样式和第三方样式,从而能够给scss,less启用模块化,而不 影响第三方样式es6

一、下载bootstrap包   cnpm i bootstrap -S
二、下载包处理字体文件的url包   cnpm i url-loader -D    cnpm i file-loader -D
三、webpack.config.js的rules里添加   { test:/\.ttf|woff|woff2|eot|svg$/,use:'url-loader'}
四、下载sass的包   cnpm i sass-loader node-sass -D
五、webpack.config.js的rules里添加   { test:/\.scss$/,use:['style-loader','css-loader?modules&localIdentName=[path][name]-[local]-[hash:5]','sass-loader']}
六、将{ test: /\.css$/, use: ['style-loader', 'css-loader?modules&localIdentName=[path][name]-[local]-[hash:5]','sass-loader'] }
   改成{ test: /\.css$/, use: ['style-loader', 'css-loader'] }
七、在相应jsx或js文件里引入   import "bootstrap/dist/css/bootstrap.css"  
   而后尽情发挥吧

webpack.config.js里本阶段rules最终版以下web

rules: [
      {test: /\.js|jsx$/,use: 'babel-loader',exclude: /node_modules/},
      { test: /\.css$/, use: ['style-loader', 'css-loader'] },
      { test:/\.ttf|woff|woff2|eot|svg$/,use:'url-loader'},
      { test:/\.scss$/,use:['style-loader','css-loader?modules&localIdentName=[path][name]-[local]-[hash:5]','sass-loader']}
    ]
为按钮绑定事件及修改私有数据

onClick onMouseenter onMouseover等 要采用小驼峰命名

import React from "react"
import "bootstrap/dist/css/bootstrap.css"

export default class Hello extends React.Component{
  constructor(){
    super()
    this.state={
        msg: '我没被修改呢'
    }
  }
  render(){
    /*this.state.msg="我被一this.state.msg的方式修改了"*/
    return <div>
            <h5>这是一个Hello组件</h5><br/>
            <h5>{this.state.msg}</h5>
            <button className="btn btn-primary" onClick={ ()=>{this.myclickHandler(参数1,参数2)}} >按钮</button>         
//函数调用用这种形式来写,能够不写参数  onClick={()=>{this.myclickHandler()}}
          </div>

  }
  myclickHandler=(a,b)=>{     //函数部分用箭头函数来写,能够不写参数a,b   myclickHandler=()=>{ }
    alert("我被点击了"+a+b);
    this.setState({       //若要修改私有数据state,react给定了一个方法 this.setState({ }),同时记住this.state.msg在这里不可用
      msg:'我被以this.setState的方式修改了'
    },function(){this.state.msg})   //此处为回调函数,可不加
  }
}
文本框与state值之间的双向绑定
import React from 'react'

export default class BindEvent extends React.Component {
    constructor() {
      super()
      this.state = {
        msg: '哈哈',
        age: 22,
      }
    }

    render() {
      return <div>
        {/* 需求:点击按钮,把修改 msg 的值 */}
        <button onClick={() => this.show('aa', 'bb')}>按钮</button>
        <h3>{this.state.msg}</h3>


        /* 若是 咱们只是把 文本框的 value 属性,绑定到了 state 状态,可是,若是不提供   onChagne 处理函数的话,获得的文本框,将会是一个只读的文本框 */
        /* 当为文本框绑定 value 值之后,要么同时提供一个 readOnly, 要么,提供一个   onChange 处理函数 */
        /* <input type="text" style={{ width: '100%' }} value={this.state.msg} readOnly /> */
        <input type="text" style={{ width: '100%' }} value={this.state.msg} onChange={(e) => this.txtChanged(e)} />
              </div>
    }
  
    // 每当文本框的内容变化了,必然会调用 这个 txtChanged
    txtChanged = (e) => {
      // 在 onChange 事件中,获取 文本框的值,经过事件参数 e 来获取
      // console.log(e.target.value);

      const newVal = e.target.value

      this.setState({
        msg: newVal
      })
  }

快速搭建react项目

一、电脑里新建文件夹
二、npm create react-app 项目名称    如 npm create react-app huihuidemo / yarn create react-app huihuidemo
三、cd 项目名称    如 cd huihuidemo
四、npm run start
五、安装antd    cnpm i antd -S / yarn add antd 
六、在css文件中最顶部引入  @import '~antd/dist/antd.css';   //分号不能丢
    (也可在js文件里直接引入,  import 'antd/dist/antd.css';  )
七、在js jsx文件中引入须要使用的组件   import {Button,Icon...} from 'antd';
八、(之后必要)安装路由和ajax请求插件   yarn add react-router-dom axios 

具体可见antd官网   https://ant.design/docs/react/use-with-create-react-app-cn
解决react脚手架不支持less的问题
一、安装less相关包    cnpm i less less-loader -S / yarn add less less-loader 
二、暴露webpack    npm run eject / yarn eject   (此语句执行后会有config和scripts文件夹生成)   
      若出现如下错误: (Remove untracked files, stash or commit any changes, and try again.)
      是由于咱们使用脚手架建立一个项目的时候,自动给咱们增长了一个.gitignore文件,而咱们本地却没有文件仓库
      这样解决: 先输入  git add .      再输入  git commit -m 'up' 
三、找到webpack.config.js的const cssRegex = /\.css$/; (第38行) 作出以下改动
    - const cssRegex = /\.css$/;
    + const cssRegex = /\.(css|less)$/;
四、找到webpack.config.js的const loaders ,在里面最后一组后面添加
    { loader: require.resolve('less-loader') },
添加以后是这样的:
const loaders = [
      isEnvDevelopment && require.resolve('style-loader'),
      isEnvProduction && {...
       },
      {...
      },
      {...
      },
      {
        loader: require.resolve('less-loader')
      },
    ].filter(Boolean);
五、大功告成

ps:若npm start失败,出现这个问题(Build fails after eject: Cannot find module '@babel/plugin-transform-react-jsx' )
则能够
一、删除 node_modules 文件夹
二、运行 yarn
三、cnpm i less less-loader -S / yarn add less less-loader
三、从新 npm start / yarn start
相关文章
相关标签/搜索