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>
但为什么?
如果这个例子没有清楚地说明引入这一变化的原因,或者感觉它在可用性方面有所退步,我理解。我最初也有同样的反应,而且我花了一段时间才弄清楚为什么需要进行这一更改。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>`
}
如果我们将其与在 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>
以及更多
封装并不是这些变化有用的唯一原因,因此这里还有另外两个原因可以说明为什么这种变化可能是 VueJS 所需要的。
VueJS 中当前基于选项的 API 存在一个问题,即它无法正确支持 TypeScript 类型推断。拟议的更改解决了这个问题,并实现了完整的类型支持,TS 代码看起来几乎与 JS 代码相同,这为已经非常实用的功能锦上添花。
VueJS 因其极小的打包体积而备受青睐,而这一变化进一步压缩了打包体积。由于函数和变量名称可以通过标准压缩方法缩短(而对象/类的方法和属性则无法缩短),因此代码压缩效果更佳。
有什么想法吗?
大家最初对 RFC 的反应褒贬不一,一些用户将这些变化与 React 进行比较,并认为 VueJS 正在失去优势。我最初的反应也远非正面,但随着我深入研究,我发现 VueJS 的封装优势开始盖过现有 API 的简洁性。
您的想法是什么?
文章来源:https://dev.to/stefandorresteijn/vuejs-is-dead-long-live-vuejs-1g7f