系列文章目录
提示:下面是简单的功能实现(时间紧迫,大晚上赶工)
el-select滚动条相关功能
- 系列文章目录
- 背景与展望
- 一、使用原生的js实现触底加载
- 1.效果图如下:
- 2.HTML如下
- 3.JS代码如下
- 二、使用自定义指令解决问题(已补全-2024-05-19)
- 1.效果图如下:
- 2.新增功能如下:
- 3.后续可以优化功能如下:
- 4.HTML代码如下:
- 4.Js代码如下:
- 总结
背景与展望
这次的功能甚至可以说一点也不复杂,但是作为一名前端开发.感觉这种交互行为其实出现在我们这个及其简易的功能场景中,就很离谱。需求做了又砍掉,纯纯的浪费时间,唉
本次的功能主要如下:
- 给el-select添加滚动条(
设置样式
)- 给el-select的滚动条
注册scroll事件
(记得一定要移除scroll
)- 体验感优化方法如下:
添加节流或防抖功能
添加loading交互- 场景优化:
不要污染全局的select框
缓存选择的options(回显)
采用footer插槽改变现有交互
拓展远端搜索供能
usehooks的提取(后面更新)
自定义指令的的声明(后面更新)
一、使用原生的js实现触底加载
1.效果图如下:
2.HTML如下
// 此处使用的是高版本的 el-Select(具体的版本使用的方法都是类似的,下面会提到)
<body>
<div id="app">
<div style="margin: 50px 0px;"><el-text class="mx-1" type="primary">初始化的options数据条数如下:{{optionsLength}}</el-text></div>
<el-select multiple v-model="value" placeholder="Select" style="width: 160px; height: 180px;" @visible-change="handleScroll">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</div>
</body>
3.JS代码如下
//因为是使用的HTML文档 所以此处的代码风格是Vue2的
//(我上手还是蛮快的,哈哈哈哈哈哈,都3年多不写Vue2的代码了)
<script>
const mockData1=[{label:"ceshi ",value:"sele1ct1"},{label:"ce2shi ",value:"sele12ct1"},{label:"cesh2i ",value:"sele3ct1"},{label:"ceshi3 ",value:"select1"},{label:"ceshi4 ",value:"sel1ec23t1"}]
const { ElMessage } = ElementPlus;
const App = {
data() {
return {
message: "Hello Element Plus",
options:[],
value:"",
mockOptions:[]
};
},
computed:{
optionsLength:function(){
return this.options.length
}
},
methods: {
createNewOptionsData:function(){
const str="测试dflklsadj我f的k京东数科了解阿ghjghjgj卡丽打飞gjghj机考拉激发lajfdkl"
const randomNumber = Math.floor(Math.random()*(str.length-2))
const result =str.split("")[randomNumber] + str.split("")[randomNumber+1]
this.options.push({label:"随机生成:"+result,value:result})
},
scrollEvent(event){
const domTarget =event.target
const translateY = domTarget.scrollTop
const viewheight =domTarget.clientHeight
const allHeight = domTarget.scrollHeight
if(allHeight-translateY<=viewheight){
this.createNewOptionsData()
// 添加一个数据
ElMessage({
message: `在Options中添加了一条数据,当前的条数为${this.options.length}`,
type: 'success',
})
}
}
,
handleScroll:function(val){
//这里注释的三个类,主要是抓的弹窗中的popover类,
//一般情况下都可以使用,我这里使用的是 [el-scrollbar__wrap]
// el-select-dropdown__wrap el-scrollbar__wrap el-scrollbar__wrap--hidden-default
const dom = document.querySelector(".el-scrollbar__wrap")
if(!val){
dom.removeEventListener("scroll",this.scrollEvent)
}
dom.addEventListener("scroll",this.scrollEvent)
}
},
mounted() {
//此处都是为了mock数据
this.options =mockData1
this.createNewOptionsData()
},
};
const app = Vue.createApp(App);
app.mount("#app");
</script>
二、使用自定义指令解决问题(已补全-2024-05-19)
敬请期待(2024-05-16 23:55)
1.效果图如下:
2.新增功能如下:
- JavaScript原生写法 ===> 自定义指令触发
- 给触发事件添加节流效果
- 将事件缓存到节点上
3.后续可以优化功能如下:
- 拓展响应式数据的池子(
支持更多功能
)- 拓展使用场景。
不单单作用el-select组件
- 拓展方法的配置
4.HTML代码如下:
// 结构如下
<body>
<div id="app">
<div style="margin: 50px 0px;">
<el-text class="mx-1" type="primary">初始化的options数据条数如下:{{optionsLength}}</el-text>
</div>
<el-select v-if="boolen" v-selectscroll="options" multiple popper-class="select-scroll" v-model="value"
placeholder="Select" style="width: 160px; height: 180px;">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</div>
</body>
4.Js代码如下:
const { ElMessage } = ElementPlus;
const { createApp, ref, watchEffect, watch } = Vue;
const mockData1 = [{ label: "ceshi ", value: "sele1ct1" }, { label: "ce2shi ", value: "sele12ct1" }, { label: "cesh2i ", value: "sele3ct1" }, { label: "ceshi3 ", value: "select1" }, { label: "ceshi4 ", value: "sel1ec23t1" }]
const App = {
data() {
return {
options: [],
value: "",
};
},
computed: {
optionsLength: function () {
return this.options.length
}
},
};
const app = createApp(App);
app.directive("selectscroll", {
created: function (el, binding) {
el.__flag = false
const getCurrentTimer = () => {
const now = new Date();
const year = now.getFullYear();
const month = (now.getMonth() + 1).toString().padStart(2, '0');
const day = now.getDate().toString().padStart(2, '0');
const hours = now.getHours().toString().padStart(2, '0');
const minutes = now.getMinutes().toString().padStart(2, '0');
const seconds = now.getSeconds().toString().padStart(2, '0');
const formattedDate = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
return formattedDate
}
el.__curentTimer = getCurrentTimer
console.log("自定义指令created");
},
mounted: (el, binding) => {
console.log("自定义指令mounted");
mockData1.forEach(item => {
binding.value.push(item)
})
const createNewOptionsData = async function () {
const str = "测试dflklsadj我f的k京东数科了解阿ghjghjgj卡丽打飞gjghj机考拉激发lajfdkl"
const randomNumber = Math.floor(Math.random() * (str.length - 2))
const result = str.split("")[randomNumber] + str.split("")[randomNumber + 1]
binding.value.push({ label: "随机生成:" + result, value: result })
const node = document.createElement('p')
node.innerText = `生成数据的时间是:${el.__curentTimer()}`
document.body.appendChild(node)
}
const handleScroll = async function (event) {
clearTimeout(el.__flag)
el.__flag = setTimeout(async () => {
const domTarget = event.target
const translateY = domTarget.scrollTop
const viewheight = domTarget.clientHeight
const allHeight = domTarget.scrollHeight
if (allHeight - translateY <= viewheight + 2) {
await createNewOptionsData()
// 添加一个数据
ElMessage({
message: `在Options中添加了一条数据,当前的条数为${binding.value.length}`,
type: 'success',
})
}
}, 1500);
}
const dom = document.querySelector(".select-scroll .el-scrollbar__wrap")
dom.addEventListener("scroll", handleScroll)
el.__handleScroll = handleScroll
el.__scrollDom = dom
},
unmounted(el, binding) {
// const dom = document.querySelector(".select-scroll .el-scrollbar__wrap")
el.__scrollDom.removeEventListener("scroll", el.__handleScroll)
console.log("成功注销了");
}
})
总结
希望自己的写法可以帮助到遇到问题的人。有不足之处,或者可以优化的地方,欢迎大家给出自己的建议,会从大家的建议中汲取营养,提升自己!!!