我在Vue中比在React中更喜欢的事情

原文信息: 查看原文查看原文

Things that I like better in Vue than in React

- Jaydev Mahadevan

我已经使用React很长时间了,所以当有人说“嘿,你应该尝试一种不同的前端框架”时,我的回答总是“哼,但我已经如此高效了=P”。然而,Vue已经有了足够多的酷炫发展,让我想要尝试一下。结果我愉快地惊讶了!Vue有一堆很棒的功能,让我作为React开发者感到羡慕。让我们深入探讨一些Vue的模式,以及它们与React方法的对比!

1. 安装过程愉快

Vue的开箱即用体验远远领先——npm create vue@latest感觉像是一个“设计好的体验”,而npm create-react-app只是一个普通的NPM命令。我更喜欢像在Vue中一样交互地选择要安装的包,而不是CRA的流程。

此外,Vue安装的包提供了比CRA更完整的开发体验,涵盖了诸如路由、状态管理和代码格式化等领域。

Vue的安装过程令人愉快地互动

Vue的安装过程令人愉快地互动。

另外,我们能不能谈谈当你为新项目打开localhost时,起始页面有多么有帮助?

接下来的所有Vue示例都使用Vue 3的Composition API,它与函数式React最相似。

2. 直观的响应式系统

与React的状态管理相比,Vue的响应式系统感觉更直观,而且没有那么多样板代码。Vue会自动处理依赖跟踪和更新,使状态管理变得简单。

Vue示例

<template>
  <p>{{ count }}</p>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';

const count = ref(0);

onMounted(() => {
  setInterval(() => {
    count.value++;
  }, 1000);
});
</script>

React等效

为了实现类似的响应式效果,React需要更多的样板代码,特别是对于依赖于先前状态值的效果和状态更新。还有谁每次想使用它们时都不得不查阅useEffectuseMemouseCallback之间微妙的区别呢?🙋🏾‍♂️

function Counter() {
  const [count, setCount] = React.useState(0);

  React.useEffect(() => {
    const interval = setInterval(() => {
      setCount(currentCount => currentCount + 1);
    }, 1000);
    return () => clearInterval(interval);
  }, []);

  return <p>{count}</p>;
}

3. 单文件组件

单文件组件(SFCs)肯定是一种爱恨交加的东西,但我认为它们很棒,尤其是对于小型组件。在我看来,将HTML、JavaScript和CSS封装在一个文件中有助于更好地组织和阅读代码。

Vue单文件组件

<script setup lang="ts">
import { defineProps } from 'vue'

defineProps({
  message: String
})
</script>

<template>
  <div class="message-box">
    <p>{{ message }}</p>
  </div>
</template>

<style scoped>
.message-box {
  padding: 20px;
  border: 1px solid #eee;
}
</style>

React等效

在React中,实现相同的封装通常涉及将不同的关注点分开到不同的文件中,或者采用CSS-in-JS库,这可能会增加复杂性。

function MessageBox({ message }) {
  return (
    <div className="message-box">
      <p>{message}</p>
    </div>
  );
}
// CSS通常单独管理,或通过CSS-in-JS解决方案管理

4. 条件渲染

Vue的指令系统(v-ifv-for等)提供了比React更可读的条件渲染方法。随着您的if/else语句变得更加复杂,这种优势会变得更加明显。

带有指令的Vue示例

<script setup lang="ts">
import { ref } from 'vue';

const isSubscribed = ref(false);
const isSubscriptionExpiring = ref(true);

// 上面的属性会动态更新...
</script>

<template>
  <div>
    <p v-if="!isSubscribed">请订阅以访问高级功能。</p>
    <p v-else-if="isSubscriptionExpiring">您的订阅即将到期。请续订以继续享受高级功能。</p>
    <p v-else>欢迎回来,尊贵的高级用户!</p>
  </div>
</template>

React等效

function SubscriptionStatus() {
  const isSubscribed = false;
  const isSubscriptionExpiring = true;

  // 上面的属性会动态更新...

  return (
    <div>
      {isSubscribed ? (
        isSubscriptionExpiring ? (
          <p>您的订阅即将到期。请续订以继续享受高级功能。</p>
        ) : (
          <p

>欢迎回来,尊贵的高级用户!</p>
        )
      ) : (
        <p>请订阅以访问高级功能。</p>
      )}
    </div>
  );
}

当然,您可以将基于JSX的逻辑移动到一个JS函数中,但在Vue中,初始过程更容易理解。

5. 计算属性

Vue的计算属性简化了依赖于响应式数据的复杂逻辑处理。它们会自动缓存,并且仅在其依赖项更改时重新计算,从而优化性能。

Vue示例

<script setup lang="ts">
import { computed, ref } from 'vue'

const price = ref(10)
const quantity = ref(3)
const totalPrice = computed(() => price.value * quantity.value)
</script>

<template>
  <p>总价:{{ totalPrice }}</p>
</template>

React等效

在React中,类似的功能需要使用useMemo hook,这会给组件逻辑增加复杂性和冗余性。

function TotalPrice() {
  const [price, setPrice] = React.useState(10);
  const [quantity, setQuantity] = React.useState(3);

  const totalPrice = React.useMemo(() => {
    return price * quantity;
  }, [price, quantity]);

  return <p>总价:{totalPrice}</p>;
}

6. 流畅的状态管理

Pinia是Vue推荐的状态管理解决方案之一。由于与Vue的紧密集成和周到的API,Pinia感觉比React + Redux中的等效代码更流畅。

使用Pinia的Vue

// stores/counter.js

import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => {
    return { count: 0 }
  },
  actions: {
    increment() {
      this.count++
    },
  },
})
// components/MyCounter.vue

<script setup>
import { useCounterStore } from '@/stores/counter'

const counter = useCounterStore()
</script>

<template>
  <button @click="counter.increment">递增</button>
  <div>当前计数:{{ counter.count }}</div>
</template>

使用Redux的React

// counterSlice.js

import { createSlice } from '@reduxjs/toolkit'

export const counterSlice = createSlice({
  name: 'counter',
  initialState: {
    value: 0,
  },
  reducers: {
    increment: (state) => {
      state.value += 1
    }
  },
})

export const { increment } = counterSlice.actions

export default counterSlice.reducer
// Counter.js

import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { decrement, increment } from './counterSlice'

export function Counter() {
  const count = useSelector((state) => state.counter.value)
  const dispatch = useDispatch()

  return (
    <button onClick={() => dispatch(increment())}>
      递增
    </button>
    <span>{count}</span>
  )
}

总结

我初次学习Vue的经历拓宽了我对良好设计模式和良好构建API的视野。很明显,Vue从一开始就优先考虑了开发者体验和应用性能。我认为这里最重要的教训是,无论您的技能水平如何,或者您已经掌握了哪些工具,您都可以通过尝试新事物来学习!

分享于 2024-04-22

访问量 110

预览图片