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

    前言

    现在的时代就是vue 和react 的天下,当然在2者之间切换,有时候会忘了一些语法,

    那么下面就比较下2者的语法,啊哈

    Render

    React.js

    ReactDOM.render(<App />, document.getElementById("root"));

    Vue.js

    new Vue({
      render: (h) => h(App),
    }).$mount("#root");

    基本组件

    React.js

    // Class component
    
    class MyReactComponent extends React.Component {
      render() {
        return <h1>Hello world</h1>;
      }
    }
    // Function component
    function MyReactComponent() { return <h1>Hello world</h1>; }

    Vue.js

    <template>
      <h1>Hello World</h1>
    </template>
    <script>
      export default {
        name: "MyVueComponent",
      };
    </script>

    Prop

    React.js

    function MyReactComponent(props) {
      const { name, mark } = props;
      return <h1>Hello {name}{mark}</h1>;
    }
    MyReactComponent.propTypes = {
      name: PropTypes.string.isRequired,
      mark: PropTypes.string,
    }
    MyReactComponent.defaultProps = {
      mark: '!',
    }
    ...
    <MyReactComponent name="world">

    Vue.js

    <template>
      <h1>Hello {{ name }}</h1>
    </template>
    <script>
      export default {
        name: "MyVueComponent",
        props: {
          name: {
            type: String,
            required: true,
          },
          mark: {
            type: String,
            default: "!",
          },
        },
      };
    </script>
    ...
    <MyVueComponent name="World" />

    事件绑定

    React.js

    Class component

    class MyReactComponent extends React.Component {
      save = () => {
        console.log("save");
      };
      render() {
        return <button onClick={this.save}>Save</button>;
      }
    }

    Function component

    function MyReactComponent() {
      const save = () => {
        console.log("save");
      };
      return <button onClick={save}>Save</button>;
    }

    Vue.js

    <template>
      <button @click="save()">Save</button>
    </template>
    <script>
      export default {
        methods: {
          save() {
            console.log("save");
          },
        },
      };
    </script>

    自定义事件

    React.js

    function MyItem({ item, handleDelete }) {
      return <button onClick={() => handleDelete(item)}>{item.name}</button>;
      /*
       * 应用useCallback钩子来防止在每次渲染时生成新的函数。
       *
       * const handleClick = useCallback(() => handleDelete(item), [item, handleDelete]);
       *
       * return <button onClick={handleClick}>{item.name}</button>;
      */
    }
    ...
    function App() {
      const handleDelete = () => { ... }
      return <MyItem item={...} handleDelete={handleDelete} />
    }

    Vue.js

    <template>
      <button @click="deleteItem()">{{item.name}}</button>
    </template>
    <script>
      export default {
        name: "my-item",
        props: {
          item: Object,
        },
        methods: {
          deleteItem() {
            this.$emit("delete", this.item);
          },
        },
      };
    </script>
    ...
    <template>
      <MyItem :item="item" @delete="handleDelete" />
    </template>
    <script>
      export default {
        components: {
          MyItem,
        },
        methods: {
          handleDelete(item) { ... }
        },
      };
    </script>

     

    State

    React.js

    Class component

    class MyReactComponent extends React.Component {
      state = {
        name: 'world,
      }
      render() {
        return <h1>Hello { this.state.name }</h1>;
      }
    }

    Function component

    function MyReactComponent() {
      const [name, setName] = useState("world");
      return <h1>Hello {name}</h1>;
    }

    Vue.js

    <template>
      <h1>Hello {{ name }}</h1>
      <!-- 使用组件状态作为prop -->
      <my-vue-component :name="name">
    </template>
    <script>
      export default {
        data() {
          return { name: "world" };
        },
      };
    </script>

    Change-State

    React.js

    Class component

    class MyReactComponent extends React.Component {
      state = {
        count: 0,
      };
      increaseCount = () => {
        this.setState({ count: this.state.count + 1 });
        // 在更新之前获取当前状态,以确保我们没有使用陈旧的值
        // this.setState(currentState => ({ count: currentState.count + 1 }));
      };
      render() {
        return (
          <div>
            <span>{this.state.count}</span>
            <button onClick={this.increaseCount}>Add</button>
          </div>
        );
      }
    }

    Function component

    function MyReactComponent() {
      const [count, setCount] = useState(0);
      const increaseCount = () => {
        setCount(count + 1);
        // setCount(currentCount => currentCount + 1);
      };
      return (
        <div>
          <span>{count}</span>
          <button onClick={increaseCount}>Add</button>
        </div>
      );
    }

    Vue.js

    <template>
      <div>
        <span>{{count}}</span>
        <button @click="increaseCount()">Add</button>
      </div>
    </template>
    <script>
      export default {
        data() {
          return { count: 0 };
        },
        methods: {
          increaseCount() {
            this.count = this.count + 1;
          },
        },
      };
    </script>

    双向绑定 (仅Vue.js)

    React.js

    React没有双向绑定,因此我们需要自己处理数据流

    function MyReactComponent() {
      const [content, setContent] = useState("");
      return (
        <input
          type="text"
          value={content}
          onChange={(e) => setContent(e.target.value)}
        />
      );
    }

    Vue.js

    <template>
      <input type="text" v-model="content" />
    </template>
    <script>
      export default {
        data() {
          return { content: "" };
        },
      };
    </script>

    计算属性

    React.js

    React.js没有计算属性,但我们可以通过react hook轻松实现

    function DisplayName({ firstName, lastName }) {
      const displayName = useMemo(() => {
        return `${firstName} ${lastName}`;
      }, [firstName, lastName]);
      return <div>{displayName}</div>;
    }
    ...
    <DisplayName firstName="Hello" lastName="World" />

    Vue.js

    <template>
      <div>{{displayName}}</div>
    </template>
    <script>
      export default {
        name: "display-name",
        props: {
          firstName: String,
          lastName: String,
        },
        computed: {
          displayName: function () {
            return `${this.firstName} ${this.lastName}`;
          },
        },
      };
    </script>
    ...
    <DisplayName firstName="Hello" lastName="World" />

    Watch

    React.js

    React.js没有 watch 属性,但是我们可以通过react hook轻松实现

    function MyReactComponent() {
      const [count, setCount] = useState(0);
      const increaseCount = () => {
        setCount((currentCount) => currentCount + 1);
      };
      useEffect(() => {
        localStorage.setItem("my_count", newCount);
      }, [count]);
      return (
        <div>
          <span>{count}</span>
          <button onClick={increaseCount}>Add</button>
        </div>
      );
    }
     

    Vue.js

    <template>
      <div>
        <span>{{count}}</span>
        <button @click="increaseCount()">Add</button>
      </div>
    </template>
    <script>
      export default {
        data() {
          return { count: 0 };
        },
        methods: {
          increaseCount() {
            this.count = this.count + 1;
          },
        },
        watch: {
          count: function (newCount, oldCount) {
            localStorage.setItem("my_count", newCount);
          },
        },
      };
    </script>
     

    Children-and-Slot

    React.js

    function MyReactComponent({ children }) {
      return <div>{children}</div>;
    }
    ...
    <MyReactComponent>Hello World</MyReactComponent>

    Vue.js

    <template>
      <div>
        <slot />
      </div>
    </template>
    <script>
      export default {
        name: "my-vue-component",
      };
    </script>
    ...
    <MyVueComponent>Hello World</MyVueComponent>
     

    渲染HTML

    React.js

    function MyReactComponent() {
      return <div dangerouslySetInnerHTML={{ __html: "<pre>...</pre>" }} />;
    }

    Vue.js

    <template>
      <div v-html="html"></div>
    </template>
    <script>
      export default {
        data() {
          return {
            html: "<pre>...</pre>",
          };
        },
      };
    </script>
     

    条件渲染

    React.js

    function MyReactComponent() {
      const [isLoading, setLoading] = useState(true);
      return (
        <div>
          {isLoading && <span>Loading...</span>}
          {isLoading ? <div>is loading</div> : <div>is loaded</div>}
        </div>
      );
    }
     

    Vue.js

    <template>
      <div>
        <!--v-show: 总是渲染,但根据条件更改CSS-->
        <span v-show="loading">Loading...</span>
        <div>
          <div v-if="loading">is loading</div>
          <div v-else>is loaded</div>
        </div>
      </div>
    </template>
    <script>
      export default {
        data() {
          return { loading: true };
        },
      };
    </script>

    列表渲染

    React.js

    function MyReactComponent({ items }) {
      return (
        <ul>
          {items.map((item) => (
            <li key={item.id}>
              {item.name}: {item.desc}
            </li>
          ))}
        </ul>
      );
    }
     

    Vue.js

    <template>
      <ul>
        <li v-for="item in items" :key="item.id">
          {{item.name}}: {{item.desc}}
        </li>
      </ul>
    </template>
    <script>
      export default {
        props: {
          items: Array,
        },
      };
    </script>

    Render-Props

    React.js

    function Modal({children, isOpen}) {
      const [isModalOpen, toggleModalOpen] = useState(isOpen);
      return (
        <div className={isModalOpen ? 'open' : 'close'}>
          {type children === 'function' ? children(toggleModalOpen) : children}
        </div>)
      ;
    }
    Modal.propTypes = {
      isOpen: PropTypes.bool,
      children: PropTypes.oneOfType([PropTypes.string, PropTypes.element]).isRequired,
    }
    Modal.defaultProps = {
      isOpen: false,
    }
    ...
    <Modal isOpen>
      {(toggleModalOpen) => {
        <div>
          <div>...</div>
          <button onClick={() => toggleModalOpen(false)}>Cancel</button>
        </div>
      }}
    </Modal>

    Vue.js(slot)

    <template>
      <div v-show="isModalOpen">
        <slot v-bind:toggleModal="toggleModalOpen" />
      </div>
    </template>
    <script>
      export default {
        name: "modal",
        props: {
          isOpen: {
            type: Boolean,
            default: false,
          },
        },
        data() {
          return {
            isModalOpen: this.isOpen,
          };
        },
        methods: {
          toggleModalOpen(state) {
            this.isModalOpen = state;
          },
        },
      };
    </script>
    ...
    <Modal isOpen>
      <template v-slot="slotProps">
        <div>...</div>
        <button @click="slotProps.toggleModal(false)">Close</button>
      </template>
    </Modal>

    生命周期

    React.js

    Class component

    class MyReactComponent extends React.Component {
      static getDerivedStateFromProps(props, state) {}
      componentDidMount() {}
      shouldComponentUpdate(nextProps, nextState) {}
      getSnapshotBeforeUpdate(prevProps, prevState) {}
      componentDidUpdate(prevProps, prevState) {}
      componentWillUnmount() {}
      render() {
        return <div>Hello World</div>;
      }
    }
     

    Function component

    function MyReactComponent() {
      // componentDidMount
      useEffect(() => {}, []);
      // componentDidUpdate + componentDidMount
      useEffect(() => {});
      // componentWillUnmount
      useEffect(() => {
        return () => {...}
      }, []);
      // 在渲染之后但在屏幕更新之前同步运行
      useLayoutEffect(() => {}, []);
      return <div>Hello World</div>;
    }

    Vue.js

    <template>
      <div>Hello World</div>
    </template>
    <script>
      export default {
        beforeCreate() {},
        created() {},
        beforeMount() {},
        mounted() {},
        beforeUpdate() {},
        updated() {},
        beforeDestroy() {},
        destroyed() {},
      };
    </script>

    错误处理

    React.js

    class ErrorBoundary extends React.Component {
      state = { hasError: false };
      static getDerivedStateFromError(error) {
        // 更新状态,这样下一个渲染将显示回退UI。
        return { hasError: true };
      }
      componentDidCatch(error, errorInfo) {}
      render() {
        if (this.state.hasError) return <h1>Something went wrong.</h1>;
        return this.props.children;
      }
    }
    ...
    <ErrorBoundary>
      <App />
    </ErrorBoundary>

    Vue.js

    const vm = new Vue({
      data: {
        error: "",
      },
      errorCaptured: function(err, component, details) {
        error = err.toString();
      }
    }

    Ref

    React.js

    Class component

    class AutofocusInput extends React.Component {
      constructor(props) {
        super(props);
        this.ref = React.createRef();
      }
      state = {
        content: "",
      };
      componentDidMount() {
        this.ref.current.focus();
      }
      setContent = (e) => {
        this.setState({ content: e.target.value });
      };
      render() {
        return (
          <input
            ref={this.ref}
            type="text"
            value={this.state.content}
            onChange={this.setContent}
          />
        );
      }
    }

    Function component

    function AutofocusInput() {
      const [content, setContent] = useState("");
      const ref = useRef(null);
      useEffect(() => {
        if (ref && ref.current) {
          ref.current.focus();
        }
      }, []);
      return (
        <input
          ref={ref}
          type="text"
          value={content}
          onChange={(e) => setContent(e.target.value)}
        />
      );
    }
    
    

    Vue.js

    <template>
      <input ref="input" type="text" v-model="content" />
    </template>
    <script>
      export default {
        name: "autofocus-input",
        data() {
          return { content: "" };
        },
        mounted() {
          this.$refs.input.focus();
        },
      };
    </script>

    性能优化

    React.js

    PureComponent

    class MyReactComponent extends React.PureComponent {
      ...
    }

    shouldComponentUpdate

    class MyReactComponent extends React.Component {
      shouldComponentUpdate(nextProps) {...}
      ...
    }

    React.memo

    export default React.memo(
      MyReactComponent,
      (prevProps, nextProps) => {
        ...
      }
    );

    useMemo

    export default function MyReactComponent() {
      return React.useMemo(() => {
        return <div>...</div>;
      }, []);
    }
     

    useCallback

    function MyItem({ item, handleDelete }) {
      const handleClick = useCallback(() => handleDelete(item), [
        item,
        handleDelete,
      ]);
      return <button onClick={handleClick}>{item.name}</button>;
    }

    Vue.js

    v:once

    <span v-once>This will never change: {{msg}}</span>
     

    函数式组件:我们可以将组件标记为 functional,这意味它无状态 (没有响应式数据),也没有实例 (没有 this 上下文)。

    <template functional>
      <h1>Hello {{ name }}</h1>
    </template>
    <script>
      export default {
        name: "MyVueComponent",
        props: {
          name: String,
        },
      };
    </script>
     

    keep-alive 组件

    <keep-alive>
      <component :is="view"></component>
    </keep-alive>

    以上就是整理的一些资料对比,也查考一些资料,

    哈哈,继续努力

  • 相关阅读:
    ZOJ 2588 Burning Bridges
    POJ 1966 ZOJ 2182 Cable TV Network
    HDU 5348 MZL's endless loop
    HDU 5352 MZL's City
    Tarjan算法求解无向连通图的割点、割边、点双连通分量和边双连通分量的模板
    ZOJ 1119 SPF
    HDU 3452 Bonsai
    HDU 1520 Anniversary party
    POJ 2239 Selecting Courses
    POJ 1144 Network
  • 原文地址:https://www.cnblogs.com/yf-html/p/12843675.html
Copyright © 2011-2022 走看看