📜  Koa.js-级联(1)

📅  最后修改于: 2023-12-03 15:02:31.812000             🧑  作者: Mango

Koa.js级联

什么是级联?

级联(又称级联选择或者级联菜单)指的是一种多个下拉菜单或者选项列表依次关联的交互方式。在级联下拉菜单中,用户选择一个菜单选项,此时会触发相关菜单项的变化。比如,用户选择某个省份,可以根据省份的值动态修改城市选项。这种交互方式在一些网站或者应用中比较常见。

Koa.js级联

Koa.js是一个新一代的node.js Web框架。它采用了ES6的新特性,更加简洁易用,真正实现了“中间件首选”的思想。

Koa.js提供了一种开发级联下拉菜单的方式,使用该方式,我们可以在后端程序中实现级联功能,将数据和所需要的逻辑封装在后台中,然后在前端以异步的方式拉去数据,实现了前后端分离。

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实现级联下拉菜单也相对简单,可以根据实际需求进行二次开发,同时避免了引入大型框架的缺点。