Vuejs中组件开发从初级到高级(二)

已收录   阅读次数: 725
2021-10-2816:09:20 发表评论
摘要

在上一篇介绍了Vuejs的组件开发,具体可以参看下方的前情提要,而本篇文章继续沿着上一篇的内容说开去,即向深层次去理解Vuejs中组件的开发……

分享至:
Vuejs中组件开发从初级到高级(二)

开篇寄语

在上一篇介绍了Vuejs的组件开发,具体可以参看下方的前情提要,而本篇文章继续沿着上一篇的内容说开去,即向深层次去理解Vuejs中组件的开发。

前情提要

内容详情

以下内容是以Vue3版本来说的,虽然与Vue2版本区别不是很大。

上一篇文章讲了如何用vuejs开发组件的基本知识,那么问题来了,在组件内部定制化内容,同样一个模板<template></template>但是显示的样子不一样,也就是说引用模板时要处理构造的组件数据,就需要引入一个名为‘slots’的概念了。

Vuejs的文档是这样写的:

Vue implements a content distribution API inspired by the Web Components spec draft (opens new window), using the element to serve as distribution outlets for content.

组件是现代 Web 应用程序开发的核心。每个应用程序都由许多组件组成,这些组件平滑地拼接在一起,以便作为一个整体运行。这些组件需要最大程度地灵活和可重用,以允许在不同的情况下甚至在不同的应用程序中使用它们。许多框架用来满足这些要求的主要机制之一——尤其是 Vue——​​被称为“slot”。

Slot是一种功能强大且通用的内容分发和组合机制。您可以将Slot视为可定制的模板(例如,类似于 PHP 模板),您可以在不同的地方使用它们,针对不同的用例,产生不同的效果。例如,在像 Vuetify 这样的 UI 框架中,常用于制作通用组件,例如警报组件。在这些类型的组件中, Slot用作默认内容和任何附加/可选内容(例如图标、图像等)的占位符。

Slot允许您向特定组件添加任何结构、样式和功能。通过使用Slot,开发人员可以大大减少单个组件中使用的 props 数量,使组件更加干净和易于管理。

试举一例:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Vue Demo</title>
</head>

<body>
    <div id="app">
        <com-input></com-input>
        <com-input>
            <template v-slot="slot">
                <span>{{ slot.data.join(' * ') }}</span>
            </template>
        </com-input>
        <com-input>
            <template v-slot="slot">
                <span>{{ slot.data.join(' - ') }}</span>
            </template>
        </com-input>
    </div>
    <template id="cpn">
        <div>
          <slot :data="Language">
              <ul>
                  <li v-for="(item, index) in Language" :key="index">{{ item }}</li>
                </ul>
          </slot>
        </div>
    </template>
    <script src="https://unpkg.com/vue@next"></script>
    <script>
        const app = Vue.createApp({
            data() {
                return {
                    isShow: true
                }
            },
        });
        app.component('com-input', {
            template: "#cpn",
            data() {
                return {
                    isShwo: false,
                    Language: ['Japanese', 'English', 'Chinese', 'Korean']
                }
            },
        })
        app.mount("#app")
    </script>
</body>

</html>

生成效果如下所示:

Vuejs中组件开发从初级到高级(二)

可以通过以上例子看出,在处理模板数据中,以slot位标志的内容,如下所示:

    <div id="app">
        <com-input></com-input>
        <com-input>
            <template v-slot="slot">
                <span>{{ slot.data.join(' * ') }}</span>
            </template>
        </com-input>
        <com-input>
            <template v-slot="slot">
                <span>{{ slot.data.join(' - ') }}</span>
            </template>
        </com-input>
    </div>
    <template id="cpn">
        <div>
          <slot :data="Language">
              <ul>
                  <li v-for="(item, index) in Language" :key="index">{{ item }}</li>
                </ul>
          </slot>
        </div>
    </template>

其中比较关键的就是v-slot的使用。

通过上面通俗易通的例子,是不是对slot有了一定的理解了?

为了照顾大多数初次接触Vue.js的朋友,接下来讲一下如何从头开始构建slot的过程以加深理解。

基本上,Vue 提供两种slot:简单slot和作用域slot。让我们从简单的开始。考虑以下示例:

const app = Vue.createApp({})

app.component('primary-button', {
  template: `
    <button>
      <slot>OK</slot>
    </button>`
})

app.mount('#app')

在这里,我们有一个主要的按钮组件。我们希望按钮的文本是可自定义的,因此我们使用按钮元素内的slot组件为文本添加占位符。我们还需要一个默认(后备)通用值,以防我们不提供自定义值。 Vue 使用我们放在 slot 组件中的所有内容作为默认 slot 内容。所以我们只是将文本“OK”放在组件中。现在我们可以像这样使用组件:

<div id="app">
  <primary-button></primary-button>
</div>

结果是一个带有文本“OK”的按钮,因为我们没有提供任何值。但是如果我们想创建一个带有自定义文本的按钮怎么办?在这种情况下,我们在组件实现中提供自定义文本,如下所示:

<div id="app">
  <primary-button>Subscribe</primary-button>
</div>

在这里,Vue 采用自定义的“Subscribe”文本并替代了之前的”OK“。

以上的示例很简单吧,那接下来咱们来点难的。

const app = Vue.createApp({}) 

app.component('quote', {
  template: `
    <article>
      <h2>The quote of the day says:</h2>
      <p class="quote-text">
        <slot></slot>
      </p>
    </article>`
})

app.mount('#app')
<div id="app">
  <quote>
    <div class="quote-box">
      "Creativity is just connecting things."
      <br><br>
      - Steve Jobs
    </div>
  </quote>
</div>
.quote-box {
  background-color: lightgreen;
  width: 300px;
  padding: 5px 10px;
}

.quote-text {
  font-style: italic;
}

在这个例子中,我们创建了一个内容不变的标题标题,然后我们在一个段落中放置了一个slot组件,其内容将根据当天的引用而变化。当组件被渲染时,Vue 将显示来自引用组件的标题,然后是我们放在引用标签中的内容。还要注意引用创建和实现中使用的 CSS 类。我们可以根据需要以两种方式设置组件的样式。

继续让它动态化,引入一个Api,自动生成随机的经典名言,如下所示:

const app = Vue.createApp({
  data() {
    return {
      quoteOfTheDay: null,
      show: false
    };
  },
  methods: {
    showQuote() {
      axios.get('https://favqs.com/api/qotd').then(result => {
        this.quoteOfTheDay = result.data
        this.show = true
      }); 
    }
  }
}) 

app.component('quote', {
  template: `
    <article>
      <h2>The quote of the day says:</h2>
      <p class="quote-text">
        <slot></slot>
      </p>
    </article>`
})

app.mount('#app')
<div id="app">
  <quote>
    <button v-if="show == false" @click="showQuote">Show Quote of the Day</button>
    <div v-if="show" class="quote-box">
      {{ quoteOfTheDay.quote.body }} 
      <br><br>
      - {{ quoteOfTheDay.quote.author }}
    </div>
  </quote>
</div>
.quote-box {
  background-color: lightgreen;
  width: 300px;
  padding: 5px 10px;
}

.quote-text {
  font-style: italic;
}

生成效果如下所示:

  • 我的微信
  • 微信扫一扫加好友
  • weinxin
  • 我的微信公众号
  • 扫描关注公众号
  • weinxin

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: