使用Vue Composition API构建电影搜索应用
Vue 3的第一个Alpha版本发布了版本3提供了许多令人兴奋的功能:Vue在新的Composition API后面公开了其反应性系统。如果您还没有听说过,我建议您阅读描述它的RFC。起初,我有点怀疑,但是看着有点相似的React的Hooks API,我决定试一试。
在本文中,我们将使用Composition API构建电影搜索应用程序。我们将不会使用基于对象的组件。我将解释新API的工作原理以及如何构建应用程序。
完成后,我们将看到类似以下内容:
该应用程序将能够通过Open Movie Database API搜索电影并呈现结果。构建此应用程序的原因是,它足够简单,不会去中心化学习新API的注意力,但足够复杂,足以证明它可以工作。
如果您对这些说明不感兴趣,则可以直接进入源代码和最终应用程序。
设置项目
对于本教程,我们将使用Vue CLI,它可以快速生成必要的环境。
npm install -g @vue/cli
vue create movie-search-vue
cd movie-search-vue
npm run serve
我们的应用程序现在在http:// localhost:8080上运行,如下所示:
在这里,您可以看到默认的文件夹结构:
如果不想在本地计算机上安装所有依赖项,也可以在Codesandbox上启动项目。 Codesandbox对于最重要的框架(包括Vue)具有完美的入门项目。
启用新的API
生成的源代码使用带有旧API的Vue 2。要在Vue 2中使用新的API,我们必须安装composition插件。
npm install @vue/composition-api
安装后,我们必须将其添加为插件:
import Vue from 'vue';
import VueCompositionApi from '@vue/composition-api';
Vue.use(VueCompositionApi);
Composition插件是可添加的:您仍然可以按旧方式创建和使用组件,并开始将Composition API用于新组件。
我们将有四个组成部分:
- App.vue:父组件。它将处理API调用并与其他组件通信。
- Header.vue:接收并显示页面标题的基本组件
- Movie.vue:渲染每个电影。电影对象作为属性传递。
- Search.vue:它包含带有输入元素和搜索按钮的表单。提交表单时,它将搜索词赋予应用程序组件。
创建组件
让我们编写第一个组件,标题:
<template>
class="App-header">
{{ title }}
template>
<script>
export default {
name: 'Header',
props: ('title'),
setup() {}
}
script>
零件 props
以相同的方式声明。您可以将父组件中期望的变量命名为数组或对象。这些变量将在模板中可用({{ title }}
)和 setup
方法。
这里的新东西是 setup
方法。它在初始后运行 props
解析度。的 setup
方法可以返回一个对象,并且该对象的属性将合并到模板上下文中:这意味着它们将在模板中可用。这个返回的对象也是放置生命周期回调的地方。我们将在“搜索”组件中看到有关此示例。
让我们看一下Search组件:
<template>
template>
<script>
import { ref } from '@vue/composition-api';
export default {
name: 'Search',
props: ('search'),
setup({ search }, { emit }) {
const movieTitle = ref(search);
return {
movieTitle,
handleSubmit(event) {
event.preventDefault();
emit('search', movieTitle.value);
},
handleChange(event) {
movieTitle.value = event.target.value
}
}
}
};
script>
搜索组件跟踪击键并将输入的值存储在变量中。完成后,按下“提交”按钮,它将发出当前搜索词直至父组件。
的 setup
方法有两个参数。
第一个论点是解决 props
作为命名对象。您可以使用对象分解来访问其属性。该参数是反应性的,这意味着 setup
输入属性更改时,该功能将再次运行。
第二个参数是上下文对象。在这里,您可以找到可供选择的属性的列表 this
在2.x API(attrs
, slots
, parent
, root
, emit
)。
这里的下一个新元素是 ref
功能。的 ref
功能公开了Vue的反应系统。调用时,它将创建具有单个属性的反应性可变变量 value
。的 value
属性将具有传递给的参数值 ref
功能。它是围绕原始值的反应性盘点器。在模板内部,我们不需要引用 value
财产,Vue会为我们拆封它。如果我们传递一个对象,它将具有很强的反应性。
反应性是指当我们修改对象的值时(在本例中 value
属性),Vue会知道该值已更改,因此需要重新渲染连接的模板并重新运行受监视的函数。
它的行为类似于从 data
方法。
data: function() {
return { movieTitle: 'Joker' };
}
粘在一起
下一步是为Header and Search组件App组件引入父组件。它侦听来自Search组件的搜索事件,在搜索词发生更改时运行API,并将找到的电影向下传递到Movie组件列表。
<template>
class="App">
:title="'Composition API'" />
:search="state.search" @search="handleSearch" />
class="App-intro">Sharing a few of our favourite movies
class="movies">
v-for="movie in state.movies" :movie="movie" :key="movie.imdbID" />
template>
<script>
import { reactive, watch } from '@vue/composition-api';
import Header from './Header.vue';
import Search from './Search.vue';
import Movie from './Movie.vue';
const API_KEY = 'a5549d08';
export default {
name: 'app',
components: {
Header, Search, Movie
},
setup() {
const state = reactive({
search: 'Joker',
loading: true,
movies: (),
errorMessage: null
});
watch(() => {
const MOVIE_API_URL = `https://www.omdbapi.com/?s=${state.search}&apikey=${API_KEY}`;
fetch(MOVIE_API_URL)
.then(response => response.json())
.then(jsonResponse => {
state.movies = jsonResponse.Search;
state.loading = false;
});
});
return {
state,
handleSearch(searchTerm) {
state.loading = true;
state.search = searchTerm;
}
};
}
}
script>
我们在这里介绍两个新元素: reactive
和 watch
。
的 reactive
功能相当于Vue 2的 Vue.observable()
。
它使传递的对象具有更强的反应性:接收原始对象并使用代理将其盘点(基于ES2015代理的实现)。关于从中返回的对象 reactive
我们可以直接访问属性,而不是从 ref
我们需要使用的功能 value
属性。如果要在Vue 2.x API中搜索等效项, data
方法将是完全匹配。
缺点之一 reactive
对象是我们无法将其从 setup
方法。
的 watch
功能需要功能。它跟踪内部的反应变量,因为组件为模板执行此操作。当我们修改在传递的函数中使用的反应变量时,给定的函数将再次运行。在我们的示例中,只要搜索字词发生变化,它就会提取与搜索字词匹配的电影。
剩下一个组件,一个组件显示每个电影记录:
<template>
class="movie">
{{ movie.Title }}
width="200" :alt="altText" :src="movie.Poster" />
{{ movie.Year }}
template>
<script>
import { computed } from '@vue/composition-api';
export default {
name: "Movie",
props: ('movie'),
setup({ movie }) {
const altText = computed(() => `The movie titled: ${movie.Title}`);
return { altText };
}
};
script>
电影组件接收要显示的电影,并打印其名称和图像。令人兴奋的部分是 alt
在图像的字段中,我们使用基于其标题的计算文本。
的 computed
函数获得一个getter函数,并将返回的变量盘点为一个反应性变量。返回的变量与从返回的变量具有相同的接口。 ref
功能。区别在于它是只读的。当getter函数中的反应性变量之一发生更改时,getter函数将再次运行。如果 computed
函数返回了一个未盘点的原始值,因此该模板将无法跟踪依赖项更改。
清理组件
目前,App组件内部有很多业务逻辑。它有两件事:处理API调用及其子组件。目的是对每个对象承担一个责任:App组件应仅管理组件,而不必理会API调用。为此,我们必须提取API调用。
import { reactive, watch } from '@vue/composition-api';
const API_KEY = 'a5549d08';
export const useMovieApi = () => {
const state = reactive({
search: 'Joker',
loading: true,
movies: ()
});
watch(() => {
const MOVIE_API_URL = `https://www.omdbapi.com/?s=${state.search}&apikey=${API_KEY}`;
fetch(MOVIE_API_URL)
.then(response => response.json())
.then(jsonResponse => {
state.movies = jsonResponse.Search;
state.loading = false;
});
});
return state;
};
现在,App组件仅收缩以处理与视图相关的操作:
import Header from './Header.vue';
import Search from './Search.vue';
import Movie from './Movie.vue';
import { useMovieApi } from '../hooks/movie-api';
export default {
name: 'app',
components: { Header, Search, Movie },
setup() {
const state = useMovieApi();
return {
state,
handleSearch(searchTerm) {
state.loading = true;
state.search = searchTerm;
}
};
}
}
就是这样;我们使用新的Composition API完成了一个小应用程序。
总结
自从使用Vue CLI生成项目以来,我们已经走了很长一段路。让我们总结一下我们学到的东西。
我们可以将新的Composition API与当前稳定的Vue 2版本一起使用。为此,我们必须使用 @vue/composition-api
插入。该API是可扩展的:我们可以使用新的API和旧的API创建新的组件,现有的组件将继续像以前一样工作。
Vue 3将引入许多不同的功能:
-
setup
:驻留在组件上,并将协调组件的逻辑,在初始后运行props
分辨率,接收props
和上下文作为论点 -
ref
:返回反应型变量,触发更改后重新渲染模板,我们可以通过value
属性。 -
reactive
:返回反应式对象(基于代理),在反应式变量更改时触发模板的重新渲染,我们可以修改其值而无需value
属性 -
computed
:根据getter函数参数返回反应变量,跟踪反应变量变化并重新评估变化 -
watch
:根据提供的功能处理副作用,跟踪反应变量的变化并根据变化重新运行
我希望这个示例使您熟悉新的API,并消除对我的怀疑。