index.vue 4.29 KB
<template>
  <!--
    属性:
      data: 数据[{ id: 1, name: '班主任', removeIcon: false //是否显示删除图标(默认显示) },{ id: 2, name: '任课老师' }],
      title: 组件标题,
      active-color: 选中时文字颜色,
      title-bg: 组件标题背景颜色,
      acitve-index: 默认选中序号
    事件:
      clicklist: 列的点击事件,返回index
      removelist: 列的删除事件,传入id
-->
  <div class="list-box">
    <div class="list-title" :style="'background:'+titleBg">{{ title }}</div>
    <div class="list-content">
      <li
        v-for="(value,index) in data"
        :key="index"
        :class="{'hoveractive':index==hoverIndex}"
        @mousemove="hoverIndex = index"
        @mouseout="hoverIndex = -1"
      >
        <p
          v-myfocus
          :class="{'clickhover':index == activeIndex}"
          :style="index == activeIndex?'color:'+activeColor:''"
          style="float:left;width:80%;margin:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;"
          :contenteditable="value.edit"
          @click.self="clickList(index)"
        >{{ value.name }}</p>
        <el-button
          v-if="!value.edit"
          v-show="value.removeIcon==undefined?true:value.removeIcon"
          type="danger"
          class="removeBtn"
          size="small"
          icon="el-icon-delete"
          circle
          @click.capture="removeList(index)"
        />
        <el-button
          v-if="value.edit"
          v-show="value.removeIcon==undefined?true:value.removeIcon"
          type="success"
          class="editBtn"
          size="small"
          icon="el-icon-check"
          circle
          @click.capture="submitname(index)"
        />
        <div style="clear:both" />
      </li>
    </div>
  </div>
</template>
<script>
import Vue from 'vue'
export default {
  name: 'ListBox',
  props: // ['data', 'title', 'activeColor', 'titleBg', 'acitveIndex'],
  {
    data: {
      type: Array,
      default: function() {
        return []
      }
    },
    title: {
      type: String,
      default: ''
    },
    activeColor: {
      type: String,
      default: ''
    },
    titleBg: {
      type: String,
      default: ''
    },
    acitveIndex: {
      type: Number,
      default: 0
    }
  },
  data() {
    return {
      hoverIndex: -1, // 菜单hover索引
      activeIndex: 0
    }
  },
  created() {
    this.activeLinkId = this.data[this.acitveIndex].id
  },
  methods: {
    clickList(index) {
      this.activeIndex = index
      this.$emit('clicklist', index)
    },
    removeList(index) {
      this.$emit('removelist', index)
    },
    addList(name) {
      this.data.push({
        name,
        edit: true
      })
    },
    submitname(index) {
      this.$emit('submitname', index)
    }
  }
}
Vue.directive('myfocus', {
  inserted: function(el, binding) {
    if (window.getSelection) {
      // ie11 10 9 ff safari
      el.focus() // 解决ff不获取焦点无法定位问题
      var range = window.getSelection() // 创建range
      range.selectAllChildren(el) // range 选择obj下所有子内容
      range.collapseToEnd() // 光标移至最后
    } else if (document.selection) {
      // ie10 9 8 7 6 5
      // eslint-disable-next-line no-redeclare
      var range = document.selection.createRange() // 创建选择对象
      range.moveToElementText(el) // range定位到obj
      range.collapse(false) // 光标移至最后
      range.select()
    }
  }
})
</script>
<style lang="scss" scoped>
    .list-box{
        width:100%;
        height:100%;
        .list-title{
            line-height: 50px;
            text-align: center
        }
        .list-content{
            height: calc(100% - 50px);
            overflow-y: auto;
            padding-bottom: 10px;
            li{
                list-style: none;
                line-height: 40px;
                padding:0 10px;
                cursor: pointer;
            }
            li:hover{
                background: #eee;
            }
            .removeBtn{
                display: none;
                float: right;
                margin-top:4px;
            }
            .editBtn{
                float: right;
                margin-top:4px;
            }
            .hoveractive .removeBtn{
                display: inline;
            }
        }
    }
</style>