WEB程序员笔记

一个前端开发工程师的个人博客

Vue 3来了

我一直在玩Vue 3,这真的很棒。因此,让我分享一些我学到的东西。根据他们的路线图,他们计划在2020年第二季度(4月,5月,6月,Juni)发布该版本。现在它在Alpha中,但可能很快就会成为Beta版本。

请注意,本文对时间敏感。由于可能发生代码更改,因此会出现更好的最佳实践,并且会提供更好的文档。但是,如果您想抢先一步,这篇文章可以为您提供帮助,撰写于2020-04-08。

立即开始

如果愿意,您可以立即创建一个Vue 3项目。请记住,目前还没有任何官方文档,并且在发布之前可能会发生代码更改。我已经创建了一个GitHub存储库,其中包含一个您可以使用的项目,并查看一些示例代码。自述文件包含有关如何设置Vue 3项目的信息,以及使您保持最新状态的资源以及有关Vue 3的文章,视频和播客。

改进之处

Vue 3的最大变化是它完全在后台进行了重写。对于我们的开发人员而言,这将几乎相同。否则结果是更好的产品。Vue已经快了,但是现在它具有巨大的性能和内存改进,在静态树吊起和树摇(消除死代码)方面更胜一筹。

《Vue 3来了》

他们还用TypeScript编写了Vue 3,这使该项目对Vue团队更具可维护性。但这对我们开发人员也有一些好处,即使您使用的是JavaScript或TypeScript,也将获得更好的IntelliSense和提前输入。

他们对每个更改都使用RFC征求意见稿),以使社区参与正在做出的决策。

变化

合成API

有一种新的可选方式来编写组件的JavaScript部分。他们将我们今天的操作方式命名为Options API,在这里您拥有一个具有数据,方法,计算值,监视等属性的对象。这在Vue 3中仍然有效。composition 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 */ }
  }
}

现在到令人兴奋的部分。让我们写一些设置代码。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 }
}

如您所见,ref和react可以做的差不多。ref主要用于基本类型和数组。同时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 }
}

我在这里使用箭头功能,但它可能是正常功能。而且代码不必位于setup方法之内,可以位于Vue对象之外,也可以位于另一个文件中,重要的是,设置返回方法和反应值。

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

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 }

item.view

<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>

查看购物车

<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>

这很酷!我们不必再处理那么多道具和发射了。

它对于重用代码也非常有用。让我们在自己的JavaScript文件中拥有“喜欢”和“超级喜欢”功能,但是每个使用该文件的人都将拥有自己的状态。

likes.js:

import { ref } from "vue"

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

export { getLikes }

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>

生命周期挂钩是组成API的最后一部分。几乎相同,但是您可以将它们包含在setup方法中。您也可以有多个相同的对象。

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

一件事,不存在诸如onCreated之类的东西!此代码应位于setup方法中。因为设置方法将在组件的最开始运行一次。因此,获取数据等是设置方法内部的好地方。

composition API是可选的,可以与同一组件中的options API一起使用。合成API将有助于使相关的逻辑彼此靠近,将设置代码移动到其自己的文件中并重新使用代码。Vue公司的概念几乎是一样的,你的数据会refreactive和我们习惯watchcomputed以及生命周期挂钩。

分段

您是否注意到每个模板只需要一个孩子?这很烦人,因为它会污染DOM并为您提供更多代码和缩进。

不再

<template>
  <h1>This is</h1>
  <h2>completely</h2>
  <h3>fine! :)</h3>
</template>

悬念

Suspense是Vue 3中引入的新功能。当组件尚未准备就绪时,它为您提供了一种简单的方法来显示例如加载微调器。

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

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

现在,这可能需要一些时间。什么时候准备好组件?只是让您的父组件像这样使用悬念。

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

传送

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

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

在应用程序中的某个位置,您具有一个具有ID的元素:

<div id="arrival-spot"></div>

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

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

多个v模型

现在,当您想绑定不同的值时,可以在自定义组件上具有多个v模型。

<HumanStats v-model:age="human.age" v-model:height="human.height"/>

过渡

过渡只不过是一个小的命名更改。我发现v-enter-active,v-enter,v-enter有点混乱。在Vue 3中,将v-enter重命名为,v-enter-from并将v-leave保留为v-leave-from。现在,转换变得更有意义了,一个用于激活状态的类,一个用于其转换的类以及一个用于转换的类。

过滤条件已删除

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

<!-- after -->
{{ format(date) }}

在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')

结论

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

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注