二次封装element plus (el-select-v2远程搜索组件)

根据项目需求,需要给每个对应的搜索字段进行 远程搜索

项目中有跟多地方都需要使用,所以进行二次封装会很方便.

创建一个ElSelectV2文件夹==> index.vue

<template>
    <div>
        <el-select-v2
            v-model="valueName"
            filterable
            remote
            :remote-method="remoteMethod"
            :options="options"
            :loading="loading"
            placeholder="请输入"
        />
    </div>
</template>

<script setup name="ElSelectV2">
import {reactive, toRefs, watch} from "vue";

const emit = defineEmits();
const valueName = ref(''); // 选中的值
const states = ref([]); // 接收数据
const options = ref([]); // 遍历出来的选项
const loading = ref(false); // 是否加载中

const props = defineProps({
    modelValue: [String, Object, Array],
    isShowTip: {
        type: String,
        default: true,
    },
});

// 监听 valueName不能写成valueName.value
watch(valueName, (val) => {
    remoteMethod(val);
});

function remoteMethod(query) {
    // 判断props.modelValue和props.isShowTip是否存在
    if (!props.modelValue || !props.isShowTip) {
        return
    }
    const list = props.modelValue.map((item) => {
        return { value: `${item[props.isShowTip]}`, label: `${item[props.isShowTip]}` }
    })

    if (query !== '') {
        loading.value = true
        setTimeout(() => {
            loading.value = false
            options.value = list.filter((item) => {
                return item.label.toLowerCase().includes(query.toLowerCase())
            })
            // 去重
            options.value = Array.from(new Set(options.value.map(item => item.label))).map(label => {
                return options.value.find(item => item.label === label)
            })
        }, 200)
        emit("update:nameValue",valueName.value);
    } else {
        options.value = []
    }
}
</script>

在父组件中使用:

// 这里的 dataList 就是我们请求过来的表格数据
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch">
    <el-form-item label="责任单位" prop="sibleUnit">
        <ElSelectV2 :isShowTip=" 'sibleUnit' " v-model="dataList" v-model:nameValue="queryParams.sibleUnit"></ElSelectV2>
    </el-form-item>
    <el-form-item label="证照类型代码" prop="typeCode">
        <ElSelectV2 :isShowTip=" 'typeCode' " v-model="dataList" v-model:nameValue="queryParams.typeCode"></ElSelectV2>
    </el-form-item>
</el-form>

<script setup>
    import ElSelectV2 from "../../components/ElSelectV2/index.vue";
    
    const data = reactive({
        queryParams: {
            pageNo: 1,
            pageSize: 10,
            sibleUnit: undefined,
            typeCode: undefined
        }
    });

    const {queryParams} = toRefs(data);

</script>

点击重置按钮,刷新子组件来实现清空内容的效果

这里我们就可以通过刷新子组件的方法来实现清空

// 通key给子组件绑定一个timer变量,类型为number
<ElSelectV2 :key="timer" :isShowTip=" 'sibleUnit' " v-model:nameValue="queryParams.sibleUnit"></ElSelectV2>

<script setup name="certificationType">
    const timer = ref(0);

    /** 重置按钮操作 */
    function resetQuery() {
        // 把当前的时间戳赋值给timer,这样绑定子组件的key就会变化,从而达到刷新的目的
        timer.value = new Date().getTime();
        proxy.resetForm("queryRef");
        handleQuery();
    }
</script>

报错:

Unable to preventDefault inside passive event listener invocation.

扫描二维码关注公众号,回复: 14922149 查看本文章

这个错误是 谷歌浏览器监听touch类事件报错: 无法被动侦听事件preventDefault,是新版本Chrome浏览器报错.

解决:

1. 处理函数时,用如下方式,明确声明为不是被动的
window.addEventListener('touchmove',func,{passive:false})
2. 应用css属性 touch-action: none; 这样任何触摸事件都不会产生默认行为,但是touch事件照样触发.
    touch-action 还有很多选项

如果以上两个方法不生效,就用下面的

/*
查看你的项目中是否安装了 default-passive-events 依赖,安装了就卸载,然后在main.js中注释掉,
它默认情况下启用某些事件的被动侦听器,基本上每次声明新的事件监听器时,都会自动设置{passive:true} 
*/
import 'default-passive-events'

default-passive-events 插件是用来解决谷歌浏览器消除 Passive Event Listeners(被动事件警告)的方法.

但是安装 default-passive-events 是为了解决 Chrome 51 以后的版本警告,进退两难.

我这里没有卸载 default-passive-events 依赖,只是在 main.js 中把它给注释了.

猜你喜欢

转载自blog.csdn.net/m0_58293192/article/details/129338135