您的位置:首页 > 健康 > 美食 > 免费咨询平台_产品线下推广方式都有哪些_科学新概念seo外链平台_网站建设 网站制作

免费咨询平台_产品线下推广方式都有哪些_科学新概念seo外链平台_网站建设 网站制作

2025/1/11 19:31:31 来源:https://blog.csdn.net/weixin_45855469/article/details/144969361  浏览:    关键词:免费咨询平台_产品线下推广方式都有哪些_科学新概念seo外链平台_网站建设 网站制作
免费咨询平台_产品线下推广方式都有哪些_科学新概念seo外链平台_网站建设 网站制作

一、查找、替换

查找替换的组件 src/views/Editor/SearchPanel.vue
回车的时候会执行查找,查找替换功能的相关方法和属性都在 src/hooks/useSearch.ts 中。

1、查找

查找的方法也比较的朴实无华,就是 for 循环所有的幻灯片中的所有元素,通过 .match() 方法匹配要查找的关键词,如果匹配上的话,就放到 searchResults 中,会保存元素的id、元素类型以及元素所在的幻灯片的id。然后对 searchResults 中的数据进行高亮。
在这里插入图片描述

高亮的方法是会给目标文本创建一个父级 marker
在这里插入图片描述

mark 上还增加了一个 data-index 表示顺序
通过 textNode.parentNode!.replaceChild(mark, textNode) 使用 mark 替换文本元素

2、下一个/上一个

src/hooks/useSearch.ts 中有一个属性 searchIndex 来标识当前查找第几个关键词。下一个/上一个 的时候,会修改这个属性,然后执行 turnTarget() 方法

const turnTarget = () => {if (searchIndex.value === -1) returnconst target = searchResults.value[searchIndex.value]if (target.slideId === currentSlide.value.id) setTimeout(setActiveMark, 0)else {const index = slides.value.findIndex(slide => slide.id === target.slideId)if (index !== -1) slidesStore.updateSlideIndex(index)}
}

这里有两种情况了,

  • 如果幻灯片没变化,执行 setActiveMark(),找对应的 mark,增加 active 类名
const setActiveMark = () => {const markNodes = document.querySelectorAll('mark[data-index]')for (const node of markNodes) {setTimeout(() => {const index = (node as HTMLElement).dataset.indexif (index !== undefined && +index === searchIndex.value) {node.classList.add('active')}else node.classList.remove('active')}, 0)}
}
  • 幻灯片变化,执行 slidesStore.updateSlideIndex(index) ,要跳转幻灯片。跳转完了之后呢,这里有一个监听幻灯片变化的方法,重新计算一下需要高亮的文本,设置 markactive
  • src/hooks/useSearch.ts
watch(slideIndex, () => {nextTick(() => {highlightCurrentSlide()setTimeout(setActiveMark, 0)})
})
3、替换

替换的时候,如果没有搜索结果的话,会直接执行 searchNext() 方法。
如果当前有搜索结果,就找当前处在激活状态中的 mark
先制造一个 fakeElement,通过 parentNode.replaceChild(document.createTextNode(replaceWord.value), mark) 方法替换节点,
然后还通过 slidesStore.updateElement({ id: target.elId, props }) 更新元素,使用 fakeElement 替换原来的元素。

4、替换全部

替换全部的时候其实跟替换差不多,但是循环 searchResults,遍历所有的文本节点,给所有的 mark 都创造一个 fakeElement,使用 slidesStore.updateElement({ id: target.elId, slideId: target.slideId, props }) 进行更新。
创建一个fakeElement 而不是直接更新 DOM ,可以防止后续错误导致流程失败结果已经更新了DOM的情况,以及减少页面重绘次数,另外可以统一将更新操作统一执行,代码可维护性更高。

二、绘制文本框

绘制文字范围、绘制形状范围使用的都是 mainStore.setCreatingElement() 方法。这个方法接收一个对象作为参数,就是要绘制的元素本身。如果是绘制文字的话,

// 绘制文字范围
const drawText = (vertical = false) => {mainStore.setCreatingElement({type: 'text',vertical,})
}

第二个参数表示是否是垂直方向,默认是横向。

src/views/Editor/Canvas/index.vue

<ElementCreateSelectionv-if="creatingElement"@created="data => insertElementFromCreateSelection(data)"/>

有了 creatingElement,就会创建 ElementCreateSelection 组件,同时会执行 insertElementFromCreateSelection()
方法。

  // 根据鼠标选区的位置大小插入元素
const insertElementFromCreateSelection = (selectionData: CreateElementSelectionData) => {if (!creatingElement.value) returnconst type = creatingElement.value.typeif (type === 'text') {const position = formatCreateSelection(selectionData)position && createTextElement(position, { vertical: creatingElement.value.vertical })}mainStore.setCreatingElement(null)
}

然而,这里有一个容易混淆的地方,@created 并不是Vue3内置的函数,而是这个自定义组件自己定义的监听函数🥹🥹🥹,我说呢,这个方法的执行实际不太对啊,这个方法是鼠标起来的时候才会执行,而不是创建这个组件的时候执行。
我们看一下 src/views/Editor/Canvas/ElementCreateSelection.vue 组件里面的执行流程

  • mousedown
    鼠标落下的时候,执行 createSelection(),记录此时的坐标到 start 中。此时会添加 document.onmousemove 监听函数

  • mousemove
    鼠标移动的时候,实时计算坐标,记录到 end

  • mouseup
    鼠标抬起时,清空 onmousemoveonmouseup
    通过 e.button 判断此时有没有按鼠标右键

    e.button = 0  // 鼠标左键
    e.button = 1  // 鼠标中键(滚轮)
    e.button = 2  // 鼠标右键
    e.button = 3  // 浏览器后退键
    e.button = 4  // 浏览器前进键
    

    如果按了就表示取消绘制,mainStore.setCreatingElement(null)creatingElement 清空。
    否则就触发 created 方法,将 startend 传进去,然后自定义组件就会监听到。那我就不明白了,明明是组件内部会触发这个方法,干嘛还要写成监听函数的形式,直接写成组件里面的方法不就行了吗?一般定义监听函数,都是给父组件来触发的👽👽👽
    哦,知道了,因为这个

    const { insertElementFromCreateSelection, formatCreateSelection } = useInsertFromCreateSelection(viewportRef)
    

    要将 viewportRef 传进去呢,这个模版元素只能从父组件中传过去。

  • @created
    监听到这个方法之后,就要执行 insertElementFromCreateSelection(data)data 是位置信息,就是上面说的 startend

  • createTextElement()
    根据位置信息创建文本元素。这个方法以前也见过了。
    src/hooks/useCreateElement.ts

      // 创建(插入)一个元素并将其设置为被选中元素const createElement = (element: PPTElement, callback?: () => void) => {// 添加元素到元素列表slidesStore.addElement(element)// 设置被选中元素列表mainStore.setActiveElementIdList([element.id])if (creatingElement.value) mainStore.setCreatingElement(null)setTimeout(() => {// 设置编辑器区域为聚焦状态mainStore.setEditorareaFocus(true)}, 0)if (callback) callback()// 添加历史快照addHistorySnapshot()}
    

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com