Home > Web Front-end > Vue.js > body text

Detailed explanation of non-rendering behavior slots in Vue

青灯夜游
Release: 2020-10-14 17:29:47
forward
1844 people have browsed it

Detailed explanation of non-rendering behavior slots in 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>
Copy after login

用法:

<lazy-loading url="https://server/api/data">
  <template #default="{ data }">
    <div>{{ data }}</div>
  </template>
</lazy-loading>
Copy after login

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

一个相反的问题

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

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

Detailed explanation of non-rendering behavior slots in 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>
Copy after login

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

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

<script>
export default {
  methods: {
    onClick(node) {
      this.$refs.tree.retractNode(node);
    }
  }
};
</script>
Copy after login

这种方法有几个缺点:

  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>
Copy after login

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

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

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

  render: () => null,

  created() {
    this.on("click", (node) => {
      this.actions.expandNode(node);
    });
  }
};
Copy after login

用法:

<tree>
  <template #behavior="{ on, actions }">
    <expand-on-click v-bind="{ on, actions }"/>
  </template>
</tree>
Copy after login

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

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

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

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

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

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

  render: () => null,

  created() {
    this.on("hover", (node) => {
      this.actions.highlight(node);
    });
  }
};
Copy after login

覆盖标准行为:

<tree>
  <template #behavior="{ on, actions }">
    <highlight-on-hover v-bind="{ on, actions }"/>
  </template>
</tree>
Copy after login
  • 行为插槽是可组合的

添加两个预定义的行为:

<tree>
  <template #behavior="{ on, actions }">
    <expand-on-click v-bind="{ on, actions }"/>
    <highlight-on-hover v-bind="{ on, actions }"/>
  </template>
</tree>
Copy after login
  • 解决方案的可读性

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

  • 可扩展性

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

总结

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

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

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

作者:David Desmaisons

相关推荐:

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

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

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

The above is the detailed content of Detailed explanation of non-rendering behavior slots in Vue. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:segmentfault.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template