zoukankan      html  css  js  c++  java
  • react 和 vue 的比较

    比较 vue

    react   (npx create-react-app my-app)

    点击事件和类的命名
    <div @click="toclick"  class='btn'></div>
    <div className="img-wrap"  onClick={() => this.toMv(item.id)}>
    或者<div className="img-wrap"  onClick={this.click}>       click=()=>{this.toMv(item.id)}
    动态添加类名
    :class={aaa:this.aa  === 2}
    动态添加单类名:  <div className={index===1?'active':null}>  </div>
    已经有类名,在动态添加类名:  <div className={ `box${classA}${index===1?‘active’:null }` } ></div>
             或者:<div className={ [ classA,'box',index===1? ‘active’:null ].join(' ') } ></div>    join() 方法用于把数组中的所有元素放入一个字符串。
    更改数据 this.data = '123' 或者 数组 $set 
    this.setState({ liked: true })  每次在组件中调用 setState 时,React 都会自动更新其子组件。
    条件选择 v-if   v-else-if  v-else  if(){return  ...}else{return ...}   //    this.a?(return ...):(return ...)   //   this.a&&console.log(123444)
    列表渲染 v-for=(item,index) in list  this.list.map(item=>{<li  key={item.id}>{item.name}<li> })    map遍历谁,就要给谁加key 
    样式处理 动态添加类名:   :class={redColor:this.ee===2}

    行内样式  <div  style={{'color:'red','backgroundColor':'pink'}}>233<div>

    类名: <div className='aaaa'  style={{'color:'red','backgroundColor':'pink'}}>233<div>   .aaaa{ text-align: center}

    组件创建 方式  

    1.使用函数创建组件 (函数名称首字母大写,函数组件必须有返回值,返回值为null,表示不渲染)  function Hello(){return ( <div>这是第一个函数组件</div>)}

    2.类组件  使用es6的语法创建的组件(类首字母大写,类组件要继承React.Component父类,可以使用父类提供的方法或者属性,必须提供render方法及返回值)   class  Hello extends React.Component{

      render(){

        return (<div>这是第一个类组件</div>)

      }

    }

    事件处理 @加事件名字

    on+事件名称 = 事件处理函数   onClick= function(){} 事件命名采取驼峰命名

    export default class extends React.Component {
      clickHandle(e){
        console.log('点了')
      }
      render(){
        return (
          <div><button onClick = {this.clickHandle}>点我点我点我</button></div>
          )
        }
    }

    类组件与函数组件绑定事件是差不多的,只是在类组件中绑定事件函数的时候需要用到this,代表指向当前的类的引用,在函数中不需要调用this

     事件对象  类似  通过事件处理函数的参数获取到的事件对象  e   e.nativeEvent   e.preventDefault() 取消事件的默认动作。  e.stopPropagation() 阻止事件冒泡
    State SwtState

    state 是数据,是组件里面的私有数据,只能在组件内部使用,通过this.state来获取状态

    export default class extends React.Component {
        constructor(){
            super()
    
            // 第一种初始化方式
            this.state = {
                count : 0
            }
        }
        // 第二种初始化方式
        state = {
            count:1
        }
        render(){
            return (
                <div>计数器 :{this.state.count}</div>
            )
        }
    }

    setState 修改状态  this.setState({要修改的数据})  作用修改state  更新ui  

    事件绑定this指向  

    1.利用箭头函数自身不绑定this的特点   即绑定事件使用箭头函数   2.使用bind 更改this里面的指向  使用函数 需要使用bind改变this

    class App extends React.Component {
      constructor() {
        super()
        ...
        // 通过bind方法改变了当前函数中this的指向
        this.onIncrement = this.onIncrement.bind(this)
      }
      // 事件处理程序
      onIncrement() {
        ...
      }
    
      render() {
        ...
      }
    }
    受控组件  无  v-model双向绑定

    受控组件:值受到react控制的表单元素

    state添加一个值,绑定表单里面的value值,然后通过给表单绑定change事件,设置state的值

    inputChange(e){
       let target = e.target;
       let value = target.type == 'checkbox' ? target.checked : target.value;  // 如果类型是checkbox,表示改变是否被选中,true,false
       this.setState({
           [e.target.name]: value
       })
    }
    <input type="text" value={this.state.txt} name="txt" onChange={this.inputChange}/>
    <input type="checkbox" value={this.state.isChecked} name="isChecked" onChange={this.inputChange}/>
    非受控组件  this.$ref 来获取dom节点

    借助于ref,使用元素DOM方式获取表单元素值 ref的作用:获取DOM或者组件

    class App extends React.Component {
        constructor(){
            super()
            
            //创建 ref
            this.txtRef = React.createRef()
        }
        // 获取文本框的值
        getTxt =() => {
            console.log(this.txtRef.current.value)
        }
        render(){
            return (
              <div>
                <input type ="text" ref={this.txtRef} />
                <button onClick ={this.getTxt}>获取值</button>
              </div>
            )
        }
    案列:渲染评论列表  
    import React, { Component } from "react";
    import "./index.scss";
    class index extends React.Component {
      state = {
        comments: [
          { id: 1, name: "jack", content: "沙发!!!" },
          { id: 2, name: "rose", content: "板凳~" },
          { id: 3, name: "tom", content: "楼主好人" },
        ],
        comment: "",
        sName: "",
      };
      changeValue = (e) => {
        this.setState({
          [e.target.name]: e.target.value,
        });
      };
      topinglin = () => {
        
        let {sName,comment} = this.state
        if(sName.trim()===''|| comment.trim()===''){
            alert('请输入内容')
            return
        }
        let newArr = [
            {
                id: this.state.comments.length + 1,
                name: sName,
                content: comment,
            },...this.state.comments
        ]
    
        this.setState({
          comments: newArr,
          comment: '',
          sName:'',
        });
      };
      renderList = () => {
        if (this.state.comments.length === 0) {
          return <div className="no-comment">暂无评论,快去评论吧~</div>;
        } else {
          return (
            <ul>
              {this.state.comments.map((item) => {
                return (
                  <li key={item.id}>
                    <h3>{item.name}</h3>
                    <p>{item.content}</p>
                  </li>
                );
              })}
            </ul>
          );
        }
      };
      render() {
        return (
          <div className="app">
            <div>
              <input
                className="user"
                name="sName"
                type="text"
                value={this.state.sName}
                onChange={this.changeValue}
                placeholder="请输入评论人"
              />
              <br />
              <textarea
                name="comment"
                className="content"
                cols="30"
                rows="10"
                placeholder="请输入评论内容"
                value={this.state.comment}
                onChange={this.changeValue}
              />
              <br />
              <button onClick={this.topinglin}>发表评论</button>
              {this.renderList()}
            </div>
          </div>
        );
      }
    }
    export default index;
     传值

     父--> 子  props

     子-->父   $emit

    兄弟  bus

     函数组件通过 参数 props接收数据,类组件通过 this.props接收数据    props是只读属性,不能对值进行修改     使用类组件时,如果写了构造函数,应该将props传递给super(),否则,无法在构造函数中获取到props,其他的地方是可以拿到的

     父--> 子    父组件提供要传递的state数据   给子组件标签添加属性,值为state中的数据   子组件中通过props接收父组件中传递的数据

    子 -- > 父  

    利用回调函数,父组件提供回调,子组件调用,将要传递的数据作为回调函数的参数   父组件提供一个回调函数,用来接收数据  将该函数作为属性的值,传递给子组件

    (假设父组件有删除的方法,子组件想调用,需要父组件将方法传过去,子组件接受方法调用)

    兄弟组件传值:

    • 将共享状态(数据)提升到最近的公共父组件中,由公共父组件管理这个状态

    • 这个称为状态提升

    • 公共父组件职责:1. 提供共享状态 2.提供操作共享状态的方法

    • 要通讯的子组件只需要通过props接收状态或操作状态的方法

    props进阶  

    props的children属性 :表示组件标签的子节点,当组件标签有子节点后,props就有该属性   children属性与普通的props一样,值可以使任意值(文本、react元素、组件、甚至是函数)

    props校验  

    对于组件来说,props是外来的,无法保证组件使用者传入什么格式的数据,简单来说就是组件调用者可能不知道组件封装着需要什么样的数据   

    • 安装包 prop-types (yarn add prop-types | npm i props-types)

    • 导入prop-types 包

    • 使用组件名.propTypes={} 来给组件的props添加校验规则

    • 校验规则通过PropTypes对象来指定

    生命周期 8个

    组件从被创建到挂载到页面中运行,再到组件不在时卸载的过程 生命周期的每个阶段总是伴随着一些方法调用,这些方法就是生命周期的钩子函数

    创建时候:

    constructor()    创建组件时,最先执行                                 初始化state    为事件绑定this

    render()            每次组件渲染都会触发                                渲染 UI

    componentDidMount   组件挂载后(完成DOM渲染后)           发送网络请求   DOM操作

    componentDidUpdate    组件更新后                                    发送网络请求   DOM操作   

    componentWillUnmount    组件卸载                                    执行清理工作(比如:清理定时器)

    组件更新机制  

    父组件重新渲染,也会重新渲染子组件,但是只会渲染当前组件子树

    性能优化   减轻state   避免不必要的重新渲染   
    路由  

    安装 yarn  add  react-router-dom   

    导入路由的三个核心组件:Router、Route、Link

    import { BrowserRouter as Router,Route,Link} from  'react-router-dom'

    使用Router组件包裹这个应用

    • 两种常用的Router: HashRouter和BrowserRouter

    • HashRouter: 使用URL的哈希值实现 (localhost:3000/#/first)

    • 推荐 BrowserRouter:使用H5的history API实现(localhost3000/first)

    使用link组件作为导航菜单   用于指定导航链接(a标签)

    • 最终Link会编译成a标签,而to属性会被编译成 a标签的href属性

    使用Route组件配置路由规则和要展示的组件

    • path属性:路由规则,这里需要跟Link组件里面to属性的值一致

    • component属性:展示的组件

    • Route写在哪,渲染出来的组件就在哪

    路由的执行过程

    • 当我们点击Link组件的时候,修改了浏览器地址栏中的url

    • React路由监听地址栏url的变化

    • React路由内部遍历所有的Route组件,拿着Route里面path规则与pathname进行匹配

    •  当路由规则(path)能够匹配地址栏中的pathname时,就展示该Route组件的内容
     

    编程式导航

       
    • 场景:点击登陆按钮,登陆成功后,通过代码跳转到后台首页,如何实现?

    • 编程式导航:通过JS代码来实现页面跳转

    • history是React路由提供的,用于获取浏览器历史记录的相关信息

    • push(path):跳转到某个页面,参数path表示要跳转的路径

    • go(n):前进或后退功能,参数n表示前进或后退页面数量

    默认路由

    • 现在的路由都是通过点击导航菜单后展示的,如果进入页面的时候就主动触发路由呢

    • 默认路由:表示进入页面时就会匹配的路由

    • 默认路由:只需要把path设置为 '/'

    匹配模式

    模糊匹配模式

    • 当Link组件的to属性值为 '/login' 时候,为什么默认路由也被匹配成功?

    • 默认情况下,React路由是模糊匹配模式

    • 模糊匹配规则:只要pathname以path开头就会匹配成功

    精准匹配

    • 默认路由认可情况下都会展示,如果避免这种问题?

    • 给Route组件添加exact属性,让其变为精准匹配模式

    • 精确匹配:只有当path和pathname完全匹配时才会展示改路由

      

    小结

    • React路由可以有效的管理多个视图实现 SPA

    • 路由先需要通过安装

    • Router组件包裹整个应用,只需要使用一次

    • Link组件是入口,Route组件是出口

    • 通过props.history实现编程式导航

    • 默认是模糊匹配,添加exact编程精确匹配

    • React路由的一切都是组件,可以像思考组件一样思考路由

  • 相关阅读:
    网络编程[28]
    网络编程[30]
    网络编程[20]
    网络编程[29]
    网络编程[19]
    网络编程[15]
    网络编程[12]
    hdu 3802【Ipad,IPhone】
    hdu 2616【Kill the monster】
    hdu 1026【Ignatius and the Princess I】
  • 原文地址:https://www.cnblogs.com/lh1998/p/13744370.html
Copyright © 2011-2022 走看看