<p dir="auto">A common requirement for a <code class="notranslate">filterBy search in ...</code> is to specify multiple keys to look, but not all of them (as that might produce false positives from fields irrelevant/invisible to the user).</p>
<p dir="auto">Below is a crude modification of <code class="notranslate">filterBy</code>, dubbed <code class="notranslate">filterByKeys</code>. Usage example:</p>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;li v-repeat=&quot;users | filterByKeys searchText in 'firstname' 'lastname'&quot;&gt;{{username}}&lt;/li&gt;"><pre class="notranslate"><span class="pl-kos">&lt;</span><span class="pl-ent">li</span> <span class="pl-c1">v-repeat</span>="<span class="pl-s">users | filterByKeys searchText in 'firstname' 'lastname'</span>"<span class="pl-kos">&gt;</span>{{username}}<span class="pl-kos">&lt;/</span><span class="pl-ent">li</span><span class="pl-kos">&gt;</span></pre></div>
<p dir="auto">Would it be possible to add this filter to the core (or perhaps replace <code class="notranslate">filterBy</code> with it, as it should be backwards compatible)?</p>
<p dir="auto">Currently, keeping this in a separate custom filters file requires duplicating the <code class="notranslate">contains</code> function and pulling in the same requirements as for <code class="notranslate">array-filters.js</code> itself.</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="var filterByKeys = function(){
    // Convert arguments to an actual Array
    var args = [].slice.call(arguments)
    var arr = args.shift()
    var search = args.shift()
    // cast to lowercase string
    search = ('' + search).toLowerCase()
    // strip optional 'in'
    if (args[0] == 'in'){
      delete args[0]
    }
    // if left with 0 keys, fall back to all keys
    var keys = args.length &gt; 0 ? args : Object.keys(args);

    // filter input array
    return arr.filter(function (item) {
      var result = false
      keys.forEach(function(datakey){
        result = result || contains(Path.get(item, datakey), search)
      })
      return result;
    })
  }"><pre class="notranslate"><span class="pl-k">var</span> <span class="pl-en">filterByKeys</span> <span class="pl-c1">=</span> <span class="pl-k">function</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">{</span>
    <span class="pl-c">// Convert arguments to an actual Array</span>
    <span class="pl-k">var</span> <span class="pl-s1">args</span> <span class="pl-c1">=</span> <span class="pl-kos">[</span><span class="pl-kos">]</span><span class="pl-kos">.</span><span class="pl-c1">slice</span><span class="pl-kos">.</span><span class="pl-en">call</span><span class="pl-kos">(</span><span class="pl-smi">arguments</span><span class="pl-kos">)</span>
    <span class="pl-k">var</span> <span class="pl-s1">arr</span> <span class="pl-c1">=</span> <span class="pl-s1">args</span><span class="pl-kos">.</span><span class="pl-en">shift</span><span class="pl-kos">(</span><span class="pl-kos">)</span>
    <span class="pl-k">var</span> <span class="pl-s1">search</span> <span class="pl-c1">=</span> <span class="pl-s1">args</span><span class="pl-kos">.</span><span class="pl-en">shift</span><span class="pl-kos">(</span><span class="pl-kos">)</span>
    <span class="pl-c">// cast to lowercase string</span>
    <span class="pl-s1">search</span> <span class="pl-c1">=</span> <span class="pl-kos">(</span><span class="pl-s">''</span> <span class="pl-c1">+</span> <span class="pl-s1">search</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">toLowerCase</span><span class="pl-kos">(</span><span class="pl-kos">)</span>
    <span class="pl-c">// strip optional 'in'</span>
    <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-s1">args</span><span class="pl-kos">[</span><span class="pl-c1">0</span><span class="pl-kos">]</span> <span class="pl-c1">==</span> <span class="pl-s">'in'</span><span class="pl-kos">)</span><span class="pl-kos">{</span>
      <span class="pl-k">delete</span> <span class="pl-s1">args</span><span class="pl-kos">[</span><span class="pl-c1">0</span><span class="pl-kos">]</span>
    <span class="pl-kos">}</span>
    <span class="pl-c">// if left with 0 keys, fall back to all keys</span>
    <span class="pl-k">var</span> <span class="pl-s1">keys</span> <span class="pl-c1">=</span> <span class="pl-s1">args</span><span class="pl-kos">.</span><span class="pl-c1">length</span> <span class="pl-c1">&gt;</span> <span class="pl-c1">0</span> ? <span class="pl-s1">args</span> : <span class="pl-v">Object</span><span class="pl-kos">.</span><span class="pl-en">keys</span><span class="pl-kos">(</span><span class="pl-s1">args</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

    <span class="pl-c">// filter input array</span>
    <span class="pl-k">return</span> <span class="pl-s1">arr</span><span class="pl-kos">.</span><span class="pl-en">filter</span><span class="pl-kos">(</span><span class="pl-k">function</span> <span class="pl-kos">(</span><span class="pl-s1">item</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
      <span class="pl-k">var</span> <span class="pl-s1">result</span> <span class="pl-c1">=</span> <span class="pl-c1">false</span>
      <span class="pl-s1">keys</span><span class="pl-kos">.</span><span class="pl-en">forEach</span><span class="pl-kos">(</span><span class="pl-k">function</span><span class="pl-kos">(</span><span class="pl-s1">datakey</span><span class="pl-kos">)</span><span class="pl-kos">{</span>
        <span class="pl-s1">result</span> <span class="pl-c1">=</span> <span class="pl-s1">result</span> <span class="pl-c1">||</span> <span class="pl-en">contains</span><span class="pl-kos">(</span><span class="pl-v">Path</span><span class="pl-kos">.</span><span class="pl-en">get</span><span class="pl-kos">(</span><span class="pl-s1">item</span><span class="pl-kos">,</span> <span class="pl-s1">datakey</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-s1">search</span><span class="pl-kos">)</span>
      <span class="pl-kos">}</span><span class="pl-kos">)</span>
      <span class="pl-k">return</span> <span class="pl-s1">result</span><span class="pl-kos">;</span>
    <span class="pl-kos">}</span><span class="pl-kos">)</span>
  <span class="pl-kos">}</span></pre></div>
<p dir="auto">PS. Possible issues might arise from the <code class="notranslate">arguments</code> conversion as that is a bit funky and I'm not 100% sure of browser compatibility</p>
<h3 dir="auto">Version</h3>
<p dir="auto">2.5.17</p>
<h3 dir="auto">Reproduction link</h3>
<p dir="auto"><a href="https://jsfiddle.net/jsotron5000/eywraw8t/464522/" rel="nofollow">https://jsfiddle.net/jsotron5000/eywraw8t/464522/</a></p>
<h3 dir="auto">Steps to reproduce</h3>
<p dir="auto">Run the JSFiddle and open up dev tools.<br>
You will see the Vue warning about duplicate default slots even though there is only one slot in the template.</p>
<h3 dir="auto">What is expected?</h3>
<p dir="auto">No warning when using child components slotted into a renderless component.</p>
<h3 dir="auto">What is actually happening?</h3>
<p dir="auto">A warning is displayed saying there are duplicate default slots when there is only one.</p>
<hr>
<p dir="auto">Here is another JSFiddle with a use case where this bug would occur:</p>
<p dir="auto"><a href="https://jsfiddle.net/jsotron5000/eywraw8t/464242/" rel="nofollow">https://jsfiddle.net/jsotron5000/eywraw8t/464242/</a></p>
<p dir="auto">It is a renderless tabs component that works with another component (TabItem) which can be passed in through a slot.</p>
<p dir="auto">The TabContainer component looks at the TabItem components and relays them to the parent component through a scoped slot.</p>
<p dir="auto">The warning only displays when doing anything with the child vnodes inside the render function.</p>
<p dir="auto">If you replace the children prop in the JSFiddle with just a hard coded array there is no warning.</p>