liweilong
2020-12-24 c95579f945a795138fc85a59246c97a21ce8a45e
添加时间线组件、但图片上传组件、标签组件
4个文件已添加
372 ■■■■■ 已修改文件
src/components_simple/UploadSingleImg.vue 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components_simple/demo.vue 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components_simple/jun_serveLabels.vue 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components_simple/long_timeline.vue 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components_simple/UploadSingleImg.vue
New file
@@ -0,0 +1,144 @@
<template>
  <div>
    <!-- 上传图片组件(单图) -->
    <el-upload
      ref="refUploadImg"
      :accept="accept"
      :auto-upload="false"
      list-type="picture-card"
      :class="{disabled:uploadDisabled}"
      action="#"
      :limit="1"
      :file-list="uploadImgs"
      :on-change="addUploadImg"
      :on-remove="delUploadImg"
      :http-request="uploadImg"
      :on-preview="uploadPreview"
      :before-upload="beforeUploadImg"
      size="mini"
    >
      <i class="el-icon-plus" />
    </el-upload>
    <!-- upload放大图片 -->
    <el-dialog :visible.sync="uploadPreviewVisible" append-to-body style="text-align:center">
      <img style="max-width:100%" :src="uploadPreviewUrl" alt="">
    </el-dialog>
  </div>
</template>
<script>
import mixin_upload from '@/mixins/upload.js' // 通用上传图片预览
export default {
  mixins: [mixin_upload],
  model: {
    prop: 'uploadImgs',
    event: 'change'
  },
  props: {
    uploadImgs: {
      type: Array,
      default: () => {
        return []
      }
    },
    accept: {
      type: String,
      default: () => {
        return 'image/jpeg,image/jpg,image/gif,image/png'
      }
    }
  },
  data() {
    return {
      callback: null
    }
  },
  computed: {
    uploadDisabled() {
      return this.uploadImgs.length > 0
    }
  },
  methods: {
    // 上传图片 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    // 上传前确认格式
    beforeUploadImg(file) {
      const isImg = file.type.indexOf('image/') > -1
      const isTooLarge = file.size / 1024 / 1024 > 4
      let flag = true
      if (!isImg) {
        this.$message.error('必须是选择图片文件')
        flag = false
      } else if (isTooLarge) {
        this.$message.error('请勿上传大于4MB的图片')
        flag = false
      }
      return flag
    },
    // 增加图片
    addUploadImg(file, fileList) {
      this.$emit('change', fileList)
    },
    // 删除图片
    delUploadImg(file, fileList) {
      this.$emit('change', fileList)
    },
    // 执行上传商品图
    runUploadImg(suc_cb) {
      console.log('runUploadImg!!!!!')
      if (this.checkNeedUpload(this.uploadImgs)) {
        this.callback = suc_cb
        this.$refs.refUploadImg.submit()
      } else {
        suc_cb && suc_cb()
      }
    },
    // 上传商品图
    uploadImg(res) {
      console.log(res)
      const file = res.file
      const formData = new FormData()
      formData.append('file', file)
      console.log(formData)
      this.postFN({
        url: 'admin/image/upload?folderCode=IMG',
        header: { 'Content-Type': 'multipart/form-data' },
        params: formData,
        mockData: {
          code: 100,
          msg: '',
          data: {
            imgUrl: 'xxxx'
          }
        }
      }, (inf) => {
        console.log('上传图片成功')
        // 替换掉未上传的图片
        this.$emit('change', [{ url: inf.imgUrl, status: 'success' }])
        console.log('上传图片结束')
        // 提交
        // this.$set(this.dialogData, 'imgUrl', inf.imgUrl)
        this.callback && this.callback(inf.imgUrl)
      })
    }
    // 上传图片 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
  }
}
</script>
<style>
.disabled .el-upload--picture-card {
    display: none;
}
.el-upload-list--picture-card{
  line-height: 1;
}
.el-upload-list--picture-card .el-upload-list__item{
  margin-bottom: 0
}
</style>
src/components_simple/demo.vue
New file
@@ -0,0 +1,27 @@
<template>
    <div class="">
    </div>
</template>
<script>
export default {
    name: "",
    data() {
        return {
        };
    },
    props:{
    },
    mounted() {
    },
    methods: {
    }
}
</script>
<style lang="less" scoped>
</style>
src/components_simple/jun_serveLabels.vue
New file
@@ -0,0 +1,117 @@
<!-- 服务标签 -->
<template>
  <div class="serveLabel">
    <el-tag
      v-for="tag in labelList"
      :key="tag"
      closable
      :disable-transitions="false"
      @close="labelCloseHandle(tag)"
    >
      {{ tag }}
    </el-tag>
    <el-input
      v-if="labelInputVisible"
      ref="saveTagInput"
      v-model="labelValue"
      class="input-new-tag"
      size="small"
      placeholder="输入标签,回车分隔"
      @keyup.enter.native="handleInputConfirm"
      @blur="handleInputConfirm"
    />
    <el-button v-else class="button-new-tag" size="small" @click="showInput">+ 添加{{ text||'标签' }}</el-button>
  </div>
</template>
<script>
export default {
  name: 'ServeLabels',
  model: {
    prop: 'param_labelList', // 使用 v-model
    event: 'change' // 绑定change事件
  },
  props: [
    'param_labelList', // 标签
    'text'
  ],
  data() {
    return {
      // 标签输入
      labelValue: '',
      // 是否显示标签输入框
      labelInputVisible: false,
      // 标签数组
      labelList: []
    }
  },
  watch: {
    // 监听shopId,并触发change事件
    labelList(value) {
      this.$emit('change', value)
    },
    param_labelList(value) {
      this.labelList = value
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    init() {
      this.labelList = this.param_labelList || []
    },
    // 删除标签
    labelCloseHandle(tag) {
      this.labelList.splice(this.labelList.indexOf(tag), 1)
    },
    // 显示输入框
    showInput() {
      this.labelInputVisible = true
      this.$nextTick(() => {
        this.$refs.saveTagInput.$refs.input.focus()
      })
    },
    // 输入标签完成
    handleInputConfirm() {
      const inputValue = this.labelValue
      if (this.labelList.indexOf(inputValue) > -1) {
        this.$messageError('请勿重复输入标签')
      } else {
        if (inputValue) {
          this.labelList.push(inputValue)
        }
      }
      // 隐藏输入框
      this.labelInputVisible = false
      // 清空输入内容
      this.labelValue = ''
    }
  }
}
</script>
<style>
.serveLabel .el-tag {
  margin-right: 10px;
  margin-bottom: 10px;
  font-size: 14px;
}
.button-new-tag {
  height: 32px;
  line-height: 30px;
  padding-top: 0;
  padding-bottom: 0;
  font-size: 14px !important;
}
.input-new-tag {
  width: 160px;
  vertical-align: bottom;
}
.input-new-tag .el-input__inner{
  font-size: 14px;
}
</style>
src/components_simple/long_timeline.vue
New file
@@ -0,0 +1,84 @@
<template>
  <div class="long_timeline">
    <el-timeline>
      <el-timeline-item v-if="!list || !list.length" color="#999">{{ emptyText||'暂无日志记录' }}</el-timeline-item>
      <el-timeline-item
        v-for="(item, index) in list"
        :key="index"
        color="#00AFAA"
      >
        <div class="flex flex-sb">
          <div class="content-box">
            <div class="title">{{ item.content }}</div>
            <div v-if="item.remark" class="content">{{ item.remark }}</div>
          </div>
          <div class="right-box">
            <div class="time-tx">{{ item.time }}</div>
            <div v-if="item.author" class="author-tx">操作人:{{ item.author }}</div>
          </div>
        </div>
      </el-timeline-item>
    </el-timeline>
  </div>
</template>
<script>
export default {
  name: 'LongTimeline',
  props: {
    // [{content:'xxx', time: 'xxx', author: 'xxx'}]
    list: {
      type: Array,
      default: null
    },
    // 空列表时显示
    emptyText: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
    }
  },
  mounted() {
  },
  methods: {
  }
}
</script>
<style lang="scss" scoped>
.long_timeline{
    margin-top: 37px;
}
.content-box{
    font-size: 14px;
    line-height: 1.2;
    color: #666666;
    // line-height: 34px;
    width: 70%;
    .content{
      // width: 60%;
      margin-top: 4px;
      font-size: 12px;
      color: #ccc;
    }
}
.right-box{
    margin-left: 20px;
}
.time-tx{
    font-size: 14px;
    color: #000000;
    // line-height: 34px;
    text-align: right;
}
.author-tx{
    font-size: 14px;
    color: #000000;
    // line-height: 34px;
    text-align: right;
    margin-top: 8px;
}
</style>