Vue and React are among the most popular and ecological front-end frameworks available. The framework itself is not superior or inferior, only applicable, and the most important goal is to choose the technology that fits our business scenario and team base.

The blogger used Vue framework a year ago and transferred to React framework in the past six months. She has some basic understanding of BOTH Vue and React. Next, we will take a closer look at Vue and React and discuss the differences between them. (If you are using Vue and are interested in React, take a look and vice versa)

Overall content overview:

In the middle section, we will compare VUE and React mainly from eight aspects: conditional rendering, display or not, list rendering, computing properties, listeners, refs, forms and slots. Welcome more exchanges and discussion. Thanks for your support.

React vs. Vue

9. Conditional Rendering (V-if vs &&)

Conditional rendering is used to determine whether to render a piece of content based on conditions.

vue

Vue uses v-if instructions to conditionally render a piece of content. V-if is rendered only when the expression returns a true value. V-if can also be used with v-else and V-else to render under different conditions, similar to the if else syntax in JS.

(1) Basic usage

 <div v-if="showContent">This is content.</div>
Copy the code

data

  data() {
    return {
      showContent: false}}Copy the code

When showContent is false, the DOM node is not rendered and a comment flag is left behind.

DOM nodes are rendered only when showContent is true.

(2) V-else double judgment

When v-if and V-else are used together, v-else must be adjacent to v-if; otherwise, an error will be reported.

  <div>
    <div v-if="showContent">This is content.</div>
    <div v-else>Hide content.</div>
  </div>
Copy the code

(3) V-else -if multiple judgment

When there are multiple judgments, you can use v-else-if, similar to v-if’s else-if block. The V-else element must come immediately after the element with v-if or v-else-if, otherwise it will not be recognized.

<div v-if="type === 'A'">
  A
</div>
<div v-else-if="type === 'B'">
  B
</div>
<div v-else-if="type === 'C'">
  C
</div>
<div v-else>
  Not A/B/C
</div>
Copy the code

(4) Template uses v-if

Additionally, when you want to switch between multiple elements, use v-if on

<template v-if="ok">
  <h1>Title</h1>
  <p>Paragraph 1</p>
  <p>Paragraph 2</p>
</template>
Copy the code

react

React uses the ampersand operator && and the trinary operator (? :), if else to achieve conditional rendering effect.

(1) and operator

Like the && operator, the effect is similar to v-if, rendering elements on the right when the left variable is true.

 return (
      <div>
        {showItem && <div>This is content.</div>}
      </div>
    );
Copy the code

(2) The trinary operator (? :)

Use the trinary operator (? If showItem is true, the first element is displayed. If showItem is false, the second element is displayed.

 return (
      <div>
        {
          showItem ?
            (<div>This is true content.</div>) : (<div>This is false content.</div>)
        }
      </div>
    );
Copy the code

(3) Multiple judgments

When dealing with multiple judgments, you can use the function plus if else multiple judgments or switch case to achieve the same effect as V-if V-else v-if V-else.

ⅰ. If-else multiple judgment

render() {
    const { type } = this.state;
    const toggeleShow = (type) = > {if (type= = ='A') {
        return <div>A</div>;
      } else if (type= = ='B') {
        return <div>B</div>;
      } else if (type= = ='C') {
        return <div>C</div>;
      } else {
        returnnull; }};return (
      <div>
        {toggeleShow(type)}
      </div>
    );
  }
Copy the code

ⅱ. Switch Case Multiple judgment

render () {
    const { type } = this.state;
    const toggeleShow = (type) => {
      switch (type) {
        case 'A':
          return <div>A</div>;
        case 'B':
          return <div>B</div>;
        case 'C':
          return <div>C</div>;
        default:
          returnnull; }};return (
      <div>
        {toggeleShow(type)}
      </div>
    );
  }
Copy the code

10. Whether to display (v-show vs style+class)

Another option for displaying conditional elements is v-show, which can be implemented with a style or class switch.

vue

Elements rendered by v-show are rendered and retained in the DOM. V-show simply toggles the element’s CSS attribute display.

 <div v-show="showContent">This is content.</div>
Copy the code

If showContent is false, the display property of style is None.

When showContent is true, the display attribute of style is block (the default display attribute of the element).

Note that v-show does not support

V-if vs V-show

  • 1)v-ifIs “true” conditional rendering because it ensures that event listeners and subcomponents within the conditional block are properly destroyed and rebuilt during the switch.
  • 2)v-ifAlso lazy: if the condition is false during the initial render, nothing is done — the conditional block does not start rendering until the condition is true for the first time.
  • 3) By contrast,v-showIt’s much simpler — regardless of the initial conditions, elements are always rendered and simply switched based on CSS.
  • 4) Generally speaking,v-ifThere is a higher switching overhead, whilev-showThere is a higher initial rendering overhead. Therefore, if you need to switch very frequently, usev-showBetter; If conditions rarely change at run timev-ifIs better.

react

React changes style or class to achieve a similar effect to v-show.

Modify the display attribute of the style attribute to switch whether to display.

<div style={{ display: showItem ? 'block' : 'none' }}>
    This is content.
</div>
Copy the code

Class is changed by variable judgment, which is essentially the display attribute of the element.

When changing element styles dynamically in React (e.g., tab-switching, button selection), use class.

 const itemClass = showItem ? 'show-item-class' : 'hide-item-class';
    return (
      <div className={itemClass}>
        This is content.
      </div >
    );
Copy the code

The class style:

.show-item-class {
  display: block;
}
.hide-item-class {
  display: none;
}
Copy the code

11. List Rendering (V-for vs Map)

Vue uses V-for to render lists, react uses Map to render lists. Both V-for and Map rendering lists require a key value (the key must be unique between siblings) to quickly compare the differences between the old and new virtual DOM trees.

vue

Vue can use V-for to render arrays, objects,

(1) Render the array

When rendering an array, use a special syntax of the form (item, index) in items, where items is the source data array, item is the alias of the array element being iterated over, and index represents the index of the current element.

  <div>
    <div v-for="(item, index) in items" :key="item.message + index">
      {{item.message}}
    </div>
  </div>
Copy the code

data

 data() {
    return {
      items: [
        {
          message: 'Hello'
        },
        {
          message: 'Welcome'}}}]Copy the code

(2) Render objects

V-for can also be used to iterate over attributes of an object in the form of (value, key, index) in obj, where key represents the key value of the object, value represents the value of the object, and index represents the current index.

When traversing objects, the result of object.keys () is used, but its results are not guaranteed to be consistent across different JavaScript engines.

<div v-for="(value, key, index) in obj" :key="key + index">
  {{index}}.{{key}}: {{value}}
</div>
Copy the code

data

  data() {
    return {
      obj: {
        name: 'xiaoming',
        age: 18,
        sex: 'male',
        height: 175
      }
    }
  }
Copy the code

(3) Render multiple elements

Use V-for on

Binding keys is not allowed when v-for is used to render element segments on

<div>
    <template v-for="(item, index) in items">
      <div :key="item.message">{{ item.message }}</div>
      <div :key="item.message + index" class="divider"></div>
    </template>
  </div>
Copy the code

data

 data() {
    return {
     items: [
       {
         message: 'hello'
       },
       {
         message: 'world'
       },
       {
         message: 'welcome'}}},Copy the code

When the DOM is generated, no actual DOM nodes are generated.

(4) Render a list of custom components

On custom components, you can use V-for to render a list of custom components, passing data to the component via props.

Key is required when v-for is used on components.

V-for renders a list of custom components, passing the item to the component via props.

 <my-component 
    v-for="(item, index) in items" 
    :key="item.message + index" 
    :item="item">
  </my-component>
Copy the code

The my-component uses props to receive data from the parent component.

<template>
  <div>{{item.message}}</div>
</template>

<script>
export default {
  props: ['item'].data() {
    return { }
  }
}
</script>
Copy the code

react

React uses the map() method to render lists.

(1) Render the array

Iterate over each element in the array to get a list of JSX elements. Each element in the array needs a unique key.

  render() {
    const items = [
      {
        message: 'hello'
      },
      {
        message: 'world'
      },
      {
        message: 'welcome'}]; const listItems = items.map((item, index) => <div key={item.message + index}>{item.message}</div>);return (
      <div>
        {listItems}
      </div>
    );
  }
Copy the code

(2) Render objects

For objects, methods can be used to traverse objects through object.keys () or object.entries ().

  render() {
    const obj = {
      name: 'xiaoming',
      age: 18,
      sex: 'male',
      height: 175
    };
    const renderObj = (obj) => {
      const keys = Object.keys(obj);
      return keys.map((item, index) => <div key={index}>{obj[item]}</div>);
    };
    return (
      <div>
        {renderObj(obj)}
      </div>
    );
  }
Copy the code

(3) Render a list of custom components

Rendering a custom component list is similar to vUE, where you add a key identifier to the component.

  render() {
    const items = [
      {
        message: 'hello'
      },
      {
        message: 'world'
      },
      {
        message: 'welcome'}]; const listItems = items.map((item, index) => <ListItem message={item.message} key={item.message + index} />);return (
      <div>
        {listItems}
      </div>
    );
  }
Copy the code

12. Computed attributes (computed vs useMemo+useCallback)

Computed properties represent data that needs to be reevaluated and “saved” based on the component’s data (both its own data and the props receiving the parent component). The benefit of using computed properties is to avoid the overhead of each recomputation (such as iterating through a large array and doing a lot of calculations).

vue

Vue uses computed to represent computed properties. You can define multiple computed properties that can be called to each other. Computed properties are cached based on their reactive dependencies. They are reevaluated only when the associated reactive dependencies change. In vue, you can use this. XXX to get calculated properties directly.

(1) Basic usage

The following statement states that the calculated property reversedMessage is dependent on Message, which means that multiple visits to the reversedMessage calculated property will immediately return the calculated result as long as the message has not changed.

<div>
    message: <input type="text" v-model="message" />
    <div>{{reversedMessage}}</div>
</div>
Copy the code

script

  data() {
    return {
      message:' '
    }
  },
  computed: {
    reversedMessage() {
      return this.message.split(' ').reverse().join(' ')}}Copy the code

(2) Calculate the setter for the property

Technical properties only have getters by default, but setters can also be used, and setter callbacks are triggered when a calculated property is modified.

script

data() {
    return {
      message:' ',
      info: ' '
    }
  },
  computed: {
    reversedMessage: {
      get() {// get callbackreturn this.message.split(' ').reverse().join(' ')},set(newValue) { // setThis.info = newValue}}}, methods: {changeMessage(event) {// Modify the reversedMessage calculation property this.reversedMessage = event.target.value; }}Copy the code

react

React hooks use useMemo for memoized values and useCallback for Memoized callback functions, implementing functions similar to computed in VUE.

Application scenario: If child components use PureComponent or React. Memo, consider encapsulating the props provided to them with useMemo and useCallback to take advantage of the shallow comparison capabilities of these components.

(1) useMemo

UseMemo returns a memoized value. UseMemo relies on certain dependency values and recalculates memoized values only when a dependency changes. If the dependency array is not provided, useMemo evaluates the new value each time it renders. UseMemo can be used as a means of performance optimization.

Functions passed into useMemo are executed during rendering. Please do not perform non-rendering operations inside this function. Operations such as side effects are used by useEffect, not useMemo.

function NewComponent(props) {
  const { num } = props;
  const [size, setSize] = useState(0); // Max is an memoized value returned by useMemo const Max = useMemo(() => math.max (num, size), [num, size]);return (<div>
    <input
      type="number"
      value={size}
      onChange={(e) => setSize(e.target.value)} />
    <div>Max {max}</div>
  </div>);
}
Copy the code

(2) useCallback

UseCallback passes the inline callback function and an array of dependencies as arguments to useCallback, which returns a Memoized version of the callback function that is updated only when a dependency changes. This is useful when you pass callback data to optimised and use reference equality to avoid unnecessary rendering (such as child components of shouldComponentUpdate).

function NewComponent(props) {
  const [message, setMessage] = useState('hello world.');
  const handleChange = useCallback((value) => {
    setMessage(value); } []);return (<div>
    <input
      type="number"
      value={message}
      onChange={(e) => handleChange(e.target.value)} />
    <div>{message}</div>
  </div>);
}
Copy the code

13. Listener (Watch vs getDerivedStateFromProps + componentDidUpdate)

Listeners perform asynchronous or data operations by listening for changes in props or component data (data or state).

vue

In VUE, the watch monitors changes in props, data, and computed attributes to perform asynchronous or expensive operations.

The Following ProjectManage component monitors the changes of projectId Prop through the Watch to obtain the corresponding project information.

export default {
  name: "ProjectManage",
  props: ["projectId"].data() {
    return {
      projectInfo: null
    };
  },
  watch: {
    projectId(newVaue, oldValue) {
      if(newVaue ! == oldValue) { this.getProject(newValue); } } }, methods: { getProject(projectId) { projectApi .getProject(projectId) .then(res => { this.projectInfo = res.data; }) .catch(err => { this.$message({
            type: "error", message: err.message }); }); }}};Copy the code

react

React uses static getDerivedStateFromProps() and componentDidUpdate() to implement the listener function.

(1)static getDerivedStateFromProps()

GetDerivedStateFromProps is called before the Render method is called, and is called both during the initial mount and during subsequent updates. It should return an object to update state, and if null is returned, nothing is updated.

Two points about getDerivedStateFromProps:

  • 1) No matter whatpropsChange, implementationsetStateorforceUpdateActions trigger this method before each render.
  • 2) whenstateThe value of is dependent at any timepropsIs applicable to this method.
class NewComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      info: ' '}} static getDerivedStateFromProps(nextProps, prevState) {// The info in state is synchronized from the info in propsif(nextProps.info ! == prevState.info) {return {
        info: nextProps.info
      }
    }
    return null;
  }
  render() {
    const { info } = this.state;
    return <div>{info}</div>
  }
}
Copy the code

(2)componentDidUpdate()

The componentDidUpdate() method is called after a component is updated. This method is not performed for the first rendering. This is where you can manipulate the DOM, perform setState, or perform asynchronous request operations when the component is updated.

componentDidUpdate(prevProps, prevState, snapshot)
Copy the code

For componentDidUpdate there are four points:

  • 1)componentDidUpdate()The third parameter ofsnapshotParameter sourcegetSnapshotBeforeUpdate()The return value of the life cycle. If not implementedgetSnapshotBeforeUpdate(), the parameter value isundefined.
  • 2) Can be incomponentDidUpdate()Call directly fromsetState(), but it must be wrapped in a conditional statement, otherwise it will cause an infinite loop.
  • 3) Can be incomponentDidUpdate()Before and after the updatepropsCompare and perform asynchronous operations.
  • 4) ifshouldComponentUpdate()The return value isfalseIs not calledcomponentDidUpdate().

The following NewComponent is judged in componentDidUpdate()

class NewComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      projectInfo: null
    }
  }
  getProject = (projectId) => {
    projectApi
      .getProject(projectId)
      .then(res => {
        this.projectInfo = res.data;
      })
      .catch(err => {
        message.error(err.message);
      });
  }
  componentDidUpdate(prevProps) {
    if (this.props.projectId !== prevProps.projectId) {
      this.getProject(this.props.projectId);
    }
  }
  render() {
    const { projectInfo } = this.state;
    return <React.Fragment>
      <div>{projectInfo.name}</div>
      <div>{projectInfo.detail}</div>
      </React.Fragment>
  }
}
Copy the code

14.ref

Ref is used to register reference information for an element or child component, allowing us to access the child component or child node.

Ref is used for:

  • Manage focus, text selection or media playback.
  • Trigger the forced animation.

vue

Assign an ID reference to a component or child element by setting the attribute ref to the component or child element.

$refs only take effect after the component is rendered, and they are not reactive. This is only used as an “escape hatch” for direct manipulation of child components — you should avoid accessing $refs in templates or computed properties.

(1) The child element references ref

Ref is referenced on the child element

 <div>
    <input type="text" v-model="message" ref="inputMessage"  />
  </div>
Copy the code

After loading the input box automatically get focus

mounted() {
  this.$refs.inputMessage.focus();
}
Copy the code

(2) The subcomponent references ref

The child component reference ref is often used when the parent uses the child component.

Common form validation is done this way.

<template>
  <div>
    <el-form ref="createForm" label-width="80px" :model="form" :rules="rules">
      <el-form-item label="Name" prop="name">
        <el-input v-model="form.name"></el-input>
      </el-form-item>
      <el-form-item label="Email" prop="email">
        <el-input v-model="form.email"></el-input>
      </el-form-item>
    </el-form>
    <el-button @click="handleSubmit"</el-button> </div> </template> <script>export default {
  name: 'CreateForm'.data() {
    return {
      form: {
        name: ' ',
        email: ' '
      },
      rules: {
        name: [{required: true, message: 'Name cannot be empty', trigger: 'blur'}],
        email: [
          { required: true, message: 'Please enter email address', trigger: 'blur' },
          { type: 'email', message: 'Please enter the correct email address', trigger: ['blur'.'change']}
        ] 
      }
    }
  },
  methods: {
    handleSubmit() {
      this.$refs.createForm.validate((valid) => {
        console.log(valid);
      })
    }
  }
}
</script>
Copy the code

react

In React, the class component binds the ref attribute with react. CreateRef (after React V16.0), while the function component binds the ref attribute with useRef. You can also use the React. ForwardRef to forward the REF property to a child component.

(1) Class component binding ref

Use React. CreateRef to generate the ref in the constructor, bind it to the input element, and focus automatically after loading.

class NewComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      message: 'hello world'
    };
    this.inputRef = React.createRef();
  }
  componentDidMount() {
    this.inputRef.current.focus();
  }
  render() {
    const { message } = this.state;
    return (<div>
      <input
        type="number"ref={this.inputRef} /> <div>{message}</div> </div>); }}Copy the code

(2) Function component binding ref

Function components can bind the ref attribute using useRef. UseRef returns a mutable ref object whose.current property is initialized as the passed parameter (initialValue). The ref object returned remains constant throughout the life of the component.

function NewComponent() {
  const [message, setMessage] = useState('hello world.'); const inputRef = useRef(null); useEffect(() => { inputRef.current.focus(); } []);return (<div>
    <input type="number" ref={inputRef} />
    <div>{message}</div>
  </div>);
}
Copy the code

ForwardRef forwards the ref to the subcomponent

The React. ForwardRef creates a React component that forwards the ref properties it receives to another component in its component tree.

This technique is uncommon, but is particularly useful in two scenarios:

  • forwardingrefstoDOMcomponent
  • Forwarding in higher-order componentsrefs

The parent component passes the REF property directly to the child component NewComponent.

function Parent() { const inputRef = useRef(null); useEffect(() => { inputRef.current.focus(); } []);return <div>
     <NewComponent ref={inputRef}><h2>This is refs.</h2></NewComponent>
  </div>;
}
Copy the code

The child component uses the react. forwardRef function as an argument, and the parent component focuses on the input box after loading.

const NewComponent = React.forwardRef((props, ref) => (<div>
  <input type="number" ref={ref} />
  <div>{props.children}</div>
</div>));
Copy the code

15. Forms (V-Model vs Value)

For forms, VUE uses V-Model to implement two-way data binding on form components, while React manages form data as controlled components by binding value properties to form components.

vue

The V-model directive creates two-way data binding on the ,

The V-Model internally uses different attributes for different input elements and throws different events:

  • textandtextareaElements usingvalueProperties andinputEvents;
  • checkboxandradiousecheckedProperties andchangeEvents;
  • selectField willvalueAs apropAnd will bechangeAs an event.

(1) Basic usage

Ⅰ text.

The INPUT box is bound with the V-model attribute binding MSG. When the input value of input is modified, MSG will automatically synchronize the input value to the user.

 <div>
  <input v-model="msg" />
</div>
Copy the code

V-model writing is equivalent to the combination of :value and @input. :value binds the input value, and @input means receiving input events to modify the value of MSG to the input value, so as to achieve bidirectional binding.

<div>
  <input :value="msg" @input="e => (msg = e.target.value)" />
</div>
Copy the code
Ⅱ. Check box

A single check box is bound to a Boolean value

<div>
  <input type="checkbox" v-model="checked" />
  <label for="checkbox">{{ checked }}</label>
</div>
Copy the code

Multiple check boxes bound to an array

<div>
    <input type="checkbox" id="apple" value="apple" v-model="selectedFruits" />
    <label for="jack">apple</label>
    <input
      type="checkbox"
      id="banana"
      value="banana"
      v-model="selectedFruits"
    />
    <label for="john">banana</label>
    <input type="checkbox" id="mango" value="mango" v-model="selectedFruits" />
    <label for="mango">mango</label>
    <div>Selected fruits: {{ selectedFruits }}</div>
  </div>
Copy the code

data

 data() {
    return {
      selectedFruits: []
    };
  }
Copy the code
Ⅲ. Select box

1) Bind string when selecting box radio

<div>
  <select v-model="selected">
    <option
      v-for="option in options"
      :value="option.value"
      :key="option.value"
    >
      {{ option.text }}
    </option>
  </select>
  <div>Selected: {{ selected }}</div>
</div>
Copy the code

data

data() {
  return {
    selected: "A",
    options: [
      { text: "One", value: "A" },
      { text: "Two", value: "B" },
      { text: "Three", value: "C"}}; }Copy the code

2) If the selection box is multi-selected, the binding is array

<div>
  <select v-model="selected" multiple>
    <option
      v-for="option in options"
      :value="option.value"
      :key="option.value"
    >
      {{ option.text }}
    </option>
  </select>
  <div>Selected: {{ selected }}</div>
</div>
Copy the code

data

 data() {
  return {
    selected: ["A"], // multiple options bind array options: [{text:"One", value: "A" },
      { text: "Two", value: "B" },
      { text: "Three", value: "C"}}; }Copy the code

The #### (2) modifier vue extends the V-model. Lazy,. Number, and. Trim modifier enhancements.

Ⅰ lazy.

By default, v-Model synchronizes the value of the input box with the data after each input event is triggered. The. Lazy modifier was added and converted to a change event for synchronization.

<! -- update when "change" is not "input" --> <input V-model. lazy="msg" >
Copy the code
Ⅱ number.

The.number modifier automatically converts user input to numeric type, especially useful when working with numeric form items.

 <input type="number" v-model.number="num" />
Copy the code
Ⅲ trim.

The. Trim modifier automatically filters the first and last whitespace characters entered by the user.

 <input v-model.trim="msg" />
Copy the code

(3) Use custom componentsv-model

By default, a V-Model on a component makes use of a prop named Value and an event named Input.

InputMessage Binding v-model value is MSG

  <InputMessage v-model="msg" />
Copy the code

The InputMessage component receives the value via the value props, emits the input event to the parent component, and modifies the value of MSG in the parent component.

<template>
  <input v-model="message" @input="$emit('input', $event.target.value)" />
</template>

<script>
export default {
  name: "InputMessage",
  props: ["value"].data() {
    return{ message: this.value }; }};Copy the code

(4) Form components (files, etc.) that cannot be managed by V-Model

For a form component of a type like , you can’t use the V-model to manage component data. Instead, you can use refs to manage the data of the form component.

<template>
  <div>
    <input type="file" ref="file" @change="fileChange" />
  </div>
</template>

<script>
export default {
  name: "InputFile".data() {
    return {};
  },
  methods: {
    fileChange() {
      const file = this.$refs.file.files[0]; console.log(file); }}}; </script>Copy the code

react

In React, form elements (

(1) Controlled components

In a controlled component, state acts as the component’s “sole data source” and the component also controls what happens to the form during user operations.

class CreateForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: ' '}} nameChange = (event) => {// Receive event as parameter this.setState({name: event.target.value}); }render() {
    const { name } = this.state; 
    return (
    <div>
      <input value={name} onChange={this.nameChange} />
      <div> name: {name} </div>
    </div>)
  }
}
Copy the code

(2) Uncontrolled components

In React, form components that cannot be managed in state mode are called uncontrolled components. The values of uncontrolled components cannot be controlled by code, and the form data is processed by DOM nodes. For uncontrolled components, you can use a REF to get form data from a DOM node.

is always an uncontrolled component that gets file data by creating a ref.

class CreateForm extends React.Component {
  constructor(props) {
    super(props);
    this.fileRef = React.createRef(null);
  }

  fileChange = (event) => {
    event.preventDefault();
    const file = this.fileRef.current.files[0];
    console.log(file)
  }

  render() {
    return (
    <div>
      <input type="file" ref={this.fileRef} onChange={this.fileChange} />
    </div>)
  }
}
Copy the code

16. Slot (slot vs Render Props+this.props. Children)

Slots are implemented in Vue and React. Slots are implemented in Vue, and slots are implemented in React using this.props. Children and Render props.

vue

Vue uses

to implement slots, including default slots, named slots, and scoped slots.

(1) Default slot

The default slot uses
to reserve “space” within the component for distribution. The start and end tags of the component can contain any code, such as HTML or other components.

There are two caveats about default slots:

(1) If slots are not used, content inserted into the component will not be rendered. (2) The slot can set the backup content, which is displayed when no content is inserted.

Components that use default slots:

</div> <h2>Slot: </h2> < Slot >Default content.</ Slot >export default {
  name: "SlotComponent".data() {
    return{}; }}; </script>Copy the code

The parent component uses this component to add slot content to the component start tag and end tag.

<slot-component>
  <h2>This is slot component.</h2>
</slot-component>
Copy the code

Eventually the slot content is inserted into the component’s
placeholder.

<div> <h2>Slot: </h2> <h2>This is Slot component.Copy the code

Default slot content is rendered when no slot content is added to

.

<div> <h2>Slot: </h2> Default content. </div>Copy the code

(2) Named slot

Only one slot can be inserted into the default slot. When multiple slots are inserted, a named slot is required. The slot element has a default attribute name that defines the named slot.

The name of the default slot is default.

When feeding content to a named slot, we can insert the content under the corresponding slot by using the V-slot directive on a

V-slot: can also be abbreviated as #, for example v-slot:footer can be rewritten as #footer.

The slot-component has a header footer, two named slots and a default slot.

<template>
  <div>
    <header>
      <slot name="header">
        Header content.
      </slot>
    </header>
    <main>
      <slot>
        Main content.
      </slot>
    </main>
    <footer>
      <slot name="footer">
        Footer content.
      </slot>
    </footer>
  </div>
</template>
Copy the code

Insert contents into slots separately:

<slot-component>
  <template v-slot:header>
    <div>This is header content.</div>
  </template>
  <template>
    <div>This is main content.</div>
  </template>
  <template #footer>
    <div>This is footer content.</div>
  </template>
</slot-component>
Copy the code

The final HTML will be rendered as:

<div>
  <header>
    <div>This is header content.</div>
  </header>
  <main>
    <div>This is main content.</div>
  </main>
  <footer>
    <div>This is footer content.</div>
  </footer>
</div>
Copy the code

(3) Scope slot

Scope slots come in handy when we need to display the data contents of the slot component in the parent component.

Scoped slots need to bind attributes to

elements, which is called slot prop. In the parent scope, we can use v-slot with a value to define the name of the slot prop we provide.

Slot components

<template>
  <div>
    <header>
      <slot name="header">
        Header content.
      </slot>
    </header>
    <main>
      <slot :person="person">
        {{ person.name }}
      </slot>
    </main>
  </div>
</template>

<script>
export default {
  name: "SlotComponent".data() {
    return {
      person: {
        name: "xiaoming",
        age: 14
      }
    };
  },
  methods: {}
};
</script>
Copy the code

The parent component scope names the object that contains all the slotProps as slotProps, or you can use any name you like.

 <slot-component>
  <template slot="header"> <div>This is header content.</div> </template> // Define the name of slot 'prop' with a value of 'v-slot' <template V-slot :default="slotProps"> 
    <div>{{ slotProps.person.name }}</div>
    <div>{{ slotProps.person.age }}</div>
  </template>
</slot-component>
Copy the code

The final HTML will be rendered as:

<div>
  <header>
    <div>This is header content.</div>
  </header>
  <main>
    <div>xiaoming</div>
    <div>14</div>
  </main>
</div>
Copy the code

react

React uses this.props. Children and Render props to implement slots similar to vue.

(1) this. Props. Children

Each component can get the content between the component’s start tag and end tag via this.props. Children, which is similar to the default slot in vue.

Use this.props. Children in the class component and props. Children in the function component. The class component uses this.props. Children to get the child element content.

class NewComponent extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    return <div>{this.props.children}</div>
  }
}
Copy the code

The function component uses props. Children to get the child element content.

function NewComponent(props) {
  return <div>>{props.children}</div>
}
Copy the code

The parent component uses the NewComponent component

 <NewComponent>
   <h2>This is new component header.</h2>
   <div>
     This is new component content.
   </div>
 </NewComponent>
Copy the code

The final HTML will be rendered as:

<div>
  <h2>This is new component header.</h2>
  <div>This is new component content.</div>
</div>
Copy the code

(2) Render props

Render Prop is a technique for sharing code between React components using a prop with a value of function. Render Prop is a function prop that tells components what to render.

For example, the Route component prop in the react-router-DOM uses the typical render prop usage.

<Router history={browserHistory}>
    <Route path="/"Component ={Index}> // Component props receives specific components <IndexRoute Component ={HomePage} /> <Route path="/users" component={Users} />
    </Route>
  </Router>
Copy the code

Functionality similar to named slots in Vue can be achieved with multiple Render Prop.

NewComponent defines header, main, and Footer Prop.

class NewComponent extends React.Component {
  constructor(props) {
    super(props);
  }
  render() {
    const { header, main, footer, children } = this.props;
    return(<div> <header> {header || (<div>Header content.</div>)} </header> <main> {main || (<div>Main content.</div>)} </main> {children} <footer> {footer || (<div>Footer content.</div>)} </footer> </div>); }}Copy the code

The parent component passes Render Prop to the child component.

 <NewComponent 
    header={<div>This is header content.</div>}
    content={<div>This is main content.</div>}
    footer={<div>This is footer content.</div>}>
    <div>
      This is new component children.
    </div>
</NewComponent>
Copy the code

The final HTML will be rendered as

<div> <header> <div>This is header content.</div> </header> <main> <div>This is main content.</div> </main> <div>This is  new component children.</div> <footer> <div>This is footer content.</div> </footer> </div>Copy the code

conclusion

The above is the comparison between React and Vue and the middle part of my personal thinking. If you think there is something to gain, you can follow it and give a thumb-up. The code word is not easy, thanks a lot.