vue语法和react语法对比

时间:2024-02-20 09:16:36

目录

前言:

语法对比:

定义数据,改变数据

计算属性(缓存计算结果):

显示/隐藏dom元素:

循环数据:

监听:

style样式:

Class:

父组件状态传递到子孙组件中 provide/inject:

插槽slots:


前言:

作为前端框架的绝代双骄,react和vue都是必须要会的,很多人可能只熟悉甚至精通其中的一种,但是对另一种框架显得很陌生,这显然是不太好的。本文将针对常用的语法进行对比,帮助小伙伴们更快的上手不熟悉的另一种框架。也欢迎大家提醒补充其他的常用语法。

语法对比:

定义数据,改变数据

vue

vue里在data里定义数据,在methods里定义方法改变数据

<template>
  <div>
    <div>{{ name }}</div>
    <button @click="changeName">变更名字</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      name: "vue",
    };
  },
  methods: {
    changeName() {
      this.name = "vuejs";
    },
  },
};
</script>

react

react里在函数式组件里使用useState定义数据和定义改变数据的方法

import { useState } from "react";

export default function App() {
  const [name, setName] = useState("react");

  const changeName = () => {
    setName("reactjs");
  };
  return (
    <>
      <div>{name}</div>
      <button onClick={changeName}>变更名字</button>
    </>
  );
}

计算属性(缓存计算结果):

vue

vue中使用computed来实现计算属性的效果

补充:computed(计算属性)可用于快速计算视图(View)中显示的属性,这些计算将被缓存,并且只在需要时更新。计算属性设置的初衷是能够解决复杂的计算。

<template>
  <div>
    <div>
      第一个数字:<input
        type="number"
        v-model.number="num1"
        class="input-computed"
      />
    </div>
    <div>
      第二个数字:<input
        type="number"
        v-model.number="num2"
        class="input-computed"
      />
    </div>
    <div>两个数相加的结果是:{{ result }}</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      num1: 0,
      num2: 0,
    };
  },
  computed: {
    result() {
      return this.num1 + this.num2;
    },
  },
};
</script>
<style>
.input-computed {
  width: 75px;
  height: 25px;
  border: 1px solid #ccc;
}
</style>

react

react里借助useMemo实现计算属性,一个值随着另一个值得改变而改变 

import { useState, useMemo } from "react";
import "./App.css";

export default function App() {
  const [num1, setNum1] = useState(0);
  const [num2, setNum2] = useState(0);

  const changeNum1 = (e) => {
    setNum1(e.target.value);
  };
  const changeNum2 = (e) => {
    setNum2(e.target.value);
  };

  const result = useMemo(() => Number(num1) + Number(num2));
  return (
    <>
      <div>
        第一个数字:
        <input type="number" className="input-computed" onChange={changeNum1} />
      </div>
      <div>
        第二个数字:
        <input type="number" className="input-computed" onChange={changeNum2} />
      </div>
      <div>两个数相加的结果是:{result}</div>
    </>
  );
}

效果图:

显示/隐藏dom元素:

vue

vue里使用v-if或者v-show来切换元素的显示与隐藏

v-if是直接插入dom或者移除dom来作元素的显示和隐藏的

v-show是根据CSS 中的 display 属性来作占位显示和隐藏的

<template>
  <div>
    <div>
      <button @click="checkoutIf">按钮一(v-if)</button></button></button>
      <button @click="checkoutShow">按钮二(v-show)</button>
    </div>
    <div>
        <div v-if="isIf">这是一段v-if控制的文字</div>
        <div v-if="isShow">这是一段v-show控制的文字</div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
        isIf:true,
        isShow:true
    };
  },
  methods:{
    checkoutIf(){
        this.isIf = !this.isIf
    },
    checkoutShow(){
        this.isShow = !this.isShow
    }
  }
};
</script>

react

react里可以根据JavaScript 中的三元表达式和“&”实现元素的显示与隐藏,等同于v-if

也可以使用元素的属性值来做元素的显示与隐藏,等同于v-show

import { useState } from "react";

export default function App() {
  const [isIf, setIsIf] = useState(true);
  const [isShow, setIsShow] = useState(true);

  const checkoutIf = () => {
    setIsIf(!isIf);
  };
  const checkoutShow = () => {
    setIsShow(!isShow);
  };
  return (
    <>
      <div>
        <button onClick={checkoutIf}>切换(类似于v-if)</button>
        <button onClick={checkoutShow}>切换(类似于v-show)</button>
      </div>
      <div>
        <div>{isIf && <div>这段文字是用来做类似于v-if的显示与隐藏的</div>}</div>
        <div style={{ display: isShow ? "block" : "none" }}>
          这段文字是用来做类似于v-show的显示与隐藏的
        </div>
      </div>
    </>
  );
}

循环数据:

vue

在vue中我们使用v-for来循环展示数据

<template>
  <div>
    <h1>三国武将排行</h1>
    <div v-for="item in userData" :key="item.id">
      排名:{{ item.rank }}&nbsp;&nbsp; 武将名:{{ item.name }}
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      userData: [
        { id: 1, rank: 1, name: "吕布" },
        { id: 2, rank: 2, name: "赵云" },
        { id: 3, rank: 3, name: "关羽" },
        { id: 4, rank: 4, name: "典韦" },
      ],
    };
  },
};
</script>

react

在react里,我们可以使用js的map数组方法进行数据的循环展示

import { useState } from "react";

export default function App() {
  const [userList, setUserList] = useState([
    { id: 1, rank: 1, name: "吕布" },
    { id: 2, rank: 2, name: "赵云" },
    { id: 3, rank: 3, name: "关羽" },
    { id: 4, rank: 4, name: "典韦" },
  ]);

  return (
    <>
      {userList.map((item) => {
        return (
          <div>
            排名:{item.rank}&nbsp;&nbsp; 武将名:{item.name}
          </div>
        );
      })}
    </>
  );
}

效果图:

监听:

vue

在vue中我们可以使用watch来实现监听数据变化然后执行回调函数

<template>
  <div>
    <select v-model="selectValue" class="select-watch">
      <option :value="0">全部</option>
      <option :value="1">男</option>
      <option :value="2">女</option>
    </select>
    <div>现在选择的是{{ hintValue }}</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      selectValue: 0,
      hintValue: "所有",
    };
  },
  watch: {
    selectValue() {
      const selectData = new Map([
        [0, "所有"],
        [1, "男性"],
        [2, "女性"],
      ]);
      this.hintValue = selectData.get(this.selectValue);
    },
  },
};
</script>
<style>
.select-watch {
  width: 180px;
  border: 1px solid #000;
}
</style>

react

在React中使用useEffect来完成监听的效果

1.在函数组件中调用 useEffect,并传入一个回调函数作为 effect。这个回调函数将会在组件渲染完成后执行。

2.可选地,传入一个依赖项数组作为第二个参数。依赖项数组表示什么情况下需要重新运行 effect。如果不传入依赖项数组,则 effect 每次组件重新渲染时都会执行;如果传入一个空数组 [],则 effect 只会在组件挂载和卸载时执行;如果传入依赖项数组,effect 将会在依赖项发生变化时执行。

import { useState, useEffect } from "react";
import "./App.css";

export default function App() {
  const [hintValue, setHintValue] = useState("所有的");
  const [selectValue, setSelectValue] = useState(0);

  const changeSelectValue = (e) => {
    setSelectValue(e.target.value);
  };

  useEffect(() => {
    const selectData = new Map([
      [0, "所有"],
      [1, "男性"],
      [2, "女性"],
    ]);
    setHintValue(selectData.get(Number(selectValue)));
  }, [selectValue]);
  return (
    <>
      <select className="select-watch" onChange={changeSelectValue}>
        <option value="0">全部</option>
        <option value="1">男</option>
        <option value="2">女</option>
      </select>
      <div>现在选择的是{hintValue}</div>
    </>
  );
}

效果图:

style样式:

Vue 和 React 都为我们提供了一种不错的动态的给dom元素添加样式的方法。在Vue中,我们通过数组语法绑定多个样式对象,React主要是单个对象的形式

vue

vue添加动态style的语法示例:

<template>
  <div>
    <div :style="[style1, style2]"></div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      style1: {
        width: "300px",
        height: "300px",
      },
      style2: {
        backgroundImage: "linear-gradient(120deg, #fccf31 0%, #f55555 100%)",
        borderRadius: "30px",
      },
    };
  },
};
</script>

react

react添加动态style的语法示例:

export default function App() {
  const style1 = { width: "300px", height: "300px" };
  const style2 = {
    backgroundImage: "linear-gradient(120deg, #fccf31 0%, #f55555 100%)",
    borderRadius: "30px",
  };

  return (
    <>
      <div style={{ ...style1, ...style2 }}></div>
    </>
  );
}

效果图:

Class:

vue

在vue 里我们可以使用动态class完成class的增添

<template>
  <div>
    <span
      v-for="item in 3"
      :key="item"
      class="button-style"
      :class="{ 'button-style-active': item === buttonNum }"
      @click="clickButton(item)"
    >
      {{ item }}
    </span>
  </div>
</template>

<script>
export default {
  data() {
    return {
      buttonNum: 1,
    };
  },
  methods: {
    clickButton(num) {
      this.buttonNum = num;
    },
  },
};
</script>
<style>
.button-style {
  display: inline-block;
  width: 100px;
  height: 20px;
  text-align: center;
  line-height: 20px;
  border: 1px solid #ccc;
}

.button-style-active {
  background-color: skyblue;
  color: #fff;
}
</style>

react

在react里可以借助className去控制class的增添

//App.js
import { useState } from "react";
import "./App.css";

export default function App() {
  const [buttonNum, setButtonNum] = useState(1);

  const clickButton = (num) => {
    setButtonNum(num);
  };
  return (
    <>
      {[1, 2, 3].map((item) => {
        return (
          <span
            className={[
              "button-style",
              buttonNum === item ? "button-style-active" : null,
            ].join(" ")}
            key={item}
            onClick={() => clickButton(item)}
          >
            按钮{item}
          </span>
        );
      })}
    </>
  );
}
//App.css
.button-style {
  display: inline-block;
  width: 100px;
  height: 20px;
  text-align: center;
  line-height: 20px;
  border: 1px solid #ccc;
}

.button-style-active {
  background-color: skyblue;
  color: #fff;
}

效果图:

父组件状态传递到子孙组件中 provide/inject:

vue

在Vue中,我们可以使用“provide/inject”将*状态传递给任何子节点

父组件App.vue

<template>
  <div>
    <Child />
  </div>
</template>

<script>
import Child from "@/Child";
export default {
  components: {
    Child,
  },
  provide: {
    adminInfo: {
      name: "jack",
    },
  },
};
</script>

子组件Child.vue

<template>
  <div>父组件传递过的信息是 {{ adminInfo.name }}</div>
</template>

<script>
export default {
  inject: ["adminInfo"],
};
</script>

react

在react里可以借助 Context 将全局状态共享给任何子节点

主页面App.js

import { useState } from "react";
import { FatherInfoDetail } from "./Father";
import Child from "./Child";

export default function App() {
  return (
    <>
      <FatherInfoDetail.Provider value={{ adminInfo: { name: "jack" } }}>
        <Child></Child>
      </FatherInfoDetail.Provider>
    </>
  );
}

父组件Father.js

import { createContext } from "react";

export const FatherInfoDetail = createContext({
  adminInfo: {
    name: "",
  },
});

子组件Child.js

import { useContext } from "react";
import { FatherInfoDetail } from "./Father";

export default function Child() {
  const { adminInfo } = useContext(FatherInfoDetail);

  return (
    <>
      <div>父组件传过来的内容是 {adminInfo.name}</div>
    </>
  );
}

效果图:

插槽slots:

vue

vue里面通过slot标签实现插槽

主页面App.vue

<template>
  <div>
    <h1>这里是父组件所在的页面</h1>
    <Child>
      <h3>本行文字就是父组件插槽传递到子组件里面的</h3>
    </Child>
  </div>
</template>

<script>
import Child from "@/Child";
export default {
  components: {
    Child,
  },
};
</script>

子组件接收插槽的页面Child.vue

<template>
  <div>
    <slot></slot>
  </div>
</template>

react

React没有插槽的概念,但是可以通过props.children获取组件内部的子元素,类似于默认插槽。

主页面App.js

import Child from "./Child";

export default function App() {
  return (
    <>
      <div>
        <h1>这里是父组件所在的页面</h1>
      </div>
      <Child>
        <h3>本行文字就是父组件插槽传递到子组件里面的</h3>
      </Child>
    </>
  );
}

子组件接收插槽的页面Child.js

export default function Child(props) {
  const { children } = props;

  return (
    <>
      <div>{children}</div>
    </>
  );
}

效果图: