<p>This one does not have <code>v-bind:keys</code> set. Notice the incorrect DOM, color, and structure when sorting. Works when changing a few innocuous things, like if using <code>&lt;span&gt;</code>s instead of <code>&lt;div&gt;</code>s in the $slots or wrapping <code>render-vnodes</code> with an extra <code>&lt;div&gt;</code></p>
<div id="app">
  <button @click="$root.$emit('sort1')">Toggle Sorting
  </button>
  <color-izer>
    <div>GREEN 2</div>
    <div>RED 1</div>
    <div>GREEN 1</div>
    <div>RED 2</div>
    <div>RED 3</div>
    <div>GREEN 3</div>
  </color-izer>
  <p>This one has <code>v-bind:keys</code>. It works fine</p>
  <button @click="$root.$emit('sort2')">Toggle Sorting
  </button>
  <color-izer set-keys="true">
    <div>GREEN 2</div>
    <div>RED 1</div>
    <div>GREEN 1</div>
    <div>RED 2</div>
    <div>RED 3</div>
    <div>GREEN 3</div>
  </color-izer>
</div>
html, body{
  max-width: 800px;
}
Vue.component("render-vnodes", {
  functional: true,
  render: function(createElement, ctx){
    return createElement("div", {}, ctx.props.vnodes);
  }
});

Vue.component("color-izer", {
  template: "<div><div style='display:inline-block;border:1px solid black;padding:4px;'>SORTED? {{sorted}}</div><br>" +
  "<render-vnodes v-if='sorted' :vnodes='nodesForColor(\"r\")'></render-vnodes>" + 
  "<render-vnodes v-if='sorted' :vnodes='nodesForColor(\"g\")'></render-vnodes>" + 
  "<slot v-if='!sorted'></slot></div>",
  mounted: function(){
    if(this.setKeys) {
      this.$slots.default.forEach(function(vnode, index){
        vnode.key = index;
      });
    }
    this.$slots.default
        .filter(function(a){return !!a.children;})
        .forEach(function(vnode){
          var color = vnode.children[0].text[0].toLowerCase();
          var style = {
            backgroundColor: color === "r" ? "#DD7777" : "#77DD77",
            display: "inline-block",
            padding: "5px",
            fontFamily: "Arial"
          };
          vnode.data = vnode.data || {};
          vnode.data.style = style;
        })
    var self = this;
    this.$root.$on(this.setKeys ? "sort2" : "sort1", function(){
      self.sorted = !self.sorted;
      self.$forceUpdate();
    });
  },
  props: ["setKeys"],
  data: function(){
    return {sorted: false};
  },
  methods: {
    nodesForColor: function(color){
      var self = this;
      return this.$slots.default.slice()
        .filter(function(a){return !!a.children;})
        .filter(function(vnode){
          return vnode.children[0].text[0].toLowerCase() === color;
        });
    }
  }
});
new Vue({
  el: "#app"
});

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js