首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >访问和过滤Vue.js组件的<slot>中定义的子组件

访问和过滤Vue.js组件的<slot>中定义的子组件
EN

Stack Overflow用户
提问于 2017-08-23 09:11:24
回答 1查看 2.7K关注 0票数 1

我正在为我正在编写的UI库实现一个组合的select下拉列表和搜索框组件,使用Vue.js来驱动交互,但我遇到了一个问题,Vue.js似乎如何处理父组件和子组件之间的通信。

基本上,我的目标是允许库的用户使用以下内容定义HTML中的搜索选择元素:

代码语言:javascript
运行
复制
<search-select>
    <search-option value="foo">Foo</search-option>
    <search-option value="bar">Bar</search-option>
    <search-option value="baz">Baz</search-option>
    <search-option value="foobar">Foobar</search-option>
</search-select>

我的search-select组件模板如下所示:

代码语言:javascript
运行
复制
<template>
    <div class="search-select">
        <div class="placeholder" ref="placeholder"></div>
        <ul class="dropdown">
            <input
                type="text"
                placeholder="Type to filter..."
                v-on:input="updateFilter"
            >
            <slot></slot>
        </ul>
    </div>
</template>

其思想是,search-select组件将在指定输入的基础上添加一个文本输入框,用户可以输入该输入框来筛选可以选择的选项。完成的组件看起来类似于

但是,从文档中可以看出,Vue.js没有为我提供任何直接的方式来从父级访问子组件的属性,也没有提供任何方式从父级<slot>中侦听click事件或类似的子组件。

这意味着我无法根据用户的输入筛选子组件的可见性,或者在用户单击其中一个子组件时更新search-select组件的值。

Vue.js文档提到了将事件从子组件传递给父组件的方法,但似乎没有一种方法适用于在插槽中定义的元素--似乎父母只能监听在其中显式定义的组件中的事件。

如何实现此用例所需的父组件和子组件之间的双向通信类型,而不违反与组件之间共享信息有关的任何Vue.js最佳实践?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-23 09:46:27

您可以使用事件总线来解决这个问题。只需让每个选项侦听输入事件,然后让它根据传递的参数决定是否隐藏自己。

请参阅下面的小提琴或演示。

代码语言:javascript
运行
复制
const bus = new Vue();

Vue.component('search-option', {
  template: `
    <option v-if="show" :value="this.$attrs.value"><slot></slot></option> 
  `,
  created() {
    bus.$on('filter', (input) => {
      this.show = this.$attrs.value.includes(input);
    });
  },
  beforeDestory() {
    bus.$off('filter');
  },
  data() {
    return {
      show: true,
    };
  },
});

Vue.component('search-select', {
  template: `
<div class="search-select">
    <div class="placeholder" ref="placeholder"></div>
    <ul class="dropdown">
        <input
            type="text"
            placeholder="Type to filter..."
            v-on:input="updateFilter"
            v-model="myinput"
        >
        <slot></slot>
    </ul>
</div>
  `,
  methods: {
    updateFilter() {
      console.log('update filter');
      bus.$emit('filter', this.myinput);
    },
  },
  data() {
    return {
        myinput: undefined,
    };
  },
});

Vue.component('parent', {
  template: `
<div class="parent">
<search-select>
    <search-option value="foo">Foo</search-option>
    <search-option value="bar">Bar</search-option>
    <search-option value="baz">Baz</search-option>
    <search-option value="foobar">Foobar</search-option>
</search-select>
</div>
  `,
});

new Vue({
  el: '#app',
})
代码语言:javascript
运行
复制
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<div id="app">
  <parent></parent>
</div>

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45835400

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档