打开网易新闻 查看精彩图片

Vue 3尚未正式发布,但是维护者已经发布了Beta版本,供我们的参与者尝试并提供反馈。

如果你想知道Vue 3的主要功能和主要变化是什么,那么我将在这篇文章中重点介绍一下,告诉你使用Vue 3 beta 9创建一个简单的应用程序。

我将介绍尽可能多的新内容,包括fragmentsteleportComposition API 以及其他一些晦涩的更改。我将尽力解释该功能或更改的原理。

目录

打开网易新闻 查看精彩图片

我们将建立什么

我们将构建一个带有模式窗口功能的简单应用。我之所以选择它,是因为它可以方便地展示Vue 3的许多变化。

这是该应用在打开和关闭状态下的外观,因此你可以在脑海中描绘出我们正在做什么:

打开网易新闻 查看精彩图片

Vue 3安装和setup

与其直接安装Vue 3,不如克隆一个项目 vue-next-webpack-preview,这将为我们提供一个包括Vue 3在内的最小的Webpack设置。

$ git clone https://github.com/vuejs/vue-next-webpack-preview.git vue3-experiment
$ cd vue3-experiment
$ npm i

一旦克隆好了,安装好了NPM模块,我们需要做的就是删除样板文件,然后创建一个新的 main.js 文件,这样我们就可以从头开始创建我们的Vue 3 app了。

$ rm -rf src/*
$ touch src/main.js

现在,我们将运行开发服务器:

$ npm run dev

创建一个新的Vue 3 app

我们启动一个新的Vue应用程序的方式改变了,我们现在需要导入新的 createApp 方法,而不是使用新的 Vue()

我们调用这个方法,传递我们的Vue实例定义对象,并将返回对象分配给一个变量 app

接下来,我们将在 app调用 mount 方法,并传递一个CSS选择器来指示我们的mount元素,就像在Vue 2中使用 $mount 实例方法一样。

// src/main.js
import { createApp } from "vue";
const app = createApp({
// 根实例定义
});
app.mount("#app");

变化的原因

与旧的API一样,我们添加的任何全局配置(plugins,mixins,原型属性等)都将永久更改全局状态。例如:

// src/main.js
// 影响两个实例
Vue.mixin({ ... })
const app1 = new Vue({ el: '#app-1' })
const app2 = new Vue({ el: '#app-2' })

在单元测试中,这确实是一个问题,因为要确保将每个测试都与上一个测试隔离是很棘手的。

在新的API下,调用 createApp 将返回一个新的app实例,该实例不会被应用于其他实例的任何全局配置污染。

添加state属性

我们的模态窗口可以处于两种状态之一——打开或关闭。让我们用一个布尔状态属性 modalOpen 来管理它,我们将给它一个初始值 false

在Vue 2下,我们可以通过在我们的应用实例上创建一个 data 属性并将一个对象分配给该对象来声明 modalOpen 属性,例如:

// src/main.js
const app = createApp({
data: {
modalOpen: false
}
});

不再允许这样做。相反,必须为数据分配一个返回状态对象的工厂函数。

// src/main.js
const app = createApp({
data: () => ({
modalOpen: false
})
});

变化的原因

使用对象而不是工厂函数来存储数据的优点是,首先,它在语法上更简单;其次,你可以在多个根实例之间共享顶级状态,例如:

// src/main.js
const state = {
sharedVal: 0
};
const app1 = new Vue({ state });
const app2 = new Vue({ state });
// 影响两个实例
app1._data.sharedVal = 1;

这种用例很少,可以使用。因为有两种类型的声明是不适合初学者的,所以决定删除这个特性。

在继续之前,我们还添加一个方法来切换 modalOpen 值。这与Vue 2没什么不同。

// src/main.js
const app = createApp({
data: () => ({
modalOpen: true
}),
methods: {
toggleModalState() {
this.modalOpen = !this.modalOpen;
}
}
});

使用一个根组件

如果你现在进入浏览器并检查控制台,则会看到警告“Component is missing render function”,因为我们尚未为根实例定义模板。

Vue 2的最佳实践是为根实例创建一个最小的模板,并创建一个app组件,其中将声明主app标记。

让我们在这里也这样做。

$ touch src/App.vue

现在我们可以获取根实例来渲染该组件。区别在于,对于Vue 2,我们通常会使用render函数来执行此操作:

// src/main.js
import App from "./App.vue";
const app = createApp({
...
render: h => h(App)
});
app.mount("#app");

我们仍然可以做到这一点,但是Vue 3有一个更简单的方法——使 App 成为根组件。为此,我们可以删除根实例定义,而是传递 App 组件。

// src/main.js
import App from "./App.vue";
const app = createApp(App);
app.mount("#app");

这意味着 App 组件不仅由根实例渲染,而且是根实例。

在此过程中,我们通过删除 app 变量来简化语法:

// src/main.js
createApp(App).mount("#app");

现在移至根组件,让我们向该组件重新添加状态和方法:

// src/App.vue