当前位置: 首页 > 后端技术 > Node.js

基于ES6面向对象封装Cascader级联选择器组件

时间:2023-04-03 20:53:17 Node.js

以省市数据为例,组件效果如下:技术亮点:1.前后端通信结合,实现动态热更新渲染数据2.在组件中设置访问器属性中使用setter和getter3.使用事件监听和抛出实现级联效果4.实现自定义组件结构和样式开发思路:1.Ajax请求:1)页面初始化请求只请求省数据,整个渲染和省数据接口在交互过程中只会请求一次。2)在回调函数loadHandler中:判断本次ajax请求的是哪个接口,如果是请求省份数据,则获取到省份数据后,将数据赋值给组件的showData属性,从而渲染出省份组件,并同时级联去请求市级和县级数据并渲染;如果本次请求市级接口,则只渲染市级和县级数据,省级数据不变。3)给组件绑定点击监听事件,当组件被点击时抛出数据,携带被点击的组件名称和当前选中的参数;同理,用上面2)中的方法判断点击的是哪一级数据,从而选择性地请求市级、县级数据或者只请求县级数据2.set/getaccessorattribute:1)setbool在组件中作为访问器属性。当点击事件触发时,bool值反转,同时ul列表样式绑定bool值,实现动态变化2)给组件设置一个accessor属性showData,当省或市的数据更改后,修改后的数据相应赋值给showData,同时触发showData中的方法,重新渲染组件的组件代码如下:importComponentfrom"./Component.js";//该组件的超类,主要作用是将elem属性声明为div元素,并创建appendTo方法插入到目标页面指定的dom元素中importUtilsfrom"./Utils.js";//公共方法,主要调用Utils.addCSS方法将样式添加到目标页面的样式表中exportdefaultclassLabelextendsComponent{_bool=false;//访问属性:setter和getter_showData=[];//访问器属性名;构造函数(_name){超级();this.name=_name;this.elem.className="dropup";只为组件设置css样式,监听元素的点击事件this.elem.addEventListener("click",(e)=>this.clickHandler(e));//渲染组件样式this.setStyle();}render(){//渲染组件的主要DOM结构this.elem.innerHTML="";this.elem.innerHTML=`${this.showData[0]}

${this.showData.reduce(function(value,item){value+="
  • "+item+"
  • ";返回值;},"")}`}clickHandler(e){this.bool=!this.bool;if(e.target.nodeName==="LI"){this.elem.children[0].textContent="";this.elem.children[0].textContent=e.target.textContent;//抛出事件时携带数据,当前显示哪些数据,属于第几层varevt=newEvent("change");evt.data=this.elem.children[0].textContent;evt.name=this.name;this.dispatchEvent(evt);}}setshowData(value){//当数据改变时this._showData=value;这个。渲染();this.setStyle();this.bool=false;}获取showData(){返回this._showData;}setbool(value){if(value){this.elem.children[1].className="ul1";}else{this.elem.children[1].className="ul1ul2";}这个._嘘l=值;}getbool(){返回这个._bool;}setStyle(){如果(this.styleBool)返回;Utils.addCSS(".dropup",{width:"120px",height:"30px",lineHeight:"30px",borderRadius:"4px",border:"1pxsolidrgba(0,0,0,.15)",userSelect:"none",textAlign:"center",float:"left",marginLeft:"10px",});Utils.addCSS(".ul1",{listStyle:"none",padding:"0",border:"1pxsolidrgba(0,0,0,.15)",borderRadius:"4px",boxShadow:"06px12pxrgba(0,0,0,.175)",margin:"2px00",fontSize:"14px",textAlign:"left",transition:"all0.2s",transitionProperty:"max-height",最大高度:"500px",溢出:"自动",});Utils.addCSS(".ul2",{maxHeight:"0px",border:"none",});Utils.addCSS("li",{padding:"0px10px",});Utils.addCSS("li:hover",{backgroundColor:"rgba(0,0,0,0.15)",});日is.styleBool=true;}}主页面js部分代码如下:importLabelfrom"./js/Label.js"//要显示的省市县及源数据varprovinceArr,cityArr,countyArr;//provinces,cities实例化对象varprovince,city,county;在里面();functioninit(){render();//渲染省市组件对象ajax("province");//初始化请求省级数据,从而触发级联反应,请求市区级数据inloadhandler//province整个过程只调用一次}functionrender(){//创建省市组件时不添加数据,统一获取数据后使用setData添加数据渲染组件province=newLabel("省”);province.addEventListener("change",changeHandler);province.appendTo(".setPos");城市=新标签(“城市”);city.appendTo(".setPos");city.addEventListener("改变",changeHandler);县=新标签(“县”);county.appendTo(".setPos");county.addEventListener("变化",changeHandler);}functionchangeHandler(e){switch(e.name){case"province"://当点击省份栏时,市县级别会发生变化//调用ajax请求城市接口,从而触发级联反应loadhandler中的ajax("city",{province:e.data});休息;case"city"://当点击城市栏时,需要改变县级//当前状态下省级显示数据varcurProvince=province.elem.firstElementChild.textContent;//调用ajax请求county接口触发loadhandler中的级联反应ajax("county",{province:curProvince,city:e.data});休息;}}functionajax(name,data){varxhr=newXMLHttpRequest();xhr.addEventListener("load",loadHandler);switch(name){case"province"://请求省份,加载第一层数据xhr.open("POST","http://10.9.72.241:4001/province");休息;case"city"://请求城市级别,加载第二层数据xhr.open("POST","http://10.9.72.241:4001/city");休息;case"county"://请求县级,加载第三层数据xhr.open("POST","http://10.9.72.241:4001/county");休息;}数据===未定义?xhr.send():xhr.send(JSON.stringify(data));}函数loadHandler(e){varxhr=e.cur租金目标;xhr.removeEventListener("load",loadHandler);//通过切割responseURL获取请求的type接口类型vartype=xhr.responseURL.trim().split("?")[0].split("\/").pop();varsourceData=JSON.parse(xhr.response);switch(type){case"province"://当发现请求的是省级数据时,将省级数据渲染到组件上,需要请求市级数据provinceArr=sourceData;ajax("城市",{"省":provinceArr[0]});province.showData=provinceArr;休息;case"city"://当发现请求的是市级数据,即需要更新市级数据时,将市级数据渲染到组件中,县级数据需要同时请求数据。cityArr=源数据;varcurProvince=province.elem.firstElementChild.textContent。修剪();ajax("县",{"省":curProvince,"市":cityArr[0]});city.showData=cityArr;休息;case"county"://当发现是请求县级数据时,直接将获取到的数据渲染到组件中countyArr=source数据;county.showData=countyArr;}}接口文档如下:省份数据:请求方式:POST请求地址:http://服务器接口url/省请求参数格式:无返回参数格式:{"res":["北京","上海","河北","山西","内蒙古"]}市级数据:请求方式:POST请求地址:http://服务器接口url/城市请求参数格式:{"省":"北京"}返回参数格式:{"res":["北京"]}县级数据:请求方式:POST请求地址:http://服务器接口url/county请求参数格式:{"省":"北京","市":"北京"}返回参数格式:{"res":["东城区"、"西城区"、"崇文区"、"玄武区"、"朝阳区"、"丰台区"、"石景山区"、“海淀区”、“门头沟区”、“房山区”、“通州区”、“顺义区”、“昌平区”、“大兴区”、“平谷区”、“怀柔区”、“密云县”,"延庆县","其他"]}