vue3uniapps使用富文本mp-html插件

1. 实现效果

具体需求:顶部是搜索栏,包括搜索结果个数,目前跳到第几个,包含上一个、下一个按钮。富文本区域关键词高亮黄色,当前关键词为高亮橙色。如图

2. 版本号

用到vue3 和 uniapp , mp-html 插件版本是v2.5.0,

插件地址:https://ext.dcloud.net.cn/plugin?id=805

用npm方式打包放到compenonts文件,如图,打包步骤详见官方文档。

3. 页面具体代码

<template>
  <view class="htmlparsePage">
    <view class="fixedTop">
      <topbar :config="barConfig"></topbar>
      <view class="search-bar-container">
        <view class="weui-search-bar__form">
          <view class="weui-search-bar__box">
            <icon class="weui-icon-search_in-box" type="search" size="14"></icon>
            <input
              class="weui-search-bar__input"
              placeholder-style="color:#b9babd;"
              placeholder="请输入需要搜索的关键词"
              v-model="keyWord"
              confirm-type="search"
              @confirm="searchSelf(keyWord)"
            />

            <view
              class="weui-icon-clear"
              v-if="keyWord?.length > 0"
              @click="
                () => {
                  keyWord = ''
                  searchSelf('')
                }
              "
            >
              <icon type="clear" size="14"></icon>
            </view>
          </view>
        </view>

        <view class="a-search" style="margin-left: 10rpx; margin-right: 10rpx" v-if="searchRes?.num">
          <view class="searchNum">{{ searchIndex }}/{{ searchRes?.num }}</view>
        </view>
        <view class="a-search" style="margin-right: 10rpx" v-if="searchRes?.num" @click="preSearch">
          <image mode="widthFix" src="../../static/img/up.svg"></image>
        </view>
        <view class="a-search" @click="nextSearch" v-if="searchRes?.num">
          <image mode="widthFix" src="../../static/img/down.svg"></image>
        </view>
      </view>
    </view>

    <view v-if="show && data.content" class="mpHtmlRef">
      <mp-html
        ref="mp"
        use-anchor
        search
        container-style="padding:10px"
        :content="data.content"
        @linktap="navigate"
        @preview-img="false"
        @show-img-menu="false"
        :selectable="true"
        :tag-style="{
          table: 'border-collapse: collapse;border: solid black 1px',
          tr: 'border: solid black 1px',
          td: 'border: solid black 1px',
        }"
        @load="onMpLoaded"
      >
      </mp-html>
    </view>

    <view v-else class="emptyBox">
      <empty />
    </view>
  </view>
</template>

<script setup>
import empty from '../../components/empty/empty'
import mpHtml from '../../components/mp-html/mp-html'   // 引入
import { getDocDetail } from '../../api/filterList'
import topbar from '../../components/topbar/topbar.vue'
import { onLoad, onUnload, onShareAppMessage } from '@dcloudio/uni-app'
import { ref, reactive, onMounted, nextTick } from 'vue'
const mp = ref(null) //富文本对象
const id = ref('')
const show = ref(true)
const keyWord = ref('')
const data = reactive({
  content: '',
})
const barConfig = reactive({
  bg_color: 'transparent',
  color: '#000',
  flag: 1,
  name: '法规详情',
})
const searchRes = ref(null)
const searchIndex = ref(1)

function navigate(e) {
  this.$nextTick(() => {
    uni.navigateTo({
      url: '../detail/analysis?id=' + e.href,
      success: function (res) {},
      fail: function (res) {},
      complete: function (res) {},
    })
  })
}

onUnload(() => {
  uni.hideLoading()
})

onLoad((options) => {
  id.value = options.id
  keyWord.value = options.searchInput || '' // 关键词高亮
  getData()
})

// 获取文本数据 const getData
= async () => { uni.showLoading() getDocDetail({ id: id.value }) .then((res) => { if (res.code === 200) { data.content = res.data.content uni.hideLoading() } }) .catch((e) => { uni.hideLoading() uni.showToast({ title: '文档详情获取失败', icon: 'none', }) }) } // 处理 mp-html 加载完成 const onMpLoaded = async () => { if (keyWord.value) { searchSelf(keyWord.value) } } const searchSelf = (key) => { mp.value.search(key, true).then((res) => { searchRes.value = res searchIndex.value = 1 if (res.num === 0) { uni.showToast({ title: '没有了', icon: 'none', duration: 2000, }) } else { show.value = false res.highlight(1) res.jump(1, -343) // 高亮第 1 个结果并跳转到该位置,偏移量 show.value = true } }) } // 下一个关键词 const nextSearch = () => { show.value = false if (searchIndex.value < searchRes.value?.num) { searchIndex.value++ searchRes.value.highlight(searchIndex.value) searchRes.value.jump(searchIndex.value, -343) show.value = true } else { uni.showToast({ title: '没有了', icon: 'none', duration: 2000, }) show.value = true } }
// 上一个关键词 const preSearch
= () => { show.value = false if (searchIndex.value > 1 && searchIndex.value <= searchRes.value.num) { searchIndex.value-- searchRes.value.highlight(searchIndex.value) searchRes.value.jump(searchIndex.value, -343) show.value = true } else { uni.showToast({ title: '没有了', icon: 'none', duration: 2000, }) show.value = true } } </script> <style> .htmlparsePage { height: 100%; background: #e5f7fe; } .fixedTop { background: #e5f7fe; padding-bottom: 10rpx; position: fixed; top: 0; left: 0; height: 266rpx; z-index: 999; } .mpHtmlRef { height: calc(100% - 273rpx); margin-top: 273rpx; overflow-y: auto; background: #ffffff; border-radius: 48rpx 48rpx 0px 0px; } .emptyBox { margin-top: 30vh; } .emptyBox .emptyCon image { width: 280rpx; height: 280rpx; } .search-bar-container { background: #e5f7fe; padding: 15rpx 20rpx 0; height: 60rpx; display: flex; } .weui-search-bar__input { height: 60rpx; line-height: 28px; font-size: 24rpx; color: #939699; } .weui-search-bar__form { border: unset; border-radius: 30rpx; height: 60rpx; } .weui-search-bar__box { padding-left: 70rpx; height: 60rpx; } .weui-icon-search_in-box { left: 30rpx; float: left; top: 20rpx; } .a-search { height: 60rpx; display: flex; align-items: center; background-color: #fff; border-radius: 30px; padding: 0 15rpx; } .a-search image { height: 28rpx; width: 34rpx; } .searchNum { color: #858687; } </style>
posted @ 2024-08-27 10:06  行走的蒲公英  阅读(46)  评论(0编辑  收藏  举报