VueJS 已死,VueJS 万岁!

2025-05-27

VueJS 已死,VueJS 万岁!

大约两周前,随着VueJS 3 的“征求意见稿”文档发布,尤雨溪介绍了基于函数式的 VueJS API,并在 VueJS 社区掀起了一股热潮。这些新想法目前仍处于“征求意见稿”阶段,因此远未最终确定。但由于 RFC 引入了如此重大的变化,我简要总结了您需要了解的内容。

注意:所有这些信息以及更多信息都在 RFC 中,所以我建议您阅读它。

设置

VueJS 3 抛弃了我们钟爱的基于选项的 API,引入了setup()函数,所有神奇的功能都将在此实现。该函数负责设置组件的逻辑,并返回暴露给模板的数据。即使在 VueJS 3 中,基于选项的 API 仍将继续有效,但这个新的基于函数的 API 将成为新的标准。

对于我们在 VueJS 中习惯使用的所有功能,例如响应式数据、计算值、方法和观察器,我们都将其import转化为函数vue并在setup()函数中使用。以下是 RFC 中的一个基本示例:

<template>
  <div>
    <span>count is {{ count }}</span>
    <span>plusOne is {{ plusOne }}</span>
    <button @click="increment">count++</button>
  </div>
</template>

<script>
import { value, computed, watch, onMounted } from 'vue'

export default {
  setup() {
    // reactive state
    const count = value(0)
    // computed state
    const plusOne = computed(() => count.value + 1)
    // method
    const increment = () => { count.value++ }
    // watch
    watch(() => count.value * 2, val => {
      console.log(`count * 2 is ${val}`)
    })
    // lifecycle
    onMounted(() => {
      console.log(`mounted`)
    })
    // expose bindings on render context
    return {
      count,
      plusOne,
      increment
    }
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

但为什么?

如果这个例子没有清楚地说明引入这一变化的原因,或者感觉它在可用性方面有所退步,我理解。我最初也有同样的反应,而且我花了一段时间才弄清楚为什么需要进行这一更改。v2.x API 广受欢迎,并且经常是人们从 ReactJS 或 AngularJS 等其他框架迁移到 VueJS 的原因,因此如此剧烈的改变似乎是一个奇怪的想法。

封装为王

创建组件 API 的部分原因是为了更轻松地在整个应用程序中复用代码。虽然 VueJS 高度模块化并使用组件,但当前基于选项的 API 无法轻松提取与单个功能或数据相关的功能。您需要分别定义数据(/状态)、计算值和方法,而它们可能彼此关联。当组件数量增加且方法处理不同的数据时,这会造成混乱。

这就是新的基于函数的 API 的用武之地。它允许你提取与某段逻辑相关的所有代码,并将其组合成所谓的“组合函数”,该函数返回响应式状态。RFC 中给出了一个示例,它使用其中一个组合函数来提取监听鼠标位置的逻辑

function useMouse() {
  const x = value(0)
  const y = value(0)
  const update = e => {
    x.value = e.pageX
    y.value = e.pageY
  }
  onMounted(() => {
    window.addEventListener('mousemove', update)
  })
  onUnmounted(() => {
    window.removeEventListener('mousemove', update)
  })
  return { x, y }
}

// in consuming component
const Component = {
  setup() {
    const { x, y } = useMouse()
    return { x, y }
  },
  template: `<div>{{ x }} {{ y }}</div>`
}
Enter fullscreen mode Exit fullscreen mode

如果我们将其与在 v2.x API 中编写此功能的方式进行比较,我们可以看到与使用鼠标位置相关的功能遍布各处,而在 v3.x API 中,它很好地分组在一个函数中:

<template>
    <div>
        {{ x }} {{ y }}
    </div>
</template>

<script>
export default {
  data() {
    return {
      x: 0,
      y: 0,
    };
  },
  mounted() {
    window.addEventListener('mousemove', this.update);
  },
  beforeDestroy() {
    window.removeEventListener('mousemove', this.update);
  },
  methods: {
    update(e) {
      this.x = e.pageX;
      this.y = e.pageY;
    },
  },
};
</script>

Enter fullscreen mode Exit fullscreen mode

以及更多

封装并不是这些变化有用的唯一原因,因此这里还有另外两个原因可以说明为什么这种变化可能是 VueJS 所需要的。

VueJS 中当前基于选项的 API 存在一个问题,即它无法正确支持 TypeScript 类型推断。拟议的更改解决了这个问题,并实现了完整的类型支持,TS 代码看起来几乎与 JS 代码相同,这为已经非常实用的功能锦上添花。

VueJS 因其极小的打包体积而备受青睐,而这一变化进一步压缩了打包体积。由于函数和变量名称可以通过标准压缩方法缩短(而对象/类的方法和属性则无法缩短),因此代码压缩效果更佳。

有什么想法吗?

大家最初对 RFC 的反应褒贬不一,一些用户将这些变化与 React 进行比较,并认为 VueJS 正在失去优势。我最初的反应也远非正面,但随着我深入研究,我发现 VueJS 的封装优势开始盖过现有 API 的简洁性。

您的想法是什么?

文章来源:https://dev.to/stefandorresteijn/vuejs-is-dead-long-live-vuejs-1g7f
PREV
成为初级开发人员的感觉如何
NEXT
PWA 是我们的未来