Getting started from vue to react

  • 2021-12-04 09:09:00
  • OfStack

Directory Design Component Communication Lifecycle Event Handling class and style classstyle conditional rendering list rendering component nests to obtain DOM document structure route Dynamic routing & Nested routing with routing parameters Routing jump routing guard (login authentication, special route processing) state management uses

Because the new company uses react technology stack, including Umi, Dva, Ant-design and other 1 series solutions. After a little familiarity with 1, I realized that although there are some differences, they are still quite different. Below, I will use two hot frameworks react16 & vue2 (in active learning vue3) makes a simple comparison from design, writing style, API, life cycle and popular ecology:

Design

react vue 说明
定位 构建用户界面的js库 渐进式框架 react侧重于library,vue侧重于framework
渲染 setState更新state的值来达到重新render视图 响应式数据渲染,修改了响应式数据对应的视图也进行渲染 react需要考虑何时setState,何时render;vue只需要考虑修改数据
编写方式 jsx template react是函数式,all in js;vue区分tempalte、script、style,提供语法糖,使用vue-loader编译

Component communication

react: Strict one-way data flow

Down props Up props func Multistage transfer context

Follow props, onChange/setState ()

vue: Unidirectional data flow

Down props down Upward events up (Subscribe to Publication) Multilevel delivery $attrs, $listeners

There are also various fetch component instances (VueComponent), such as: $refs, $parent, $children; Obtain superior or subordinate components recursively, such as findComponentUpward, findComponentsUpward; High-order components: provide/reject, dispatch/broadcast

react vue 说明
子组件数据传递 props props 都是声明式
组件状态机 state data 管理组件的状态,react使用setState更改,vue直接赋值,新属性使用$set;vue使用函数闭包特性,保证组件data的独立性,react本就是函数

Life cycle

react vue 说明
数据的初始化 constructor created
挂载 componentDidMount mounted dom节点已经生成
更新 componentDidUpdate updated react:组件更新完毕后,react只会在第1次初始化成功会进入componentDidmount,之后每次重新渲染后都会进入这个生命周期,这里可以拿到prevProps和prevState,即更新前的props和state。 vue:在数据更改导致的虚拟 DOM 重新渲染和更新完毕之后被调用
卸载 componentWillUnmount destroyed 销毁事件

Event handling

react

The name of React event is small hump (camelCase) instead of pure lowercase When using JSX syntax, you need to pass in a function as an event handler instead of a string Default behavior cannot be blocked by returning false. You must explicitly use preventDefault Cannot unload the non-Element tag, otherwise it will be passed down as props

function Form() {
  function handleSubmit(e) {
    e.preventDefault();
    console.log('You clicked submit.');
  }
  return (
    <form onSubmit={handleSubmit}>
      <button type="submit">Submit</button>
    </form>
  );
}

vue

When used on ordinary elements, you can only listen for native DOM events. When used on a custom element component, you can also listen for custom events triggered by subcomponents


// Primary event 
<form v-on:submit.prevent="onSubmit"></form>
// Custom Events 
<my-component @my-event="handleThis(123, $event)"></my-component>

vue event modifier:

. stop-Call event. stopPropagation (). . prevent-Call event. preventDefault (). . capture-Use capture mode when adding event listeners. . self-Fires a callback only if the event is fired from the listener-bound element itself. . native-Listens for native events of the component root element. . once-Triggers only one callback. . left-(2.2. 0) Triggered only when the left mouse button is clicked. . right-(2.2. 0) Triggered only when the right mouse button is clicked. . middle-(2.2. 0) Triggered only when the middle mouse button is clicked. . passive-(2.3. 0) Add listeners in {passive: true} mode

class and style

class

react


render() {
  let className = 'menu';
  if (this.props.isActive) {
    className += ' menu-active';
  }
  return <span className={className}>Menu</span>
}

vue


<div
  class="static"
  :class="{ active: isActive, 'text-danger': hasError }"
></div>

 
<div :class="[{ active: isActive }, errorClass]"></div>

style

react


<div style={{color: 'red', fontWeight: 'bold'}} />

vue


<div :style="[baseStyles, overridingStyles]"></div>

For component style, you can declare an scoped on the style tab as a component style isolation label, such as: < style lang="sass" scoped > < /style > . In the final packaging, the only 1 value of hash is added to the actual style to avoid css pollution among components

Conditional rendering

react: jsx expression, & & Or 3 yuan expression; return false means no rendering vue: The expression returns true to be rendered, and multiple v-else-if, v-else can be nested

List rendering

react: With. map, the key for 1 element is preferably a string with 1 but no 2 that this element has in the list


<ul>
  {props.posts.map((post) =>
    <li key={post.id}>
      {post.title}
    </li>
  )}
</ul>

vue: In order to give Vue a hint so that it can track the identity of each node, thus reusing and reordering existing elements, you need to provide a only 1 key attribute for each item


<li v-for="item in items" :key="item.message">
  {{ item.message }}
</li>

Component nesting

react

Default slot


<div className={'FancyBorder FancyBorder-' + props.color}>
  {props.children}
</div>

Named slot


<div className="SplitPane">
  <div className="SplitPane-left">
    {props.left}
  </div>
  <div className="SplitPane-right">
    {props.right}
  </div>
</div>

<SplitPane left={<Contacts />} right={<Chat />} />

vue

Default slot


// Primary event 
<form v-on:submit.prevent="onSubmit"></form>
// Custom Events 
<my-component @my-event="handleThis(123, $event)"></my-component>
0

Named slot


<header>
  <slot name="header"></slot>
</header>

Get DOM

react: Manage focus, text selection, or media playback. Triggers a forced animation. Integrate the third party DOM library


class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  render() {
    return <div ref={this.myRef} />;
  }
}

vue: Used to register reference information for an element or subcomponent


// Primary event 
<form v-on:submit.prevent="onSubmit"></form>
// Custom Events 
<my-component @my-event="handleThis(123, $event)"></my-component>
3

Document structure

Umi


// Primary event 
<form v-on:submit.prevent="onSubmit"></form>
// Custom Events 
<my-component @my-event="handleThis(123, $event)"></my-component>
4

vue_cli


// Primary event 
<form v-on:submit.prevent="onSubmit"></form>
// Custom Events 
<my-component @my-event="handleThis(123, $event)"></my-component>
5

Route

Dynamic routing & Routing parameter transfer

react-router

history.push(/list?id=${id}) history.push({pathname: '/list', query: {id}}) history.push(/list/id=${id}) history.push({pathname: '/list', params: {id}})

Get props. match. query/props. match. params

vue-router

this.$router.push({path: '/list', query: {id}}) this.$router.push({path: '/list', params: {id}})

Get this. $router. query/this. $router. params

Nested routing

-react


// Primary event 
<form v-on:submit.prevent="onSubmit"></form>
// Custom Events 
<my-component @my-event="handleThis(123, $event)"></my-component>
6

Rendering sub-routes using props. children

vue-router


{
  path: '/user/:id',
  component: User,
  children: [
    {
      path: 'profile',
      component: UserProfile
    },
    {
      path: 'posts',
      component: UserPosts
    }
  ]
}

<div id="app">
  <router-view></router-view>
</div>

Using vue native components/ < router-view/ > Component rendering sub-route

Routing jump

umi


<NavLink exact to="/profile" activeClassName="selected">Profile</NavLink>
history.push(`/list?id=${id}`)

vue


// Primary event 
<form v-on:submit.prevent="onSubmit"></form>
// Custom Events 
<my-component @my-event="handleThis(123, $event)"></my-component>
9

Routing guard (login authentication, special route processing)

Umi vue-router

Global routing guard

Global front guard: router. beforeEach


 const router = new VueRouter({ ... })
 router.beforeEach((to, from, next) => {
   // ...
 })

Global rear guard: router. beforeEach


 router.afterEach((to, from) => {
   // ...
 })

State management

Multiple views depend on the same 1 state or behaviors from different views need to change the same 1 state; You need to use a state manager.

dva vuex 说明
模块 namespace modules 解决应用的所有状态会集中到1个比较大的对象,store对象可能变得相当臃肿
单1状态树 state state 唯1数据源
提交状态机 reducer mutations 用于处理同步操作,唯1可以修改 state 的地方
处理异步操作 effects action 调用提交状态机更改状态树

Use

dva: model connect UI


// new model:models/products.js
export default {
  namespace: 'products',
  state: [],
  reducers: {
    'delete'(state, { payload: id }) {
      return state.filter(item => item.id !== id);
    },
  },
};
//connect model
export default connect(({ products }) => ({
  products,
}))(Products);

//dispatch model reduce
dispatch model reduce({
  type: 'products/delete',
  payload: id,
})

If there is an asynchronous operation, such as ajax request, dispath model effects, then effects calls model reduce
vuex


// new module
const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
  }
})
//bind UI
<input v-model="$store.state[modelesName].name"/>
//commit module mutation 
store.commit('increment')

If there is an asynchronous operation, such as an ajax request, dispath module actions, and then actions calls module mutations


store.dispatch({
  type: 'incrementAsync',
  amount: 10
})

Related articles: