目錄
无渲染组件
一个相反的问题
无渲染插槽
总结
首頁 web前端 Vue.js 詳解Vue中的無渲染行為插槽

詳解Vue中的無渲染行為插槽

Oct 14, 2020 pm 05:29 PM
vue 插槽

詳解Vue中的無渲染行為插槽

在本文中我们讨论 Vue 中的无渲染插槽模式能够帮助解决哪些问题。

在 Vue.js 2.3.0 中引入的作用域插槽显著提高了组件的可重用性。无渲染组件模式应运而生,解决了提供可重用行为和可插入表示的问题。

在这里,我们将会看到如何解决相反的问题:怎样提供可重用的外观和可插入的行为。

无渲染组件

这种模式适用于实现复杂行为且具有可自定义表示的组件。

它满足以下功能:

  1. 该组件实现所有行为
  2. 作用域的插槽负责渲染
  3. 后备内容能够确保组件可以直接使用。

举个例子:一个执行 Ajax 请求并显示结果的插槽的组件。组件处理 Ajax 请求并加载状态,而默认插槽提供演示。

这是一个简化版的实现:

<template>
  <div>
    <slot v-if="loading" name="loading">
        <div>Loading ...</div>
    </slot>
    <slot v-else v-bind={data}>
    </slot>
  </div>
</template>

<script>
export default {
  props: ["url"],
  data: () => ({
    loading: true,
    data: null
  }),
  async created() {
    this.data = await fetch(this.url);
    this.loading = false;
  }
};
</script>
登入後複製

用法:

<lazy-loading url="https://server/api/data">
  <template #default="{ data }">
    <div>{{ data }}</div>
  </template>
</lazy-loading>
登入後複製

有关这种模式的原始文章,请在这里查看

一个相反的问题

如果问题反过来该怎么办:想象一下,如果一个组件的主要特征就是它的表示形式,另外它的行为应是可自定义的。

假设你想要基于 SVG 创建一个树组件,如下所示:

詳解Vue中的無渲染行為插槽

你想要提供 SVG 的显示和行为,例如在单击时收回节点和突出显示文本。

当你打算不对这些行为进行硬编码,并且让组件的用户自由覆盖它们时,就会出现问题。

暴露这些行为的简单解决方案是向组件添加方法和事件。

你可能会这样去实现:

<script>
export default {
  mounted() {
    // pseudo code
    nodes.on(&#39;click&#39;,(node) => this.$emit(&#39;click&#39;, node));
  },
  methods: {
    expandNode(node) {
      //...
    },
    retractNode(node) {
      //...
    },
    highlightText(node) {
      //...
    },
  }
};
</script>
登入後複製

如果组件的使用者要向组件添加行为,需要在父组件中使用 ref,例如:

<template>
  <tree ref="tree" @click="onClick"></tree>
</template>

<script>
export default {
  methods: {
    onClick(node) {
      this.$refs.tree.retractNode(node);
    }
  }
};
</script>
登入後複製

这种方法有几个缺点:

  1. 无法再提供默认行为
  2. 行为代码最终会被频繁的复制粘贴
  3. 行为不可重用

让我们看看无渲染插槽如何解决这些问题。

无渲染插槽

行为基本上包括证明对事件的反应。所以让我们创建一个插槽,用来接收对事件和组件方法的访问:

<template>
  <div>
    <slot name="behavior" :on="on" :actions="actions">
    </slot>
  </div>
</template>

<script>
export default {
  methods: {
    expandNode(node) { },
    retractNode(node) { },
   //...
  },
  computed:{
    actions() {
      const {expandNode, retractNode} = this;
      return {expandNode, retractNode};
    },
    on() {
      return this.$on.bind(this);
    }
  }
};
</script>
登入後複製

on 属性是父组件的 $on 方法,因此可以监听所有事件。

可以将行为实现为无渲染组件。接下来编写点击扩展组件:

export default {
  props: [&#39;on&#39;,&#39;action&#39;]

  render: () => null,

  created() {
    this.on("click", (node) => {
      this.actions.expandNode(node);
    });
  }
};
登入後複製

用法:

<tree>
  <template #behavior="{ on, actions }">
    <expand-on-click v-bind="{ on, actions }"/>
  </template>
</tree>
登入後複製

该解决方案的主要优点是:

  • 通过备用内容来提供默认行为的可能性:

例如,通过将图形组件声明为:

<template>
  <div>
    <slot name="behavior" :on="on" :actions="actions">
      <expand-on-click v-bind="{ on, actions }"/>
    </slot>
  </div>
</template>
登入後複製
  • 能够创建可重用的组件,并可以实现使用这个组件的用户能够选择的标准行为

考虑一个悬停突出显示组件:

export default {
  props: [&#39;on&#39;,&#39;action&#39;]

  render: () => null,

  created() {
    this.on("hover", (node) => {
      this.actions.highlight(node);
    });
  }
};
登入後複製

覆盖标准行为:

<tree>
  <template #behavior="{ on, actions }">
    <highlight-on-hover v-bind="{ on, actions }"/>
  </template>
</tree>
登入後複製
  • 行为插槽是可组合的

添加两个预定义的行为:

<tree>
  <template #behavior="{ on, actions }">
    <expand-on-click v-bind="{ on, actions }"/>
    <highlight-on-hover v-bind="{ on, actions }"/>
  </template>
</tree>
登入後複製
  • 解决方案的可读性

作为行为的组件是能够自描述的。

  • 可扩展性

on 属性可以访问所有组件事件。默认情况下,该插槽可使用新事件。

总结

无渲染插槽提供了一种有趣的解决方案,可以在组件中公开方法和事件。它们提供了更具可读性和可重用性的代码。

可以在 github 上找到实现此模式的树组件的代码:Vue.D3.tree

英文地址原文:https://alligator.io/vuejs/renderless-behavior-slots/

作者:David Desmaisons

相关推荐:

2020年前端vue面试题大汇总(附答案)

vue教程推荐:2020最新的5个vue.js视频教程精选

更多编程相关知识,请访问:编程入门!!

以上是詳解Vue中的無渲染行為插槽的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

vue中怎麼用bootstrap vue中怎麼用bootstrap Apr 07, 2025 pm 11:33 PM

在 Vue.js 中使用 Bootstrap 分為五個步驟:安裝 Bootstrap。在 main.js 中導入 Bootstrap。直接在模板中使用 Bootstrap 組件。可選:自定義樣式。可選:使用插件。

vue怎麼給按鈕添加函數 vue怎麼給按鈕添加函數 Apr 08, 2025 am 08:51 AM

可以通過以下步驟為 Vue 按鈕添加函數:將 HTML 模板中的按鈕綁定到一個方法。在 Vue 實例中定義該方法並編寫函數邏輯。

vue中的watch怎麼用 vue中的watch怎麼用 Apr 07, 2025 pm 11:36 PM

Vue.js 中的 watch 選項允許開發者監聽特定數據的變化。當數據發生變化時,watch 會觸發一個回調函數,用於執行更新視圖或其他任務。其配置選項包括 immediate,用於指定是否立即執行回調,以及 deep,用於指定是否遞歸監聽對像或數組的更改。

vue多頁面開發是啥意思 vue多頁面開發是啥意思 Apr 07, 2025 pm 11:57 PM

Vue 多頁面開發是一種使用 Vue.js 框架構建應用程序的方法,其中應用程序被劃分為獨立的頁面:代碼維護性:將應用程序拆分為多個頁面可以使代碼更易於管理和維護。模塊化:每個頁面都可以作為獨立的模塊,便於重用和替換。路由簡單:頁面之間的導航可以通過簡單的路由配置來管理。 SEO 優化:每個頁面都有自己的 URL,這有助於搜索引擎優化。

vue.js怎麼引用js文件 vue.js怎麼引用js文件 Apr 07, 2025 pm 11:27 PM

在 Vue.js 中引用 JS 文件的方法有三種:直接使用 &lt;script&gt; 標籤指定路徑;利用 mounted() 生命週期鉤子動態導入;通過 Vuex 狀態管理庫進行導入。

vue返回上一頁的方法 vue返回上一頁的方法 Apr 07, 2025 pm 11:30 PM

Vue.js 返回上一頁有四種方法:$router.go(-1)$router.back()使用 &lt;router-link to=&quot;/&quot;&gt; 組件window.history.back(),方法選擇取決於場景。

vue遍歷怎麼用 vue遍歷怎麼用 Apr 07, 2025 pm 11:48 PM

Vue.js 遍歷數組和對像有三種常見方法:v-for 指令用於遍歷每個元素並渲染模板;v-bind 指令可與 v-for 一起使用,為每個元素動態設置屬性值;.map 方法可將數組元素轉換為新數組。

vue的div怎麼跳轉 vue的div怎麼跳轉 Apr 08, 2025 am 09:18 AM

Vue 中 div 元素跳轉的方法有兩種:使用 Vue Router,添加 router-link 組件。添加 @click 事件監聽器,調用 this.$router.push() 方法跳轉。

See all articles