Vue 3 即将到来!

2025-06-05

Vue 3 即将到来!

我一直在尝试 Vue 3,它真的很酷。所以,让我分享一些我的心得。根据他们的路线图,他们计划在 2020 年第二季度末(4 月、5 月、6 月)发布。目前 Vue 3 处于 Alpha 测试阶段,但可能很快就会发布 Beta 版本。

请注意,本文具有时效性。随着代码的不断更改,可能会出现更好的最佳实践,并提供更完善的文档。但如果您想抢先一步,这篇撰写于 2020-04-08 的文章或许能帮到您。

立即开始

如果您愿意,现在就可以创建一个 Vue 3 项目。但请注意,目前尚无官方文档,在正式发布之前,代码可能会有所更改。我创建了一个GitHub 仓库,其中包含一个项目,您可以试用并查看一些示例代码。自述文件包含有关如何设置 Vue 3 项目的信息,以及一些让您随时了解最新情况的资源,以及有关 Vue 3 的文章、视频和播客。

改进

Vue 3 最大的变化在于其底层完全重写。对于我们开发者来说,这意味着一切基本相同。除此之外,最终结果会是一个更好的产品。Vue 本来就很快,但现在它在性能和内存方面都有了巨大的提升,并且在静态树提升和 tree shake(死代码消除)方面也做得更好了。

快速地

他们还用 TypeScript 编写了 Vue 3,这使得 Vue 团队能够更轻松地维护项目。同时,它也给我们开发者带来了一些好处,即使你使用的是 JavaScript 或 TypeScript,也能获得更好的 IntelliSense 和 TypeAhead 功能。

他们对每项变更都使用RFC(征求意见稿),以便让社区参与正在制定的决策。

变化

组合 API

现在,组件的 JavaScript 部分新增了一种可选的编写方式。我们将目前使用的方式称为 Options API,其中包含一个包含数据、方法、计算、监视等属性的对象。这在 Vue 3 中仍然有效。组合 API 只是一种附加的方式。我会尽量简短,但如果您想获得更清晰的解释,可以访问此处

让我们看一下组件对象的骨架。

// Import the API's you are using for the component
import { ref, reactive, computed } from 'vue';

export default {
  // the setup method where logic happens
  setup(){
    return { /* return what logic is exposed to the template */ }
  }
}
Enter fullscreen mode Exit fullscreen mode

现在到了激动人心的部分。让我们编写一些设置代码。refreactive用于存储反应变量。

setup(){
  //Let's have two different reactive values
  const counter = ref(0);
  const state = reactive({
    count: 0
  });

  //Update the values
  counter.value++;
  state.count++;

  return { counter, state }
}
Enter fullscreen mode Exit fullscreen mode

正如你所见,ref 和 react 的功能几乎相同。refref主要用于原始类型和数组。while 用来reactive保存对象。使用哪种方法取决于你,但我认为随着时间的推移,关于在何处使用哪种方法的最佳实践将会逐渐出现。

我们已经熟悉了计算属性、方法和监视。原理是一样的,只是写法略有不同。

我们还有watchEffect与 watch 非常相似的,但是您不必告诉它要监听哪些值,它将在函数内部使用的每个依赖项上运行。

setup(){
  const counter = ref(0);

  const double = computed(() => counter.value * 2);

  const addToCounter = toAdd => counter.value += toAdd;

  watch(counter, () => console.log('counter updated'));

  return { double, addToCounter }
}
Enter fullscreen mode Exit fullscreen mode

我在这里使用了箭头函数,但它也可以是普通函数。代码不必位于 setup 方法内部,它可以位于 Vue 对象之外,也可以位于其他文件中。重要的是 setup 方法会返回方法和响应值。

这让我开始思考,这能不能用来创建一个非常简单的全局响应状态?答案是肯定的。

globalShoppingCart.js

import { reactive, computed } from 'vue';

const shoppingCart = reactive({
  items: [],
  totalPrice: computed(() => shoppingCart.items.reduce((acc, item) => acc + item.price, 0))
});

const addItem = item => shoppingCart.items.push(item);

export { addItem, shoppingCart }
Enter fullscreen mode Exit fullscreen mode

item.vue

<template>
    <h1>Ball</h1>
    <button @click="addItem({name: 'ball', price: 99})">Add to Cart</button>
</template>

<script>
import { addItem } from '@/globalShoppingCart'

export default {
    setup(){
        return { addItem }
    }
}
</script>
Enter fullscreen mode Exit fullscreen mode

cart.vue

<template>
    <h1>Cart</h1>
    <span>Items: {{ shoppingCart.items.length }}</span>
    <span>Price: {{ shoppingCart.totalPrice }}</span>
</template>

<script>
import { shoppingCart } from '@/globalShoppingCart'

export default {
    setup(){
        return { shoppingCart }
    }
}
</script>
Enter fullscreen mode Exit fullscreen mode

太棒了!我们不用再处理那么多 props 和 emits 了。

它也非常适合代码复用。让我们将“点赞”和“超级点赞”功能放在一个独立的 JavaScript 文件中,但每个使用该文件的用户都会拥有各自的状态。

likes.js:

import { ref } from "vue"

const getLikes = () => {
    const likes = ref(0)
    const superLike = () => likes.value += 1000;
    return { likes, superLike }
}

export { getLikes }
Enter fullscreen mode Exit fullscreen mode

hearts.vue

<template>
    <div>
        {{likes}}🧡
        <button @click="likes++">Love</button>
        <button @click="superLike">💕💕💕</button>
    </div>
</template>

<script>
import { getLikes } from '@/likesOwn';
export default {
    setup(){
        return { ...getLikes() }
    }
}
</script>
Enter fullscreen mode Exit fullscreen mode

回到 Composition API 的最后一部分,生命周期钩子。它和生命周期钩子基本相同,但你可以在 setup 方法中使用它们。你也可以使用多个生命周期钩子。

setup(){
  onMounted(() => console.log('DOM is ready'));
  onMounted(() => console.log('mounted called again'));
}
Enter fullscreen mode Exit fullscreen mode

有一点,根本没有 onCreated 之类的方法!这段代码应该放在 setup 方法里。因为 setup 方法会在组件启动时运行一次。所以,获取数据之类的操作最好放在 setup 方法里。

Composition API 是可选的,它可以与 Options API 在同一组件中使用。Composition API 有助于保持相关逻辑彼此接近,将设置代码移至其自己的文件中,并实现代码复用。Vue 的概念与之基本相同,您的数据将是ref或 ,reactive以及我们习惯使用的watchcomputed和生命周期钩子。

分段

你有没有注意到每个模板只需要一个子元素?这很烦人,因为它会污染 DOM,并增加代码量和缩进。

不再

<template>
  <h1>This is</h1>
  <h2>completely</h2>
  <h3>fine! :)</h3>
</template>
Enter fullscreen mode Exit fullscreen mode

悬念

Suspense 是 Vue 3 中引入的新功能。当您的组件尚未准备好时,它可以让您轻松地显示加载微调器。

让我们有一个异步设置方法来获取一些数据。

async setup(){
  const response = await fetch('someurl');
  const data = await response.json();
  return { data }
}
Enter fullscreen mode Exit fullscreen mode

现在,这可能需要一些时间。你的组件什么时候才能准备好?只需让你的父组件像这样使用 Suspense 即可。

<template>
  <Suspense>
    <template #default>
      <MyChildComponenta/> //the component with async setup
    </template>
    <template #fallback>
      <div>Loading...</div>
    </template>
  </Suspense>
</template>
Enter fullscreen mode Exit fullscreen mode

传送

请注意,Teleport 直到最近才被命名为 Portal,因此如果您正在阅读其他文章,它们可能已经过时了。

Teleport 使我们能够将一些 HTML 代码传送到应用程序中组件之外的另一个位置。

在您的应用程序中的某个地方,您有一个带有 id 的元素:

<div id="arrival-spot"></div>
Enter fullscreen mode Exit fullscreen mode

现在您可以让另一个组件定位该元素。

<template>
  <div>
    <span>I'm still in my component</span>
    <Teleport to="#arrival-spot">
      <span>Woho, I can teleport \o/ </span>
    </Teleport>
  </div>
</template>
Enter fullscreen mode Exit fullscreen mode

多个 v-model

现在,当您想要绑定不同的值时,您可以在自定义组件上拥有多个 v-model。

<HumanStats v-model:age="human.age" v-model:height="human.height"/>
Enter fullscreen mode Exit fullscreen mode

过渡

只是过渡效果的命名略有变化。我发现 v-enter-active、v-enter 和 v-enter-to 有点令人困惑。在 Vue 3 中,v-enter 重命名为v-enter-from,v-leave 重命名为v-leave-from。现在,过渡效果更加清晰了,一个类表示活动状态,一个类表示过渡起始位置,一个类表示过渡目标位置。

已移除过滤器

<!-- before -->
{{ date | format }}

<!-- after -->
{{ format(date) }}
Enter fullscreen mode Exit fullscreen mode

在 Vue 2 中,我们曾经使用过滤方法来处理显示值。现在,我们移除了过滤方法,以确保括号内的内容均为有效的 JavaScript。我们应当使用计算属性或方法,这完全没问题,只是另一种编写代码的方式而已。

应用程序配置

在 Vue 2 中,我们有一个全局Vue对象用于配置。在 Vue 3 中,每个配置的作用域都限定在用 定义的某个 Vue 应用程序内createApp

main.js

import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)

app.use(/* ... */)
app.mixin(/* ... */)
app.component(/* ... */)
app.directive(/* ... */)

app.mount('#app')
Enter fullscreen mode Exit fullscreen mode

结论

我对 Vue 3 感到非常兴奋。我认为这将使 Vue 成为最好的框架之一。

文章来源:https://dev.to/gautemeekolsen/vue-3-is-coming-3icj
PREV
为什么我更喜欢 Vue 而不是 React 结论
NEXT
表达:req.params、req.query 和 req.body