VUE DIV模拟input框的基本处理

关键代码

        <div class="dialog-main"
          :contenteditable= "editable"
          v-text="noticeContent"
          v-if="noDate"
          innerHTML.length = "20"
          ref="Maincontent"
          @input="handleInput"
          @compositionstart="handleStart"
          @compositionend="handleEnd"
          >

      /**
       * 限制输入长度
       * 如10个中文,英文就可以20
       */
      validateTextLength (value) {
        // 中文、中文标点、全角字符按1长度,英文、英文符号、数字按0.5长度计算
        let cnReg = /([\u4e00-\u9fa5]|[\u3000-\u303F]|[\uFF00-\uFF60])/g
        let mat = value.match(cnReg)
        let length
        if (mat) {
          length = (mat.length + (value.length - mat.length) * 0.5)
          return length
        } else {
          return value.length * 0.5
        }
      },
      /**
       * @input事件
       */
      handleInput (event) {
        let text = event.target.innerText
        this.valueHandle(event, text)
      },
      /**
       * 处理逻辑
       * strVale文本数据
       */
      valueHandle (event, strVale) {
        let _this = this
        let text = strVale
        this.sendContent = text
        if (this.composing) {
          return
        }
        let len = this.validateTextLength(text)
        if (len > 500) {
          this.$refs.Maincontent.innerHTML = text.substr(0, 500)
          this.$refs.Maincontent.focus()
        }
        setTimeout(() => {
          _this.keepLastIndex(event.target)
        }, 5)
        // 拓展 如果想要只需要前100位数据
        // this.content = this.content.substring(0, 100)
      },
      /**
       * 中文输入开始
       */
      handleStart () {
        this.composing = true
      },
      /**
       * 中文输入结束
      */
      handleEnd ($event) {
        this.composing = false
        let text = $event.target.innerHTML
        // console.log($event.target.innerHTML)
        this.valueHandle($event, text)
      },
      // 编辑
      editHandle () {
        this.editable = true
        this.noDate = true
        // let notice = this.NoticeContent
        // this.NoticeContent(false)
      },

全部代码

<template>
  <div class="del-confirm" v-if="groupNameStatus">
    <div class="group-dialog">
      <div class="dialog-content">
        <p class="win-top">
          <span class="win-txt">群公告</span>
          <span class="edit" @click="editHandle" v-if="+userId === +groupCreaterId"><icon-svg name="icon-kaka-compile" icon-style="edit-ico"></icon-svg></span>
          <span class="close-icon" @click="closeGroupNameDialog">
            <icon-svg name="icon-kaka-close" icon-style="off-ico"></icon-svg>
          </span>
        </p>
        <div class="dialog-main"
          :contenteditable= "editable"
          v-text="noticeContent"
          v-if="noDate"
          innerHTML.length = "20"
          ref="Maincontent"
          @input="handleInput"
          @compositionstart="handleStart"
          @compositionend="handleEnd"
          >
        </div>
        <!-- <div>{{groupAnnouncement}}</div> -->
        <div v-if="!noDate" class="dialog-main">暂无群公告</div>
        <div class="name-create-btn" v-if="editable">
          <div class="cancel" @click="cancelEdit">取消</div>
          <div class="sure" @click="sure">确定</div>
        </div>
        <div class="edit-tips" v-if="!editable"><p class="tips-main">只有群主才能修改公告</p></div>
      </div>
    </div>
  </div>
</template>

<script>
  import api from '@/api/group'
  export default {
    name: 'notice',
    showChatBox: {
      type: Boolean,
      default: false
    },
    data () {
      return {
        groupNameStatus: true,
        friendsInfo: this.$store.getters.friendsInfo,
        contactList: {},
        checkedContact: [],
        searchVal: '',
        groupName: '',
        userId: this.$store.getters.userId,
        noticeContent: '',
        editable: false,
        noDate: false,
        sendContent: '',
        composing: false
      }
    },
    computed: {
      // 群id
      groupId () {
        return this.$store.state.mainInit.showGroupNoticeId.groupId
      },
      // 群id
      groupCreaterId () {
        return this.$store.getters.groupSetInfo.createrId
      },
      groupAnnouncement () {
        return this.$store.getters.groupSetInfo.groupAnnouncement
      },
      NoticeContent: {
        get () {
          let groupAnnouncement = this.$store.getters.groupSetInfo.groupAnnouncement
          if (groupAnnouncement) {
            this.noDate = true
            this.noticeContent = groupAnnouncement
          }
          return groupAnnouncement
        },
        set (v) {
          // 使用vuex中的mutations中定义好的方法来改变
          let groupNotice = this.$store.state.mainInit.showGroupNoticeId
          let copyMyinfo = Object.assign({}, groupNotice)
          copyMyinfo.groupInfo.groupAnnouncement = v
          console.log(copyMyinfo)
          this.$store.dispatch('showGroupNoticeId', copyMyinfo)
        }
      }
    },
    methods: {
      /**
       * 限制输入长度
       * 如10个中文,英文就可以20
       */
      validateTextLength (value) {
        // 中文、中文标点、全角字符按1长度,英文、英文符号、数字按0.5长度计算
        let cnReg = /([\u4e00-\u9fa5]|[\u3000-\u303F]|[\uFF00-\uFF60])/g
        let mat = value.match(cnReg)
        let length
        if (mat) {
          length = (mat.length + (value.length - mat.length) * 0.5)
          return length
        } else {
          return value.length * 0.5
        }
      },
      /**
       * @input事件
       */
      handleInput (event) {
        let text = event.target.innerText
        this.valueHandle(event, text)
      },
      /**
       * 处理逻辑
       * strVale文本数据
       */
      valueHandle (event, strVale) {
        let _this = this
        let text = strVale
        this.sendContent = text
        if (this.composing) {
          return
        }
        let len = this.validateTextLength(text)
        if (len > 500) {
          this.$refs.Maincontent.innerHTML = text.substr(0, 500)
          this.$refs.Maincontent.focus()
        }
        setTimeout(() => {
          _this.keepLastIndex(event.target)
        }, 5)
        // 拓展 如果想要只需要前100位数据
        // this.content = this.content.substring(0, 100)
      },
      /**
       * 中文输入开始
       */
      handleStart () {
        this.composing = true
      },
      /**
       * 中文输入结束
      */
      handleEnd ($event) {
        this.composing = false
        let text = $event.target.innerHTML
        // console.log($event.target.innerHTML)
        this.valueHandle($event, text)
      },
      // 编辑
      editHandle () {
        this.editable = true
        this.noDate = true
        // let notice = this.NoticeContent
        // this.NoticeContent(false)
      },
      closeCreateGroupWindow () {
        this.$electron.ipcRenderer.send('closeCreateGroup')
      },
      // 取消
      cancelEdit () {
        this.editable = false
        if (this.noticeContent) {
          this.noDate = true
        } else {
          this.noDate = false
        }
      },
      // 关闭
      closeGroupNameDialog () {
        this.$store.dispatch('showGroupNotice', false)
        this.editable = false
      },
      // 确定保存
      sure () {
        // console.log(this.noticeContent) 公告接口测试修改
        let groupId = this.$store.state.mainInit.showGroupNoticeId.groupId
        let params = {
          userId: this.$store.getters.userId,
          groupId: groupId,
          groupAnnouncement: this.sendContent,
          devType: 3
        }
        api.sendAnnouncement(params).then(res => {
          console.log(res)
          if (res.code === '1') {
            this.$store.dispatch('showGroupNotice', false)
            // 保存到当前的VUEX
            let groupSetInfo = this.$store.getters.groupSetInfo
            let copyMyinfo = Object.assign({}, groupSetInfo)
            copyMyinfo.groupAnnouncement = this.sendContent
            this.$store.dispatch('groupSetInfo', copyMyinfo)
          }
          this.editable = false
          // this.$store.commit('SHOW_HANDLESUCCESS', true)
        }).catch(err => {
          console.log(err)
        })
      },
      keepLastIndex (obj) {
        if (window.getSelection) { // ie11 10 9 ff safari
          obj.focus() // 解决ff不获取焦点无法定位问题
          let range = window.getSelection() // 创建range
          range.selectAllChildren(obj) // range 选择obj下所有子内容
          range.collapseToEnd() // 光标移至最后
        } else if (document.selection) { // ie10 9 8 7 6 5
          let range = document.selection.createRange() // 创建选择对象
          // var range = document.body.createTextRange();
          range.moveToElementText(obj) // range定位到obj
          range.collapse(false) // 光标移至最后
          range.select()
        }
      },
      getNoticeData () {
        let groupAnnouncement = this.$store.getters.groupSetInfo.groupAnnouncement
        if (groupAnnouncement) {
          this.noDate = true
          this.noticeContent = groupAnnouncement
        }
      }
    },
    created () {
      // this.dealContactList()
      this.getNoticeData()
    }
  }
</script>

<style scoped lang="scss">
  .del-confirm {
    position: absolute;
    width: 100%;
    height: 100%;
    margin: auto;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color:rgba(0, 0, 0, 0);
    z-index: 999;
    .win-top {
      height: 40px;
      background-color: #F5F6F7;
      padding-left: 20px;
      border-radius: 4px;
      // @extend .drag;
      .win-txt {
        float: left;
        font-size: 14px;
        color: #252B38;
        line-height: 40px;
        // @extend .no-drag;
      }
      .edit{
        width: 15px;
        height: 14px;
        line-height: 40px;
        margin-left: 10px;
        cursor: pointer;
      }
      .close-icon {
        float: right;
        width: 30px;
        height: 30px;
        margin-top: 5px;
        margin-right: 5px;
        cursor: pointer;
        display: flex;
        align-items: center;
        justify-content: center;
        .iconsvg {
          color: #A4A4A7;
          font-size: 9px;
        }
        &:hover {
          & > .off-ico {
            color: #f45454;
          }
        }
        @extend .no-drag;
      }
    }
    .group-dialog {
      position: absolute;
      left: 0;
      right: 0;
      top: 0;
      bottom: 0;
      background: $rgba;
      z-index: 1;
      .dialog-content {
        width: 338px;
        height: 440px;
        position: absolute;
        background-color: #fff;
        left: 50%;
        top: 50%;
        margin-left: -169px;
        margin-top: -220px;
        box-shadow: 0 2px 10px 2px rgba(0, 0, 0, .19);
        border-radius: 4px;
        .dialog-main {
          height: 350px;
          padding: 20px;
          overflow: auto;
          // -webkit-user-modify: read-write-plaintext-only;
          outline: none;
          [contenteditable]:empty:not(:focus):before{
              content: attr(placeholder)
          }
          &:focus {
            outline: none;
          }
        }
      }
      .group-name {
        width: 213px;
        height: 22px;
        border: 1px solid #E2E6E9;
        font-size: 12px;
        color: #232936;
        padding: 0 7px;
        display: block;
        margin: 22px auto 35px;
        &:focus {
          outline: none;
        }
      }
      .name-create-btn {
        text-align: center;
        // height: 30px;
        font-size: 0;
        .cancel {
          display: inline-block;
          width: 68px;
          height: 30px;
          line-height: 30px;
          text-align: center;
          border-radius: 4px;
          font-size: 12px;
          cursor: pointer;
          background-color: #ffffff;
          border: 1px solid #999;
          color: #333;
          margin-right: 15px;
        }
        .sure{
          display: inline-block;
          margin-left: 15px;
          width: 68px;
          height: 30px;
          line-height: 30px;
          text-align: center;
          border-radius: 4px;
          font-size: 12px;
          cursor: pointer;
          background-color: $btn-confim;
          color: #fff;
          border: 1px solid $btn-confim;
        }
      }
      .edit-tips {
        text-align: center;
        height: 30px;
        line-height: 30px;
        .tips-main{
          font-size:10px;
          color:rgba(162,164,168,1);
          position: relative;
          &::after,&::before {
            content: '';
            width: 20px;
            height: 1px;
            background:rgba(216,216,216,1);
            border-radius: 1px;
            position: absolute;
          }
          &::after {
            left: 90px;
            top: 15px;
          }
          &::before {
            right: 90px;
            top: 15px;
          }
        }
      }
    }
  }
</style>


posted @ 2019-04-18 15:26  山村码农  阅读(5048)  评论(1编辑  收藏  举报