【CodeMirror自定义点击搜索事件显示搜索框进行搜索】

CodeMirror自定义点击搜索事件显示搜索框进行搜索

背景

vue项目使用CodeMirror组件,要求增加一个类似浏览器的Ctrl+F的查询功能。为什么不直接使用浏览器的Ctrl+F功能?因为当CodeMirror里面的文本内容超出显示高度有滚动条时,超出滚动的内容是没有渲染在页面的,所以Ctrl+F是搜索不到的。
CodeMirror有自带的搜索功能,但是太简陋了,无法满足需求。
最终效果
在这里插入图片描述

代码

codemirror.vue

<template>
	<codemirror v-model:value="currValue" :options="options" border :placeholder="$props.placeholder" @change="onChange" :keyHandled="onKeyhandle"/>
</template>

<script setup lang="ts">
	/**
	 *@file 公共组件-代码编辑器
	 */
	// TS类型
	// 内置方法
	import {
   
    reactive, ref, watch } from 'vue';
	// 公共方法
	import './components/codemirror_search/revisedsearch'
	import './components/codemirror_search/revisedsearch.css'
	import './components/advanced-dialog/advanced-dialog'
	// 接口
	// 组件
	// Store
	// 常量
	import {
   
    modeMap } from 'src/plugins/codemirror';

	const $props = withDefaults(
		defineProps<{
   
   
			value?: string;
			placeholder?: string;
			suffix?: string;
		}>(),
		{
   
   
			placeholder: '请输入...',
			suffix: 'txt'
		}
	);

	// 获取类名为 CodeMirror-dialog CodeMirror-dialog-top 的 div 元素
	let dialogDiv = document.querySelector('.CodeMirror-dialog.CodeMirror-dialog-top');
	if (dialogDiv) {
   
   
		// 创建左箭头按钮
		let leftArrowButton = document.createElement('button');
		leftArrowButton.textContent = '←';
	
		// 创建右箭头按钮
		let rightArrowButton = document.createElement('button');
		rightArrowButton.textContent = '→';
	
		// 将按钮添加到 div 元素中
		dialogDiv.appendChild(leftArrowButton);
		dialogDiv.appendChild(rightArrowButton);
	}

	// 当前编辑器的内容
	const currValue = ref('');

	const $emit = defineEmits(['update:value']);
	// 双向绑定
	watch(
		() => $props.value,
		(val) => {
   
   
			currValue.value = val ?? '';
		},
		{
   
    immediate: true }
	);

	const onChange = (value: string) => {
   
   
		$emit('update:value', value);
	};
	const onKeyhandle = (name:any, event:any) => {
   
   
		console.log('123--', name, event)
	};

	// 编辑器配置
	const options = reactive({
   
   
		tabSize: 4, // Tab缩进,默认4
		mode: modeMap[$props.suffix],
		lineNumbers: true, // 显示行号
		line: true,
		lineWrapping: true, // 自动换行
		theme: 'darcula', // 主题
		smartIndent: true, // 智能缩进
		indentUnit: 4, // 智能缩进单位为4个空格长度
		indentWithTabs: true, // 使用制表符进行智能缩进
		// 在行槽中添加行号显示器、折叠器、语法检测器
		gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter', 'CodeMirror-lint-markers'],
		foldGutter: true, // 启用行槽中的代码折叠
		autofocus: true, // 自动聚焦
		matchBrackets: true, // 匹配结束符号,比如"]、}"
		autoCloseBrackets: true, // 自动闭合符号
		styleActiveLine: true // 显示选中行的样式
	});

	watch(
		() => $props.suffix,
		(val) => {
   
   
			options.mode = modeMap[val ?? 'txt'];
		}
	);
</script>

<style scoped lang="less"></style>

/**
 * @file 注册codemirror编辑器插件
 */
import {
   
    TCommonDir } from 'src/types/common';

import {
   
    InstallCodemirro } from 'codemirror-editor-vue3';

// 主题
import 'codemirror/theme/darcula.css';
import 'codemirror/lib/codemirror.css';
// 语法
import 'codemirror/mode/textile/textile';
import 'codemirror/mode/clike/clike';
import 'codemirror/mode/python/python';
import 'codemirror/mode/go/go';
import 'codemirror/mode/php/php';
import 'codemirror/mode/sql/sql';
import 'codemirror/mode/shell/shell';
import 'codemirror/mode/powershell/powershell';
import 'codemirror/mode/javascript/javascript';
import 'codemirror/mode/xml/xml';
import 'codemirror/mode/vue/vue';
import 'codemirror/mode/markdown/markdown';
import 'codemirror/mode/yaml/yaml';
// 插件
import 'codemirror/addon/dialog/dialog.js'
import 'codemirror/addon/dialog/dialog.css'
import 'codemirror/addon/display/placeholder.js';
import 'codemirror/addon/scroll/annotatescrollbar.js'
import 'codemirror/addon/search/jump-to-line.js'
import 'codemirror/addon/search/matchesonscrollbar.js'
import 'codemirror/addon/search/matchesonscrollbar.css'
import 'codemirror/addon/search/match-highlighter.js'
import 'codemirror/addon/search/searchcursor.js'
import 'codemirror/addon/search/search.js'
import 'codemirror/addon/display/panel.js'
// 折叠
import 'codemirror/addon/fold/foldgutter.css'
import 'codemirror/addon/fold/foldcode'
import 'codemirror/addon/fold/foldgutter'
import 'codemirror/addon/fold/brace-fold'
import 'codemirror/addon/fold/comment-fold'

// 文件后缀映射语法mode
const modeMap: TCommonDir<string> = {
   
   
	txt: 'text/x-textile',
	c: 'text/x-c',
	'c++': 'text/x-c++src',
	'c#': 'text/x-csharp',
	py: 'text/x-python',
	java: 'text/x-java',
	go: 'text/x-go',
	php: 'text/x-php',
	sql: 'text/x-sql',
	sh: 'text/x-sh',
	ps1: 'application/x-powershell',
	js: 'text/javascript',
	ts: 'text/javascript',
	json: 'application/json',
	xml: 'text/xml',
	html: 'text/html',
	vue: 'text/x-vue',
	md: 'text/x-markdown',
	yml: 'text/yaml'
};

export {
   
    InstallCodemirro, modeMap };

revisedsearch.js

/* eslint-disable */

"use strict";

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
   
    return typeof obj; } : function (obj) {
   
    return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// Revised search plugin written by Jamie Morris
// Define search commands. Depends on advanceddialog.js
(function (mod) {
   
   
  if ((typeof exports === "undefined" ? "undefined" : _typeof(exports)) == "object" && (typeof module === "undefined" ? "undefined" : _typeof(module)) == "object") // CommonJS
    mod(require("codemirror"), require("codemirror-advanceddialog"));else if (typeof define == "function" && define.amd) // AMD
    define(["codemirror", "codemirror-advanceddialog"], mod);else // Plain browser env
    mod(CodeMirror);
})(function (CodeMirror) {
   
   
  "use strict";

  var replaceDialog = '\n    <div class="row find">\n      <label for="CodeMirror-find-field">替换:</label>\n      <input id="CodeMirror-find-field" type="text" class="CodeMirror-search-field" placeholder="Find" />\n      <span class="CodeMirror-search-hint">(Use /re/ syntax for regexp search)</span>\n      <span class="CodeMirror-search-count"></span>\n    </div>\n    <div class="row replace">\n      <label for="CodeMirror-replace-field">With:</label>\n      <input id="CodeMirror-replace-field" type="text" class="CodeMirror-search-field" placeholder="Replace" />\n    </div>\n    <div class="but
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值