📅  最后修改于: 2023-12-03 15:02:31.812000             🧑  作者: Mango
级联(又称级联选择或者级联菜单)指的是一种多个下拉菜单或者选项列表依次关联的交互方式。在级联下拉菜单中,用户选择一个菜单选项,此时会触发相关菜单项的变化。比如,用户选择某个省份,可以根据省份的值动态修改城市选项。这种交互方式在一些网站或者应用中比较常见。
Koa.js是一个新一代的node.js Web框架。它采用了ES6的新特性,更加简洁易用,真正实现了“中间件首选”的思想。
Koa.js提供了一种开发级联下拉菜单的方式,使用该方式,我们可以在后端程序中实现级联功能,将数据和所需要的逻辑封装在后台中,然后在前端以异步的方式拉去数据,实现了前后端分离。
1.首先我们需要根据参数下拉菜单产生对应的路由,并在对应的路由中编写处理逻辑。对于koa-router,我们可以使用params进行路由参数注入。
const Koa=require('koa')
const Router=require('koa-router')
const app=new Koa()
const router=new Router()
router
.get('/province/:provinceId/city',async (ctx,next)=>{
const provinceId=ctx.params.provinceId
const result=[
{"id":1,"name":"北京市"},
{"id":2,"name":"天津市"}
]
ctx.body={
"code":200,
"msg":"success",
"result":result
}
await next()
})
.get('/province/:provinceId/:cityId',async (ctx,next)=>{
const provinceId=ctx.params.provinceId
const cityId=ctx.params.cityId
const result=[
{"id":1,"name":"朝阳区"},
{"id":2,"name":"海淀区"},
{"id":3,"name":"西城区"},
{"id":4,"name":"东城区"}
]
ctx.body={
"code":200,
"msg":"success",
"result":result
}
await next()
})
app
.use(router.routes())
.use(router.allowedMethods())
app.listen(3000)
2.在前端代码中,我们需要实现级联逻辑,对于一级菜单的选择,我们可以使用ajax向后台请求获取对应的数据,并根据数据生成二级菜单。对于二级菜单的选择,我们可以再次ajax向后台请求获取对应的数据,并生成三级菜单。
下面是一个示例代码:
const provincesEle = document.querySelector("#provinces") //获取省份下拉菜单元素
const citiesEle = document.querySelector("#cities") //获取城市下拉菜单元素
const districtsEle = document.querySelector("#districts") //获取区县下拉菜单元素
//通过ajax获取省份数据
function getProvinces() {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open("GET", "/province")
xhr.send()
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
const result = JSON.parse(xhr.responseText).result
resolve(result)
} else {
reject("获取省份数据失败!")
}
}
}
})
}
//通过ajax获取城市数据
function getCities(provinceId) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open("GET", `/province/${provinceId}/city`)
xhr.send()
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
const result = JSON.parse(xhr.responseText).result
resolve(result)
} else {
reject("获取城市数据失败!")
}
}
}
})
}
//通过ajax获取区县数据
function getDistricts(provinceId, cityId) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open("GET", `/province/${provinceId}/${cityId}`)
xhr.send()
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
const result = JSON.parse(xhr.responseText).result
resolve(result)
} else {
reject("获取区县数据失败!")
}
}
}
})
}
//动态填充省份下拉菜单
async function fillProvinces() {
const provinces = await getProvinces()
provinces.forEach((province) => {
const optionEle = document.createElement("option")
optionEle.value = province.id
optionEle.textContent = province.name
provincesEle.appendChild(optionEle)
})
//默认选择第一个省份
provincesEle.value = provinces[0].id
}
//动态填充城市下拉菜单
async function fillCities(provinceId) {
citiesEle.innerHTML = ""
districtsEle.innerHTML = ""
const cities = await getCities(provinceId)
cities.forEach((city) => {
const optionEle = document.createElement("option")
optionEle.value = city.id
optionEle.textContent = city.name
citiesEle.appendChild(optionEle)
})
//默认选择第一个城市
if (cities.length > 0) {
citiesEle.value = cities[0].id
await fillDistricts(provinceId, cities[0].id)
}
}
//动态填充区县下拉菜单
async function fillDistricts(provinceId, cityId) {
districtsEle.innerHTML = ""
const districts = await getDistricts(provinceId, cityId)
districts.forEach((district) => {
const optionEle = document.createElement("option")
optionEle.value = district.id
optionEle.textContent = district.name
districtsEle.appendChild(optionEle)
})
//默认选择第一个区县
if (districts.length > 0) {
districtsEle.value = districts[0].id
}
}
//添加省份下拉菜单change事件
provincesEle.addEventListener("change", async () => {
const provinceId = provincesEle.value
await fillCities(provinceId)
})
//添加城市下拉菜单change事件
citiesEle.addEventListener("change", async () => {
const provinceId = provincesEle.value
const cityId = citiesEle.value
await fillDistricts(provinceId, cityId)
})
//初始化省份下拉菜单
fillProvinces()
级联下拉菜单是一种常见的交互方式,在实际项目中也比较常见。使用Koa.js可以方便地实现级联下拉菜单功能,将数据和逻辑封装在后台中,实现了前后端分离。同时,使用原生JavaScript实现级联下拉菜单也相对简单,可以根据实际需求进行二次开发,同时避免了引入大型框架的缺点。