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>

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

    哈哈,继续努力

  • 相关阅读:
    《流畅的Python》Data Structures--第7章 colsure and decorator
    CSS Reset 2.0标准
    Layout
    一个简单的例子 vux mutation改变状态
    __WEBPACK_IMPORTED_MODULE_3_vuex__.a is not a constructor
    vuex 使用
    (转)Vue-初步了解vue-router的三要素:路由map 、路由视图、路由导航
    router-link-active 和 router-link-exact-active router-link-active
    当前目录 根目录 写法
    mode: 'history', 去掉路由地址的#
  • 原文地址:https://www.cnblogs.com/yf-html/p/12843675.html
Copyright © 2011-2022 走看看