跟随Element学习Vue小技巧(23)——Transfer

1,316 阅读4分钟

历史虽然会一再重演

但人类却无法回到过去

前言

宇宙的起点在哪里?时间的终点在哪里?
如果穿越人海,能否赶到时间的尽头?

  • 今天给你介绍的怎么样?
  • 嗯,不行吧
  • 这都是这个月第几个了?
  • 3...
  • 你还记得是第三个
  • 如果是3的话,说不定可以
  • 什么可以?
  • 可以穿越呀
  • 穿越?啥?哎,这孩子没救了,介绍了这么多个,穿越人海,只为与理相拥 假如一天,真的可以穿越,你会对过去的自己说点什么呢?
    嗖嗖嗖...
    再不充钱,又得涨价啦 O(∩_∩)O哈哈~

1 Transfer

reduce

  • 1+2等于几?
  • 再加3呢?
  • 3 + 3 = 6
  • 再加4呢
  • 6 + 4 = 10
  • 再加...

[1] + [2] + [3]呢?
{a} + {b} + {c}呢?
的确,reduce貌似只能做加法?但是你真的会做加法吗?
1 + 1到底等于几呢?
2,今天就算是天王老子来了,也等于2

代码片段

// [{key: 'a'}, {key: 'b'}] 
// =>{a: {key: 'a'}, b: {key: 'b'}}
dataObj() {
  const key = this.props.key;
  return this.data.reduce((o, cur) => (o[cur[key]] = cur) && o, {});
},
targetData() {
  if (this.targetOrder === 'original') {
    ...
  } else {
  // ['a', 'b', 'c'], {a: 'a', b: 'b'} 
  // =>['a', 'b']
    return this.value.reduce((arr, cur) => {
      const val = this.dataObj[cur];
      if (val) {
        arr.push(val);
      }
      return arr;
    }, []);
  }
},

技巧解析

数组转对象,{}=>{a}=>{a, b}
数组过滤,[]=>['a']=>['a', 'b']
更多好玩的攻略,传送门发给你

数组处理的神兵利器-reduce 传送门
js扁平化树形结构 传送门

2 TransferPanel

checkAll

小明在路边捡到一神灯,擦了擦跑出个灯神

  • 我可以实现你三个愿望
  • 什么愿望都行吗?
  • 为了感谢你救我出来,什么愿望我都帮你实现
  • 我想要好多好多钱
  • 没问题
  • 我想要一个非常非常漂亮的老婆
  • 满足你
  • 我,我,...
  • 还有最后一个愿望
  • 我还想要,想要,...想要另外3个愿望 够贪心,贪心是人类搏杀的原动力!!

代码片段

handleAllCheckedChange(value) {
  this.checked = value
    ? this.checkableData.map(item => item[this.keyProp])
    : [];
},
watch: {
  checked(val, oldVal) {
    this.updateAllChecked();
    if (this.checkChangeByUser) {
      const movedKeys = val.concat(oldVal)
        .filter(v => val.indexOf(v) === -1 || oldVal.indexOf(v) === -1);
      this.$emit('checked-change'val, movedKeys);
    } else {
      this.$emit('checked-change'val);
      this.checkChangeByUser = true;
    }
  },
}

// methods
updateAllChecked() {
  const checkableDataKeys = this.checkableData.map(item => item[this.keyProp]);
  this.allChecked = checkableDataKeys.length > 0 &&
    checkableDataKeys.every(item => this.checked.indexOf(item) > -1);
},

技巧解析

全选handleAllCheckedChange: checked清空或填满
选择updateAllChecked: allChecked选上或不选

选择太多,往往不知所措;没有选择的选择反而会更专注

render

发光并非太阳的专利,星星之火也可以燎原
render只能在模板渲染中使用吗?也不一定
还记得女娲造的那些小泥人吗?
$createElement可以创建DOM, render也是可以的,不过是披上了JSX的外衣,换了个发型而已

代码片段

<template>
 <el-transfer
  ...
  :render-content="renderFunc"
  ...
  :data="data">
  <el-button class="transfer-footer" slot="left-footer" size="small">操作</el-button>
  <el-button class="transfer-footer" slot="right-footer" size="small">操作</el-button>
</el-transfer>
</template>
<script>
  export default {
    data() {
      ...
      return {
        ...
        renderFunc(h, option) {
          return <span>{ option.key } - { option.label }</span>;
        }
      };
    },
    ...
  };
</script>
render(h) {
  ...
  return panel.renderContent
    ? panel.renderContent(h, this.option)
    : transfer.$scopedSlots.default
      ? transfer.$scopedSlots.default({ option: this.option })
      : <span>{ this.option[panel.labelProp] || this.option[panel.keyProp] }</span>;
}

技巧解析

renderFunc,回调参数h,不认识?不过是换了个发型,本质上仍然是createElement
panel.renderContent嘀咕着,我需要一个渲染函数,如果有,把option和h给你
看吧,有礼物,有惊喜 ^^
想到了什么?
作用域插槽,模板props



无论好坏 都是一种邂逅

参考链接

往期回顾