如何利用插槽、混合体和合成 API 使您的 Vue.js 应用程序保持 DRY

作者选择了 开源精神疾病以作为 写给捐赠计划的一部分获得捐赠。

介绍

DRY是一个编程策略,代表不要重复自己。它通过模块化架构鼓励代码可重复使用,代码被重复使用,而不是重复使用。

Vue.js包括多种策略来模块化和重复使用代码的片段。 在本教程中,您将通过制作 Vue.js 应用程序 DRY 样本来尝试这些策略。本教程将介绍如何将您的模板脚本 DRY 保持在您的 组件内。您将使用布局组件来建立一个 HTML 结构,您可以通过插座将内容放入。然后,您将使用 mixins,这些是包含数据方法计算属性的 JavaScript 文件,这些属性与现有组件选项相结合。最后,您将使用 Vue 3 中引入的新构成 API。构成 API 是构成组件的另一种方式,并促进组件属

前提条件

要在 macOS 或 Ubuntu 20.04 上安装此功能,请遵循 如何在 macOS 上安装 Node.js 并创建本地开发环境如何在 macOS 上安装 Node.js 并创建本地开发环境或 [如何在 Ubuntu 20.04 上安装 Node.js 并使用 NodeSource PPA 使用 Apt 安装 Node.js 版本 2 选项]的步骤。

步骤 1 – 设置示例应用程序

为了说明您如何创建可扩展和 DRY Vue.js 代码,您将首先设置一个示例应用程序. 此示例应用程序将是一个主要 / 详细的应用程序,显示机场地图列表。

首先,您需要创建一个新的 Vue.js 应用程序,然后在终端中运行以下命令:

1vue create favorite-airports

当被提示时,选择手动选择功能。下列选项是选择视图版本,Babel路由器。一旦选择,按下RETURN键,然后继续如下填写提示:

1[secondary_label Output]
2Vue CLI v4.5.15
3? Please pick a preset: Manually select features
4? Check the features needed for your project: Choose Vue version, Babel, Router
5? Choose a version of Vue.js that you want to start the project with 3.x
6? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
7? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files

一旦创建了最喜欢的机场项目,打开您的终端窗口和cd(更改目录)到最喜欢的机场根文件夹。

1mkdir src/data

在此文件夹中,创建一个名为src/data/airports.js的新JavaScript文件,并在您所选择的文本编辑器中打开它。

 1[label favorite-airports/src/data/airports.js]
 2export default [
 3  {
 4    name: 'Cincinnati/Northern Kentucky International Airport',
 5    abbreviation: 'CVG',
 6    city: 'Hebron',
 7    state: 'KY',
 8    destinations: {
 9      passenger: [ 'Toronto', 'Seattle/Tacoma', 'Austin', 'Charleston', 'Denver', 'Fort Lauderdale', 'Jacksonville', 'Las Vegas', 'Los Angeles', 'Baltimore', 'Chicago', 'Detroit', 'Dallas', 'Tampa' ],
10      cargo: [ 'Anchorage', 'Baltimore', ' Chicago' , 'Indianapolis', 'Phoenix', 'San Francisco', 'Seattle', 'Louisville', 'Memphis' ]
11    }
12  },
13  {
14    name: 'Seattle-Tacoma International Airport',
15    abbreviation: 'SEA',
16    city: 'Seattle',
17    state: 'WA',
18    destinations: {
19      passenger: [ 'Dublin', 'Mexico City', 'Vancouver', 'Albuquerque', 'Atlanta', 'Frankfurt', 'Amsterdam', 'Salt Lake City', 'Tokyo', 'Honolulu' ],
20      cargo: [ 'Spokane', 'Chicago', 'Dallas', ' Shanghai', 'Cincinnati', 'Luxenbourg', 'Anchorage', 'Juneau', 'Calgary', 'Ontario' ]
21    }
22  },
23  {
24    name: 'Minneapolis-Saint Paul International Airport',
25    abbreviation: 'MSP',
26    city: 'Bloomington',
27    state: 'MN',
28    destinations: {
29      passenger: [ 'Dublin', 'Paris', 'Punta Cana', 'Winnipeg', 'Tokyo', 'Denver', 'Tulsa', 'Washington DC', 'Orlando', 'Mexico City' ],
30      cargo: [ 'Cincinnati', 'Omaha', 'Winnipeg', 'Chicago', 'St. Louis', 'Portland', 'Philadelphia', 'Milwaukee', 'Ontario' ]
31    }
32  }
33]

这是由美国几个机场组成的 objectsarray 在本应用程序的主要视图中,您将通过这些数据重复,以生成由名称缩写城市属性组成的卡片。

保存数据/airports.js并返回终端。

完成此步骤后,创建一个名为AirportCard.vue的单个文件组件(SFC)。这个文件将生活在您的项目的组件目录中,并包含机场卡的所有风格和逻辑。

 1[label favorite-airports/src/components/AirportCard.vue]
 2<template>
 3  <div class="airport">
 4    <p>{{ airport.abbreviation }}</p>
 5    <p>{{ airport.name }}</p>
 6    <p>{{ airport.city }}, {{ airport.state }}</p>
 7  </div>
 8</template>
 9
10<script>
11export default {
12  props: {
13    airport: {
14      type: Object,
15      required: true
16    }
17  }
18}
19</script>
20
21<style scoped>
22.airport {
23  border: 3px solid;
24  border-radius: .5rem;
25  padding: 1rem;
26  margin-bottom: 1rem;
27}
28
29.airport p:first-child {
30  font-weight: bold;
31  font-size: 2.5rem;
32  margin: 1rem 0;
33}
34
35.airport p:last-child {
36  font-style: italic;
37  font-size: .8rem;
38}
39</style>

AirportCard.vue组件中,包装器<div>包含了机场的类别。本CSS通过添加边界来为每个机场提供卡片的外观,为生成的HTML添加了一些风格。:第一个孩子:最后一个孩子是应用于<div>元素中的HTML中第一个和最后一个<p>标签的不同风格选择器。

保存和退出文件。

在包装此设置之前,请将现有view/Home.vue组件代码替换为以下:

 1[label favorite-airports/src/views/Home.vue]
 2<template>
 3  <div class="wrapper">
 4    <div v-for="airport in airports" :key="airport.abbreviation">
 5      <airport-card :airport="airport" />
 6    </div>
 7  </div>
 8</template>
 9
10<script>
11import allAirports from '@/data/airports.js'
12import AirportCard from '@/components/AirportCard.vue'
13
14export default {
15  components: {
16    AirportCard
17  },
18  data() {
19    return {
20      airports: allAirports
21    }
22  }
23}
24</script>
25
26<style>
27#app {
28  font-family: Avenir, Helvetica, Arial, sans-serif;
29  -webkit-font-smoothing: antialiased;
30  -moz-osx-font-smoothing: grayscale;
31  text-align: center;
32  color: #2c3e50;
33  margin-top: 60px;
34}
35
36.wrapper {
37  display: grid;
38  grid-template-columns: 1fr 1fr 1fr;
39  grid-column-gap: 1rem;
40  max-width: 960px;
41  margin: 0 auto;
42}
43
44p,
45h3 {
46  grid-column: span 3;
47}
48</style>

此代码包含一个 v-for 循环,它通过 airports.js 数据进行迭代,并通过 prop :airport 传输的机场数据,返回一系列 AirportCards.vue 组件。

在项目设置时,使用终端中的npm run serve命令运行本地开发服务器:

1npm run serve

这将启动您的本地主机上的服务器,通常在端口8080,打开您所选择的Web浏览器,然后访问本地主机:8080,以查看以下内容:

A list of cards rendered in Vue using the v-for directive.

现在,您的示例应用程序已设置,在下一步,您将创建两个不同的 Vue.js 组件,以后可以用作页面布局。

步骤 2 — 使用插槽创建布局组件

布局组件是使用插槽元素组成 HTML 模板的组件,可以与不同的内容重复使用,这些组件非常适合当您有多个您想要重复使用的模板时,例如两列或三列布局。

您可以将它们放入组件文件夹中,但由于这些组件具有非常具体的任务,您的项目将更易于读取给其他程序员,如果你区分它们。

1mkdir src/layouts

接下来,在您的布局目录中创建一个名为DefaultLayout.vue的文件。DefaultLayout.vue组件将是一个包含视图内容的包装器,并将其集中在浏览器窗口中。

 1[label favorite-airports/src/layouts/DefaultLayout.vue]
 2<template>
 3  <div class="default-layout">
 4    <slot />
 5  </div>
 6</template>
 7
 8<style scoped>
 9  .default-layout {
10    max-width: 960px;
11    margin: 0 auto;
12  }
13</style>

这个组件是一个div具有默认布局的类别。你可以利用这个类来添加一些风格。你在上面的组件中看到的CSS风格将其宽度限制到最多为960px,侧边边是自动的。这将把div集中在浏览器窗口的水平上。slot元素是一个默认插座。在两个<layout-default>标签之间放置的任何东西都会被注入到这个<slot />的位置。你可以通过在上一步中修改的Home.vue来尝试。

在文本编辑器中,打开src/views/Home.vue导入``DefaultLayout.vue组件。

 1[label favorite-airports/src/views/Home.vue]
 2...
 3<script>
 4import allAirports from '@/data/airports.js'
 5import AirportCard from '@/components/AirportCard.vue'
 6import DefaultLayout from '@/layouts/DefaultLayout.vue'
 7
 8export default {
 9  components: {
10    AirportCard,
11    DefaultLayout
12  },
13  data() {
14    return {
15      airports: allAirports
16    }
17  }
18}
19</script>
20...

随着DefaultLayout.vue组件的导入,您现在可以将包含<div />的组件替换为<default-layout />

1[label favorite-airports/src/views/Home.vue]
2<template>
3  <default-layout class="wrapper">
4    <div v-for="airport in airports" :key="airport.abbreviation">
5      <airport-card :airport="airport" />
6    </div>
7  </default-layout>
8</template>
9...

您现在可以删除包含和中心divmax-widthmargin属性在.wrapper类中。 保存此文件,并在浏览器窗口中打开localhost:8080

在您转到下一步之前,您将创建另一个布局组件。这将是一个两个列布局。一个列将用于补充信息,另一个列将用于视图的主要内容。在src/layouts/TwoColumnLayout.vue创建一个新文件。一旦创建,请在文本编辑器中打开TwoColumnLayout.vue组件并添加以下内容:

 1[label favorite-airports/src/layouts/TwoColumnLayout.vue]
 2<template>
 3  <div class="two-column-layout">
 4    <aside>
 5      <slot name="sideBar" />
 6    </aside>
 7    <main>
 8      <slot name="content" />
 9    </main>
10  </div>
11</template>
12
13<style>
14  .two-column-layout {
15    display: grid;
16    grid-template-columns: 1fr 1fr 1fr;
17    grid-column-gap: 1rem;
18  }
19
20  .two-column-layout aside,
21  .two-column-layout main {
22    border: 1px solid;
23    border-radius: 5px;
24  }
25
26  .two-column-layout aside {
27    grid-column: span 1;
28  }
29
30  .two-column-layout main {
31    grid-column: span 2;
32  }
33</style>

在此组件中,您有两个命名的插槽,一个用于侧栏,另一个用于主内容. 在包含 <div> 的插件上,您正在使用 CSS 创建一个由三个列组成的网格,其中一个涵盖一个列,另一个涵盖两个列。

若要使用此布局,请在src/views/AirportDetail.vue创建机场详细信息视图的新视图,然后将下列代码添加到新文件中:

 1[label favorite-airports/src/views/AirportDetail.vue]
 2<template>
 3  <two-column-layout>
 4    <template v-slot:sideBar>
 5      <p>Sidebar</p>
 6    </template>
 7    <template v-slot:content>
 8      <p>Main Content</p>
 9    </template>
10  </two-column-layout>
11</template>
12
13<script>
14import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
15
16export default {
17  components: {
18    TwoColumnLayout
19  },
20}
21</script>

此新视图导入TwoColumnLayout.vue,然后使用v-slot以用正确的内容填充命名的插槽。

要查看此视图,请在 Vue router文件中添加路线:

 1[label favorite-airports/src/router/index.js]
 2import { createRouter, createWebHistory } from 'vue-router'
 3import Home from '../views/Home.vue'
 4import AirportDetail from '../views/AirportDetail'
 5
 6const routes = [
 7  {
 8    path: '/',
 9    name: 'Home',
10    component: Home
11  },
12  {
13    path: '/airport/:code',
14    name: 'AirportDetail',
15    component: AirportDetail
16  },
17  {
18    path: '/about',
19    name: 'About',
20    // route level code-splitting
21    // this generates a separate chunk (about.[hash].js) for this route
22    // which is lazy-loaded when the route is visited.
23    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
24  }
25]
26...

在这里,您正在注册一条路线,当您访问时,它将加载AirportDetail.vue组件。在路径中的:代码是一个论点,您可以稍后利用它来获取特定机场的数据。

保存您的文件,然后打开您的浏览器到localhost:8080/airport/cvg

The airport detail view, with a sidebar box and a main content box.

在此步骤中,您通过利用插槽创建了布局组件. 这些布局组件可以通过在创建网页结构时消除重复代码来帮助您的应用程序保持 DRY。

步骤 3 – 使用混合物共享方法和属性

Mixins 是将可重复使用的组件选项重新分配到任何数量的组件的一种方式。当一个 mixin 被导入时, mixin 的组件选项将被混合到当前的组件中。

假设您有两个具有独特属性的文件,前者有数据方法和计算属性,如下:

 1[label sample-component]
 2<script>
 3  export default {
 4    data() {
 5      return {
 6        firstName: 'Dave',
 7        lastName: 'Berning'
 8      }
 9    },
10    computed: {
11      fullName() {
12        return `${this.firstName} ${this.lastName}`
13      }
14    }
15  }
16</script>

第二个是包含您要重复使用的某些组件选项的文件:

 1[label someMixin]
 2export default {
 3  data() {
 4    return {
 5      counter: 0
 6    }
 7  },
 8  methods: {
 9    increment() {
10      this.counter++
11    }
12  }
13}

您可以将这两个文件混合在一起,将 mixin (someMixin) 导入组件(sample-component)。

 1[label sample-component]
 2<script>
 3import someMixin from '@/mixins/someMixin'
 4
 5export default {
 6  data() {
 7    return {
 8      firstName: 'Dave',
 9      lastName: 'Berning'
10    }
11  },
12  mixins: [ 'someMixin' ],
13  computed: {
14    fullName() {
15      return `${this.firstName} ${this.lastName}`
16    }
17  }
18}
19</script>

当被导入时,假设组件可以访问所有方法,数据,计算属性和可能包含的任何其他组件选项。

接下来,您将创建一个含有方法数据属性的混合,该函数将空港名称缩写相结合,并将其存储为一个数据属性。

在您的终端中,使用mkdir命令创建一个新目录:

1mkdir src/mixins

创建名为src/mixins/airport.js的文件并导出包含以下属性的对象:

 1[label src/mixins/airport.js]
 2export default {
 3  data() {
 4    return {
 5      airportWithCode: ''
 6    }
 7  },
 8  methods: {
 9    getAirportWithCode(airport) {
10      this.airportWithCode = `${airport.name} - ${airport.abbreviation}`
11    }
12  }
13}

此对象现在将有一个数据方法,一个方法将数据设置为机场的名称和缩写。

您将利用此方法数据属性来显示用户点击卡时返回的字符串:

 1[label src/views/Home.vue]
 2<template>
 3  <default-layout class="wrapper">
 4    <div v-for="airport in airports" :key="airport.abbreviation" @click="getAirportWithCode(airport)">
 5      <airport-card :airport="airport" />
 6    </div>
 7    <p>test: {{ airportWithCode }}</p>
 8  </default-layout>
 9</template>
10
11<script>
12import allAirports from '@/data/airports.js'
13import AirportCard from '@/components/AirportCard.vue'
14import DefaultLayout from '@/layouts/DefaultLayout.vue'
15import airportMixin from '@/mixins/airport.js'
16
17  export default {
18    components: {
19      AirportCard,
20      DefaultLayout
21    },
22    mixins: [ airportMixin ],
23    data() {
24      return {
25        airports: allAirports
26      }
27    }
28  }
29</script>
30...

由于您可以访问该组合中的方法数据,您可以将它们作为任何其他组件选项引用。您在本代码片段中做了这些操作,以便在用户点击卡片时存储一个airportWithCode值,然后将字符串值转换为段落元素。

接下来,在文本编辑器中打开AirportDetail.vue,然后写一个JavaScript过滤器,以返回airport对象,如果缩写匹配了先前在路由器中定义的:代码参数:

 1[label src/views/AirportDetail.vue]
 2...
 3<script>
 4import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
 5import allAirports from '@/data/airports.js'
 6
 7export default {
 8  components: {
 9    TwoColumnLayout
10  },
11  data() {
12    return {
13      airport: ''
14    }
15  },
16  methods: {
17  getAirportByCode() {
18    return allAirports.filter(airport => airport.abbreviation === this.$route.params.code.toUpperCase())[0]
19    }
20  },
21  mounted() {
22    this.airport = this.getAirportByCode()
23  }
24}
25</script>

在本片中,您正在创建一个名为getAirportByCode的新方法,它通过机场数据过滤并返回机场对象,其缩写匹配路线URL中的缩写。

保存文件. 接下来,导入您之前使用的 mixin. 您将利用您之前使用的相同的数据方法属性:

 1[label src/views/AirportDetail.vue]
 2<template>
 3  <two-column-layout>
 4    <template v-slot:sideBar>
 5      <p>Sidebar</p>
 6    </template>
 7    <template v-slot:content>
 8      <p>Main Content</p>
 9      <p>{{ airportWithCode }}</p>
10    </template>
11  </two-column-layout>
12</template>
13
14<script>
15import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
16import allAirports from '@/data/airports.js'
17import airportMixin from '@/mixins/airport.js'
18
19export default {
20  components: {
21    TwoColumnLayout
22  },
23  mixins: [ airportMixin ],
24  data() { ... },
25  methods: { ... },
26  mounted() {
27    this.airport = this.getAirportByCode()
28    this.getAirportWithCode(this.airport)
29  }
30}
31</script>

既然您已用getAirportByCode()确定特定机场,并将其设置为this.airport,您现在可以使用getAirportWithCode方法从混合物中设置airportWithCode值。

保存此檔案,並在瀏覽器窗口中開啟「localhost:8080/airport/cvg」。你會找到在主要內容部分中顯示的「airportWithCode」字符串值,如下圖像所示:

Detail view of the CVG airport, with the string "Cincinnati/Northern Kentucky International Airport - CVG" rendered in the main content section.

在此步骤中,您使用mixins在组件之间共享方法和计算属性。mixins可以是组织组件和利用可重复使用的代码在整个应用程序中的一种很好的方式。

步骤 4 – 使用构成 API

您在本教程中迄今为止尝试过的混合和布局组件可用于Vue的所有主要版本,包括Vue 2和更早版本,这些组成 Options API

Composition API 是建立组件的新方法,而不是为数据计算方法附件分开单独的部分,你有一个单一的设置链接,所有东西都生活在其中。

在此步骤中,您将从使用选项 API重构一个组件到新的构成 API

在您的文本编辑器中,打开AirportDetail.vue组件。 现在,您已经将一个 mixin 导入到该组件中。 该 mixin 提供了一些功能和数据属性。 但是在 Composition API 中,您的组件需要渲染的所有内容都将生活在设置方法中; 无需导入此方法。

移除您的混合物导入,并在安装下添加设置方法:

 1[label favorite-airports/src/views/AirportDetail.vue]
 2...
 3<script>
 4import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
 5import allAirports from '@/data/airports.js'
 6
 7export default {
 8  components: { ... },
 9  methods: {
10    getAirportByCode() {
11      return allAirports.filter(airport => airport.abbreviation === this.$route.params.code.toUpperCase())[0]
12    }
13  },
14  mounted() { ... },
15  setup() {
16
17  }
18}
19</script>

创建设置方法后,请通过添加新的OnMounted生命周期链接开始重构此功能,该onMounted函数接受一个参数,通常是一个匿名函数:

 1[label favorite-airports/src/views/AirportDetail.vue]
 2...
 3<script>
 4import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
 5import allAirports from '@/data/airports.js'
 6import { onMounted } from 'vue'
 7
 8export default {
 9  components: { ... },
10  methods: {
11    getAirportByCode() {
12      return allAirports.filter(airport => airport.abbreviation === this.$route.params.code.toUpperCase())[0]
13    }
14  },
15  mounted() { ... },
16  setup() {
17    onMounted(() => {
18
19    })
20  }
21}
22</script>

当这个组件被安装时,你会将当前的机场对象存储在一个反应性数据属性中。 要创建一个变量或恒定性,你需要将该值嵌入一个ref函数中,你将从vue中导入这个函数。 恒定值的名称将是您在组件的设置模板部分中的参考名称。 另外,从方法中删除getAirportByCode并将其定义为设置中的常规JavaScript函数:

 1[label favorite-airports/src/views/AirportDetail.vue]
 2...
 3<script>
 4import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
 5import allAirports from '@/data/airports.js'
 6import { onMounted, ref } from 'vue'
 7
 8export default {
 9  components: { ... },
10  mounted() { ... },
11  setup() {
12    function getAirportByCode() {
13      return allAirports.filter(airport => airport.abbreviation === this.$route.params.code.toUpperCase())[0]
14    }
15
16    onMounted(() => {
17      const airport = ref(getAirportByCode())
18    })
19  }
20}
21</script>

完成此操作后,您可以继续从组件文件中删除旧的安装方法属性。

由于您现在没有使用混合,您将在设置函数中定义getAirportWithCode,并将其分配给一个变量airportWithCode,以便在您的视图中使用它:

 1[label favorite-airports/src/views/AirportDetail.vue]
 2...
 3<script>
 4import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
 5import allAirports from '@/data/airports.js'
 6import { onMounted, ref } from 'vue'
 7
 8export default {
 9  components: {
10    TwoColumnLayout
11  },
12  setup() {
13    const airportWithCode = ref('')
14
15    function getAirportByCode() {
16      return allAirports.filter(airport => airport.abbreviation === this.$route.params.code.toUpperCase())[0]
17    }
18
19    function getAirportWithCode(airport) {
20      return `${airport.name} - ${airport.abbreviation}`
21    }
22
23      onMounted(() => {
24        const airport = ref(getAirportByCode())
25      })
26    }
27  }
28</script>

对于 Composition API 的反应性数据属性,一个非常重要的事情是ref返回一个对象,要访问这些值,你需要访问其.value属性:

 1[label favorite-airports/src/views/AirportDetail.vue]
 2...
 3<script>
 4import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
 5import allAirports from '@/data/airports.js'
 6import { onMounted, ref } from 'vue'
 7
 8export default {
 9  components: {
10    TwoColumnLayout
11  },
12  setup() {
13    const airportWithCode = ref('')
14
15    function getAirportByCode() {
16      return allAirports.filter(airport => airport.abbreviation === this.$route.params.code.toUpperCase())[0]
17    }
18
19    function getAirportWithCode(airport) {
20      return `${airport.name} - ${airport.abbreviation}`
21    }
22
23    onMounted(() => {
24      const airport = ref(getAirportByCode())
25      airportWithCode.value = getAirportWithCode(airport.value)
26    })
27  }
28}
29</script>

现在有两件事你需要做,才能完全转换使用 Composition API. 你需要改变的第一件事是getAirportByCode函数中的this.$route

要访问路线,请从vue-router包中导入useRoute,最好将其保存到一个const中,您可以在整个应用程序中参考:

 1[label favorite-airports/src/views/AirportDetail.vue]
 2...
 3<script>
 4import TwoColumnLayout from '@/layouts/TwoColumnLayout.vue'
 5import allAirports from '@/data/airports.js'
 6import { onMounted, ref } from 'vue'
 7import { useRoute } from 'vue-router'
 8
 9export default {
10  components: {
11    TwoColumnLayout
12  },
13  setup() {
14    const route = useRoute()
15    const airportWithCode = ref('')
16
17    function getAirportByCode() {
18      return allAirports.filter(airport => airport.abbreviation === route.params.code.toUpperCase())[0]
19    }
20
21    function getAirportWithCode(airport) {
22      return `${airport.name} - ${airport.abbreviation}`
23    }
24
25    onMounted(() => {
26      const airport = ref(getAirportByCode())
27      airportWithCode.value = getAirportWithCode(airport.value)
28    })
29  }
30}
31</script>

完成后,请将对象返回您的设置函数,此对象返回的属性可用于模板:

 1[label favorite-airports/src/views/AirportDetail.vue]
 2...
 3  setup() {
 4    const route = useRoute()
 5    const airportWithCode = ref('')
 6
 7    function getAirportByCode() {
 8      return allAirports.filter(airport => airport.abbreviation === route.params.code.toUpperCase())[0]
 9    }
10
11    function getAirportWithCode(airport) {
12      return `${airport.name} - ${airport.abbreviation}`
13    }
14
15    onMounted(() => {
16      const airport = ref(getAirportByCode())
17      airportWithCode.value = getAirportWithCode(airport.value)
18    })
19
20    return { airportWithCode }
21  }
22}
23</script>

保存您的代码并在浏览器中重新加载「localhost:8080/airport/cvg」。 重新编写代码后,将不会有任何变更。

结论

在本教程中,您尝试了一些策略来使您的应用程序 DRY. 具体来说,您在多个视图中重新使用布局组件,然后用混合物模块化属性和方法。

如果您想了解更多关于 MixinsComposition API的信息,则强烈建议您查看官方的 Vue 文档。

Published At
Categories with 技术
comments powered by Disqus