我一直在玩Vue 3,这真的很棒。因此,让我分享一些我学到的东西。根据他们的路线图,他们计划在2020年第二季度(4月,5月,6月,Juni)发布该版本。现在它在Alpha中,但可能很快就会成为Beta版本。
请注意,本文对时间敏感。由于可能发生代码更改,因此会出现更好的最佳实践,并且会提供更好的文档。但是,如果您想抢先一步,这篇文章可以为您提供帮助,撰写于2020-04-08。
立即开始
如果愿意,您可以立即创建一个Vue 3项目。请记住,目前还没有任何官方文档,并且在发布之前可能会发生代码更改。我已经创建了一个GitHub存储库,其中包含一个您可以使用的项目,并查看一些示例代码。自述文件包含有关如何设置Vue 3项目的信息,以及使您保持最新状态的资源以及有关Vue 3的文章,视频和播客。
改进之处
Vue 3的最大变化是它完全在后台进行了重写。对于我们的开发人员而言,这将几乎相同。否则结果是更好的产品。Vue已经快了,但是现在它具有巨大的性能和内存改进,在静态树吊起和树摇(消除死代码)方面更胜一筹。
他们还用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 */ }
}
}
现在到令人兴奋的部分。让我们写一些设置代码。ref
并reactive
用于存储反应变量。
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公司的概念几乎是一样的,你的数据会ref
或reactive
和我们习惯watch
,computed
以及生命周期挂钩。
分段
您是否注意到每个模板只需要一个孩子?这很烦人,因为它会污染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成为目前最好的框架之一。