欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue3??mark.js?實(shí)現(xiàn)文字標(biāo)注功能(案例代碼)

 更新時(shí)間:2023年09月27日 09:36:35   作者:楊芋可可  
這篇文章主要介紹了vue3??mark.js?實(shí)現(xiàn)文字標(biāo)注功能,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

頁面效果

具體實(shí)現(xiàn)

新增

1、監(jiān)聽鼠標(biāo)抬起事件,通過 window.getSelection() 方法獲取鼠標(biāo)用戶選擇的文本范圍或光標(biāo)的當(dāng)前位置。

2、通過 選中的文字長(zhǎng)度是否大于0 window.getSelection().isCollapsed (返回一個(gè)布爾值用于描述選區(qū)的起始點(diǎn)和終止點(diǎn)是否位于一個(gè)位置,即是否框選了)來判斷是否展示標(biāo)簽選擇的彈窗。

3、標(biāo)簽選擇的彈窗采用 子絕父相 的定位方式,通過鼠標(biāo)抬起的位置確認(rèn)彈窗的 top left 值。

    const TAG_WIDTH = 280 //自定義最大范圍,以保證不超過內(nèi)容的最大寬度
    const tagInfo = ref({
     visible: false,
     top: 0,
     left: 0,
    })
    const el = document.getElementById('text-container')
    //鼠標(biāo)抬起
    el?.addEventListener('mouseup', (e) => {
      const text = window?.getSelection()?.toString() || ''
      if (text.length > 0) {
        const left = e.offsetX < TAG_WIDTH ? 0 : e.offsetX - 300
        tagInfo.value = {
          visible: true,
          top: e.offsetY + 40,
          left: left,
        }
        getSelectedTextData()
      } else {
        tagInfo.value.visible = false
      }
      //清空重選/取消數(shù)據(jù)
      resetEditTag()
 const selectedText = reactive({
    start: 0,
    end: 0,
    content: '',
  })
  //獲取選取的文字?jǐn)?shù)據(jù)
  const getSelectedTextData = () => {
    const select = window?.getSelection() as any
    console.log('selectselectselectselect', select)
    const nodeValue = select.focusNode?.nodeValue
    const anchorOffset = select.anchorOffset
    const focusOffset = select.focusOffset
    const nodeValueSatrtIndex = markContent.value?.indexOf(nodeValue)
    selectedText.content = select.toString()
    if (anchorOffset < focusOffset) {
      //從左到右標(biāo)注
      selectedText.start = nodeValueSatrtIndex + anchorOffset
      selectedText.end = nodeValueSatrtIndex + focusOffset
    } else {
      //從右到左
      selectedText.start = nodeValueSatrtIndex + focusOffset
      selectedText.end = nodeValueSatrtIndex + anchorOffset
    }
  }

javascript操作光標(biāo)和選區(qū)詳情可參考文檔:http://www.dbjr.com.cn/article/94012.htm

  • 4、選中標(biāo)簽后,采用markjs的 markRanges() 方式去創(chuàng)建一個(gè)選中的元素并為其添加樣式和綁定事件。
  • 5、定義一個(gè)響應(yīng)式的文字列表,專門記錄標(biāo)記的內(nèi)容,添加完元素后可追加一條已標(biāo)記的數(shù)據(jù)。
import Mark from 'mark.js'
import {ref} from 'vue
import { nanoid } from 'nanoid'
const selectedTextList = ref([])
const handleSelectLabel = (t) => {
  const marker = new Mark(document.getElementById('text-container'))
  const { tag_color, tag_name, tag_id } = t
  const markId = nanoid(10)
  marker.markRanges(
      [
        {
          start: selectedText.start, //必填
          length: selectedText.content.length, //必填
        },
      ],
      {
        className: 'text-selected',
        element: 'span',
        each: (element: any) => {
          //為元素添加樣式和屬性
          element.setAttribute('id', markId)
          element.style.borderBottom = `2px solid ${t.tag_color}` //添加下劃線
          element.style.color = t.tag_color
          //綁定事件
          element.onclick = function (e: any) {
            //
          }
        },
      }
    )
    selectedTextList.value.push({
      tag_color,
      tag_name,
      tag_id,
      start: selectedText.start,
      end: selectedText.end,
      mark_content:selectedText.content,
      mark_id: markId,
    })
}

刪除

image.png

點(diǎn)擊已進(jìn)行標(biāo)記的文字————>重選/取消彈窗顯示————>點(diǎn)擊取消

如何判斷點(diǎn)擊的文字是否已標(biāo)記,通過在創(chuàng)建的標(biāo)記元素中綁定點(diǎn)擊事件,觸發(fā)則表示已標(biāo)記。

在點(diǎn)擊事件中記錄該標(biāo)記的相關(guān)內(nèi)容,如顏色,文字,起始位置,以及唯一標(biāo)識(shí)id(新建時(shí)給元素添加一個(gè)id屬性,點(diǎn)擊時(shí)即可通過 e.target.id 獲取)

  import { nanoid } from 'nanoid'
      //選擇標(biāo)簽后
      const markId = nanoid(10)
      marker.markRanges(
      [
        {
          start: isReset ? editTag.value.start : selectedText.start,
          length: isReset ? editTag.value.content.length : selectedText.content.length,
        },
      ],
      {
        className: 'text-selected',
        element: 'span',
        each: (element: any) => {
          element.setAttribute('id', markId)
          //綁定事件
          element.onclick = function (e: any) {
            e.preventDefault()
            if (!e.target.id) return
            const left = e.offsetX < TAG_WIDTH ? 0 : e.offsetX - 300
            const item = selectedTextList.value?.find?.((t) => t.mark_id == e.target.id) as any
            const { mark_content, tag_id, start, end } = item || {}
            editTag.value = {
              visible: true,
              top: e.offsetY + 40,
              left: e.offsetX,
              mark_id: e.target.id,
              content: mark_content || '',
              tag_id: tag_id || '',
              start: start,
              end: end,
            }
            tagInfo.value = {
              visible: false,
              top: e.offsetY + 40,
              left: left,
            }
          }
        },
      }
    )

3.點(diǎn)擊取消后,獲取在此前記錄的id,根據(jù)id查詢相關(guān)的標(biāo)記元素

  • 使用 markjs.unmark() 方法即可刪除此元素。
  • 綁定的響應(yīng)式數(shù)據(jù),可使用 findIndex splice() 刪除編輯彈窗隱藏
const handleCancel = () => {
    if (!editTag.value.mark_id) return
    const markEl = new Mark(document.getElementById(editTag.value.mark_id))
    markEl.unmark()
    selectedTextList.value.splice(
      selectedTextList.value?.findIndex((t) => t.mark_id == editTag.value.mark_id),
      1
    )
    tagInfo.value = {
      visible: false,
      top: 0,
      left: 0,
    }
    resetEditTag()
  }
const resetEditTag = () => {
    editTag.value = {
      visible: false,
      top: 0,
      left: 0,
      mark_id: '',
      content: '',
      tag_id: '',
      start: 0,
      end: 0,
    }
  }

重選

image.png

和取消的步驟一樣,只不過在點(diǎn)擊重選后,先彈出標(biāo)簽彈窗,選擇標(biāo)簽后,需要先刪除選中的元素,然后再新增一個(gè)標(biāo)記元素。由于在標(biāo)簽選擇,在標(biāo)簽選擇中判斷一下是否是重選,是重選的話就需刪除后再創(chuàng)建元素,不是的話就代表是新增,直接新增標(biāo)記元素(綜上所述)。

 const handleSelectLabel = (t: TTag) => {
    tagInfo.value.visible = false
    const { tag_color, tag_name, tag_id } = t
    const marker = new Mark(document.getElementById('text-container'))
    const markId = nanoid(10)
    const isReset = selectedTextList.value?.map((j) => j.mark_id).includes(editTag.value.mark_id)
      ? 1
      : 0 // 1:重選 0:新增
    if (isReset) {
      //如若重選,則刪除后再新增標(biāo)簽
      const markEl = new Mark(document.getElementById(editTag.value.mark_id))
      markEl.unmark()
      selectedTextList.value.splice(
        selectedTextList.value?.findIndex((t) => t.mark_id == editTag.value.mark_id),
        1
      )
    }
    marker.markRanges(
      [
        {
          start: isReset ? editTag.value.start : selectedText.start,
          length: isReset ? editTag.value.content.length : selectedText.content.length,
        },
      ],
      {
        className: 'text-selected',
        element: 'span',
        each: (element: any) => {
          element.setAttribute('id', markId)
          element.style.borderBottom = `2px solid ${t.tag_color}`
          element.style.color = t.tag_color
          element.style.userSelect = 'none'
          element.style.paddingBottom = '6px'
          element.onclick = function (e: any) {
            e.preventDefault()
            if (!e.target.id) return
            const left = e.offsetX < TAG_WIDTH ? 0 : e.offsetX - 300
            const item = selectedTextList.value?.find?.((t) => t.mark_id == e.target.id) as any
            const { mark_content, tag_id, start, end } = item || {}
            editTag.value = {
              visible: true,
              top: e.offsetY + 40,
              left: e.offsetX,
              mark_id: e.target.id,
              content: mark_content || '',
              tag_id: tag_id || '',
              start: start,
              end: end,
            }
            tagInfo.value = {
              visible: false,
              top: e.offsetY + 40,
              left: left,
            }
          }
        },
      }
    )
    selectedTextList.value.push({
      tag_color,
      tag_name,
      tag_id,
      start: isReset ? editTag.value.start : selectedText.start,
      end: isReset ? editTag.value.end : selectedText.end,
      mark_content: isReset ? editTag.value.content : selectedText.content,
      mark_id: markId,
    })
  }

清空標(biāo)記

image.png

const handleAllDelete = () => {
    selectedTextList.value = []
    const marker = new Mark(document.getElementById('text-container'))
    marker.unmark()
  }

完整代碼

<script setup lang="ts">
  import { ref, onMounted, reactive } from 'vue'
  import Mark from 'mark.js'
  import { nanoid } from 'nanoid'
  type TTag = {
    tag_name: string
    tag_id: string
    tag_color: string
  }
  type TSelectText = {
    tag_id: string
    tag_name: string
    tag_color: string
    start: number
    end: number
    mark_content: string
    mark_id: string
  }
  const TAG_WIDTH = 280
  const selectedTextList = ref<TSelectText[]>([])
  const selectedText = reactive({
    start: 0,
    end: 0,
    content: '',
  })
  const markContent = ref(
    '這是標(biāo)注的內(nèi)容有業(yè)績(jī)還是我我很快就很快就開完如突然好幾個(gè)地方各級(jí)很大功夫數(shù)據(jù)庫(kù)二極管捍衛(wèi)國(guó)家和我回家很晚十九世紀(jì)俄國(guó)激活工具和丈母娘環(huán)境和顛覆國(guó)家的高房?jī)r(jià)奧蘇愛哦因?yàn)閕以太網(wǎng)圖的還是覺得好看啊空間函數(shù)調(diào)用加快速度還是饑渴的發(fā)貨可是磕碰日俄和那那么會(huì)就開始開會(huì)的數(shù)據(jù)庫(kù)和也會(huì)覺得講故事的而黃金九二額呵呵三角函數(shù)的吧合乎實(shí)際的和盡快核實(shí)當(dāng)升科技看交互的接口和送二ui為人開朗少女都被你們進(jìn)貨金額麥當(dāng)娜表面上的'
  )
  const tagInfo = ref({
    visible: false,
    top: 0,
    left: 0,
  })
  const editTag = ref({
    visible: false,
    top: 0,
    left: 0,
    mark_id: '',
    content: '',
    tag_id: '',
    start: 0,
    end: 0,
  })
  const tagList: TTag[] = [
    {
      tag_name: '標(biāo)簽一',
      tag_color: `#DE050CFF`,
      tag_id: 'tag_id1',
    },
    {
      tag_name: '標(biāo)簽二',
      tag_color: `#6ADE05FF`,
      tag_id: 'tag_id2',
    },
    {
      tag_name: '標(biāo)簽三',
      tag_color: `#DE058BFF`,
      tag_id: 'tag_id3',
    },
    {
      tag_name: '標(biāo)簽四',
      tag_color: `#9205DEFF`,
      tag_id: 'tag_id4',
    },
    {
      tag_name: '標(biāo)簽五',
      tag_color: `#DE5F05FF`,
      tag_id: 'tag_id5',
    },
  ]
  const handleAllDelete = () => {
    selectedTextList.value = []
    const marker = new Mark(document.getElementById('text-container'))
    marker.unmark()
  }
  const handleCancel = () => {
    if (!editTag.value.mark_id) return
    const markEl = new Mark(document.getElementById(editTag.value.mark_id))
    markEl.unmark()
    selectedTextList.value.splice(
      selectedTextList.value?.findIndex((t) => t.mark_id == editTag.value.mark_id),
      1
    )
    tagInfo.value = {
      visible: false,
      top: 0,
      left: 0,
    }
    resetEditTag()
  }
  const handleReset = () => {
    editTag.value.visible = false
    tagInfo.value.visible = true
  }
  const handleSave = () => {
    console.log('標(biāo)注的數(shù)據(jù)', selectedTextList.value)
  }
  const handleSelectLabel = (t: TTag) => {
    const { tag_color, tag_name, tag_id } = t
    tagInfo.value.visible = false
    const marker = new Mark(document.getElementById('text-container'))
    const markId = nanoid(10)
    const isReset = selectedTextList.value?.map((j) => j.mark_id).includes(editTag.value.mark_id)
      ? 1
      : 0 // 1:重選 0:新增
    if (isReset) {
      //如若重選,則刪除后再新增標(biāo)簽
      const markEl = new Mark(document.getElementById(editTag.value.mark_id))
      markEl.unmark()
      selectedTextList.value.splice(
        selectedTextList.value?.findIndex((t) => t.mark_id == editTag.value.mark_id),
        1
      )
    }
    marker.markRanges(
      [
        {
          start: isReset ? editTag.value.start : selectedText.start,
          length: isReset ? editTag.value.content.length : selectedText.content.length,
        },
      ],
      {
        className: 'text-selected',
        element: 'span',
        each: (element: any) => {
          element.setAttribute('id', markId)
          element.style.borderBottom = `2px solid ${t.tag_color}`
          element.style.color = t.tag_color
          element.style.userSelect = 'none'
          element.style.paddingBottom = '6px'
          element.onclick = function (e: any) {
            e.preventDefault()
            if (!e.target.id) return
            const left = e.offsetX < TAG_WIDTH ? 0 : e.offsetX - 300
            const item = selectedTextList.value?.find?.((t) => t.mark_id == e.target.id) as any
            const { mark_content, tag_id, start, end } = item || {}
            editTag.value = {
              visible: true,
              top: e.offsetY + 40,
              left: e.offsetX,
              mark_id: e.target.id,
              content: mark_content || '',
              tag_id: tag_id || '',
              start: start,
              end: end,
            }
            tagInfo.value = {
              visible: false,
              top: e.offsetY + 40,
              left: left,
            }
          }
        },
      }
    )
    selectedTextList.value.push({
      tag_color,
      tag_name,
      tag_id,
      start: isReset ? editTag.value.start : selectedText.start,
      end: isReset ? editTag.value.end : selectedText.end,
      mark_content: isReset ? editTag.value.content : selectedText.content,
      mark_id: markId,
    })
  }
  /**
   * 獲取選取的文字?jǐn)?shù)據(jù)
   */
  const getSelectedTextData = () => {
    const select = window?.getSelection() as any
    const nodeValue = select.focusNode?.nodeValue
    const anchorOffset = select.anchorOffset
    const focusOffset = select.focusOffset
    const nodeValueSatrtIndex = markContent.value?.indexOf(nodeValue)
    selectedText.content = select.toString()
    if (anchorOffset < focusOffset) {
      //從左到右標(biāo)注
      selectedText.start = nodeValueSatrtIndex + anchorOffset
      selectedText.end = nodeValueSatrtIndex + focusOffset
    } else {
      //從右到左
      selectedText.start = nodeValueSatrtIndex + focusOffset
      selectedText.end = nodeValueSatrtIndex + anchorOffset
    }
  }
  const resetEditTag = () => {
    editTag.value = {
      visible: false,
      top: 0,
      left: 0,
      mark_id: '',
      content: '',
      tag_id: '',
      start: 0,
      end: 0,
    }
  }
  const drawMark = () => {
    //模擬后端返回的數(shù)據(jù)
    const res = [
      {
        start: 2, //必備
        end: 6,
        tag_color: '#DE050CFF',
        tag_id: 'tag_id1',
        tag_name: '標(biāo)簽一',
        mark_content: '標(biāo)注的內(nèi)容',
        mark_id: 'mark_id1',
      },
      {
        start: 39,
        end: 41,
        tag_color: '#6ADE05FF',
        tag_id: 'tag_id2',
        tag_name: '標(biāo)簽二',
        mark_content: '二極管',
        mark_id: 'mark_id2',
      },
      {
        start: 58,
        end: 61,
        tag_color: '#DE058BFF',
        tag_id: 'tag_id3',
        tag_name: '標(biāo)簽三',
        mark_content: '激活工具',
        mark_id: 'mark_id3',
      },
    ]
    selectedTextList.value = res?.map((t) => ({
      tag_id: t.tag_id,
      tag_name: t.tag_name,
      tag_color: t.tag_color,
      start: t.start,
      end: t.end,
      mark_content: t.mark_content,
      mark_id: t.mark_id,
    }))
    const markList =
      selectedTextList.value?.map((j) => ({
        ...j,
        start: j.start, //必備
        length: j.end - j.start + 1, //必備
      })) || []
    const marker = new Mark(document.getElementById('text-container'))
    markList?.forEach?.(function (m: any) {
      marker.markRanges([m], {
        element: 'span',
        className: 'text-selected',
        each: (element: any) => {
          element.setAttribute('id', m.mark_id)
          element.style.borderBottom = `2px solid ${m.tag_color}`
          element.style.color = m.tag_color
          element.style.userSelect = 'none'
          element.style.paddingBottom = '6px'
          element.onclick = function (e: any) {
            console.log('cccccc', m)
            const left = e.offsetX < TAG_WIDTH ? 0 : e.offsetX - 300
            editTag.value = {
              visible: true,
              top: e.offsetY + 40,
              left: e.offsetX,
              mark_id: m.mark_id,
              content: m.mark_content,
              tag_id: m.tag_id,
              start: m.start,
              end: m.end,
            }
            tagInfo.value = {
              visible: false,
              top: e.offsetY + 40,
              left: left,
            }
          }
        },
      })
    })
  }
  //頁面初始化
  onMounted(() => {
    const el = document.getElementById('text-container')
    //鼠標(biāo)抬起
    el?.addEventListener('mouseup', (e) => {
      const text = window?.getSelection()?.toString() || ''
      if (text.length > 0) {
        const left = e.offsetX < TAG_WIDTH ? 0 : e.offsetX - 300
        tagInfo.value = {
          visible: true,
          top: e.offsetY + 40,
          left: left,
        }
        getSelectedTextData()
      } else {
        tagInfo.value.visible = false
      }
      //清空重選/取消數(shù)據(jù)
      resetEditTag()
    })
    //從后端獲取標(biāo)注數(shù)據(jù),進(jìn)行初始化標(biāo)注
    drawMark()
  })
</script>
<template>
  <header>
    <n-button
      type="primary"
      :disabled="selectedTextList.length == 0 ? true : false"
      ghost
      @click="handleAllDelete"
    >
      清空標(biāo)記
    </n-button>
    <n-button
      type="primary"
      :disabled="selectedTextList.length == 0 ? true : false"
      @click="handleSave"
    >
      保存
    </n-button>
  </header>
  <main>
    <div id="text-container" class="text">
      {{ markContent }}
    </div>
    <!-- 標(biāo)簽選擇 -->
    <div
      v-if="tagInfo.visible && tagList.length > 0"
      :class="['tag-box p-4 ']"
      :style="{ top: tagInfo.top + 'px', left: tagInfo.left + 'px' }"
    >
      <div v-for="i in tagList" :key="i.tag_id" class="tag-name" @click="handleSelectLabel(i)">
        <n-space>
          <p>{{ i.tag_name }}</p>
          <n-button v-if="i.tag_id == editTag.tag_id" text type="primary">√</n-button>
        </n-space>
        <div
          :class="['w-4 h-4']"
          :style="{
            background: i.tag_color,
          }"
        ></div>
      </div>
    </div>
    <!-- 重選/取消 -->
    <div
      v-if="editTag.visible"
      class="edit-tag"
      :style="{ top: editTag.top + 'px', left: editTag.left + 'px' }"
    >
      <div class="py-1 bg-gray-100 text-center" @click="handleCancel">取 消</div>
      <div class="py-1 bg-gray-100 mt-2 text-center" @click="handleReset">重 選</div>
    </div>
  </main>
</template>
<style lang="less" scoped>
  header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0 24px;
    height: 80px;
    border-bottom: 1px solid #e5e7eb;
    user-select: none;
    background: #fff;
  }
  main {
    background: #fff;
    margin: 24px;
    height: 80vh;
    padding: 24px;
    overflow-y: auto;
    position: relative;
    box-shadow: 0 3px 8px 0 rgb(0 0 0 / 13%);
    .text {
      color: #333;
      font-weight: 500;
      font-size: 16px;
      line-height: 50px;
    }
    .tag-box {
      position: absolute;
      z-index: 10;
      width: 280px;
      max-height: 40vh;
      overflow-y: auto;
      background: #fff;
      border-radius: 4px;
      box-shadow: 0 9px 28px 8px rgb(0 0 0 / 3%), 0 6px 16px 4px rgb(0 0 0 / 9%),
        0 3px 6px -2px rgb(0 0 0 / 20%);
      user-select: none;
      .tag-name {
        width: 100%;
        background: rgba(243, 244, 246, var(--tw-bg-opacity));
        font-size: 14px;
        cursor: pointer;
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 4px 8px;
        margin-top: 8px;
      }
      .tag-name:nth-of-type(1) {
        margin-top: 0;
      }
    }
    .edit-tag {
      position: absolute;
      z-index: 20;
      padding: 16px;
      cursor: pointer;
      width: 100px;
      background: #fff;
      border-radius: 4px;
      box-shadow: 0 9px 28px 8px rgb(0 0 0 / 3%), 0 6px 16px 4px rgb(0 0 0 / 9%),
        0 3px 6px -2px rgb(0 0 0 / 20%);
      user-select: none;
    }
    ::selection {
      background: rgb(51 51 51 / 20%);
    }
  }
</style>

結(jié)束語

目前功能實(shí)現(xiàn)比較簡(jiǎn)單,還有很多發(fā)揮的空間,先小小的記錄一下,最后~,預(yù)祝大家,雙節(jié)快樂??!

markjs

到此這篇關(guān)于vue3  mark.js 實(shí)現(xiàn)文字標(biāo)注功能的文章就介紹到這了,更多相關(guān)vue3  mark.js文字標(biāo)注內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue上傳組件vue Simple Uploader的用法示例

    Vue上傳組件vue Simple Uploader的用法示例

    本篇文章主要介紹了Vue上傳組件vue Simple Uploader的用法示例,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2017-08-08
  • vue封裝組件之上傳圖片組件

    vue封裝組件之上傳圖片組件

    這篇文章主要為大家詳細(xì)介紹了vue封裝組件之上傳圖片組件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • vuex直接修改state、commit和dispatch修改state的用法及區(qū)別說明

    vuex直接修改state、commit和dispatch修改state的用法及區(qū)別說明

    這篇文章主要介紹了vuex直接修改state、commit和dispatch修改state的用法及區(qū)別說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • 詳細(xì)講一講vue3下會(huì)造成響應(yīng)式丟失的情況

    詳細(xì)講一講vue3下會(huì)造成響應(yīng)式丟失的情況

    vue3開發(fā)過程中,綁定的響應(yīng)式數(shù)據(jù)失去了響應(yīng)式,如何解決問題呢,下面這篇文章主要給大家介紹了關(guān)于vue3下會(huì)造成響應(yīng)式丟失的情況,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • vue項(xiàng)目檢測(cè)依賴包是否有使用的問題

    vue項(xiàng)目檢測(cè)依賴包是否有使用的問題

    這篇文章主要介紹了vue項(xiàng)目檢測(cè)依賴包是否有使用的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • 一文詳解Vue中nextTick的原理與作用

    一文詳解Vue中nextTick的原理與作用

    Vue的nextTick方法是用于在DOM更新后執(zhí)行回調(diào)的工具函數(shù),它的作用是在當(dāng)前JavaScript執(zhí)行環(huán)境中延遲執(zhí)行回調(diào),以確保在下次DOM更新循環(huán)之前,可以訪問到更新后的DOM,本文就給大家介紹一下Vue nextTick原理與作用,需要的朋友可以參考下
    2023-08-08
  • 全面總結(jié)Vue3.0的多種偵聽方式

    全面總結(jié)Vue3.0的多種偵聽方式

    Vue提供了一種更通用的方式來觀察和響應(yīng)當(dāng)前活動(dòng)的實(shí)例上的數(shù)據(jù)變動(dòng):偵聽屬性,下面這篇文章主要給大家介紹了關(guān)于Vue3.0多種偵聽方式的相關(guān)資料,需要的朋友可以參考下
    2021-10-10
  • vue項(xiàng)目打包時(shí)自動(dòng)更新版本號(hào)的實(shí)現(xiàn)方法

    vue項(xiàng)目打包時(shí)自動(dòng)更新版本號(hào)的實(shí)現(xiàn)方法

    本文主要介紹了vue項(xiàng)目打包時(shí)自動(dòng)更新版本號(hào)的實(shí)現(xiàn)方法,通過在根目錄下創(chuàng)建autoVersion.js腳本文件,頁面獲取版本號(hào)時(shí)直接使用,修改package.json配置,感興趣的可以了解一下
    2025-02-02
  • Vue.Draggable實(shí)現(xiàn)交換位置

    Vue.Draggable實(shí)現(xiàn)交換位置

    這篇文章主要為大家詳細(xì)介紹了Vue.Draggable實(shí)現(xiàn)交換位置,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • vue實(shí)現(xiàn)點(diǎn)擊按鈕“查看詳情”彈窗展示詳情列表操作

    vue實(shí)現(xiàn)點(diǎn)擊按鈕“查看詳情”彈窗展示詳情列表操作

    這篇文章主要介紹了vue實(shí)現(xiàn)點(diǎn)擊按鈕“查看詳情”彈窗展示詳情列表操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09

最新評(píng)論