感觉好难哦(还有救吗) tab页面切换判断(升序降序) 以及计算属性的使用

200 阅读1分钟

前端

  <template>
      <div class="search-list">
        <!-- tab -->
        <div class="tab">
          <ul>
            <!--  3 点击每一个li 让动态绑定的激活class类的index判断的值进行动态变化 -->
            <li v-for="(item,index) in tabList.data" :key="index" @click="changeTab(index)">
              <div class="filter">
                <!-- 2 默认第一个展示高亮 通过index和自定义的值做对比 动态绑定class -->
                <div :class="tabList.currentIndex == index ? 'active':''">{{item.name}}{{index}}</div>
                <!--  1 第一个不显示上下箭头 通过index值判断 -->
                <div class="icons" v-if="index !=0">
                  <!-- 4 判断箭头 什么时候有active 什么时候没有  -->
                  <i class="iconfont icon-caret-up" :class=" item.status == 1 ? 'active':''"></i>
                  <i class="iconfont icon-caret-down" :class=" item.status == 2 ? 'active':''"></i>
                </div>
              </div>
            </li>
          </ul>
        </div>

        <!-- 商品 -->
        <div class="shop-list">
          <ul>
            <li v-for="(item,index) in shopList" :key="index">
              <div class="shopImg">
                <img :src="item.imgUrl" alt />
                <span>{{item.title}}</span>
              </div>
              <div class="shopIntroduce">
                <p>{{item.introduce}}</p>
                <p>{{item.price}}元</p>
              </div>
            </li>
          </ul>
        </div>
      </div>
    </template>

<script>
import http from "@/common/api/request.js";
export default {
  data() {
    return {
      // 0  数据准备
      tabList: {
        currentIndex: 0,
        data: [
          // status 0 代表都不亮 1 代表上箭头高亮 2 代表下箭头亮
          {
            name: "综合",
          },
          {
            name: "价格",
            status: 0,
            key: "price",
          },
          {
            name: "销量",
            status: 0,
            key: "num",
          },
        ],
      },
      shopList: [
        // {
        //   id: 1,
        //   imgUrl: "../images/searchShop.png",
        //   title: "性价远超同价产品",
        //   introduce: "靠谱经典滇红300g",
        //   price: "68",
        // },
        // {
        //   id: 2,
        //   imgUrl: "../images/searchShop.png",
        //   title: "性价远超同价产品",
        //   introduce: "靠谱经典滇红300g",
        //   price: "68",
        // },
        // {
        //   id: 3,
        //   imgUrl: "../images/searchShop.png",
        //   title: "性价远超同价产品",
        //   introduce: "靠谱经典滇红300g",
        //   price: "68",
        // },
      ],
    };
  },
  created() {
    this.getData();
  },
  methods: {
    async getData() {
      await http
        .$axios({
          url: "/api/goods/shopList",
          params: {
            // 前端给后端传一个数据
            searchName: this.$route.query.key,
            ...this.orderBy, //9 调用计算属性 使用扩展运算符结构方式 最后形式 是 kv 形式传给后端
          },
        })
        .then((res) => {
          // console.log(res);
          this.shopList = res;
        });
    },

    // 判断 点击的是哪一个
    changeTab(index) {
      this.tabList.currentIndex = index;
      // console.log(index);
      //5  点击的下标 就是对应数据的哪一个
      let item = this.tabList.data[index];
      console.log(item);
      //6 点击的时候 先让所有 不是当前点击的项  status都变成0 然后让当前的变成index
      this.tabList.data.forEach((v, i) => {
        if (i != index) {
          v.status = 0;
        }
        // 7 判断改变当前状态值: 如果 index 和 currentIndex 相等
        if (index == this.tabList.currentIndex) {
          item.status = item.status == 1 ? 2 : 1;
        }

        // 发送请求(并且告诉后端 到底是升序还是降序) 通过key来定义数据 到底是价格 还是 销量
      });
    },
  },

  // 8  最后把这个计算属性 通过请求发送给后端
  computed: {
    orderBy() {
      //8.1 知道选的是哪个tab对象
      let obj = this.tabList.data[this.tabList.currentIndex];
      //8.2 根据选的tab 判断status 的值 是多来 来 判断是升序还是降序
      let val = obj.status == 1 ? "asc" : "desc";
      return { [obj.key]: val }; // 返回一个对象 price :ase  代表 价格升序
    },
  },

  // 监听路由 如果路由发生改变 就再请求查询一次
  watch: {
    $route() {
      this.getData();
    },
  },
};
</script>

<style scoped>
.search-list {
  display: flex;
  flex-direction: column;
}
/* 
.tab {
  display: flex;
  justify-content: space-around;
  align-items: center;
  font-size: 0.533333rem;
  margin: 0.266667rem 0;
} */
/* .filter {
  display: flex;
  justify-content: center;
  align-items: center;
} */

/* ul li {
  display: flex;
} */

ul {
  display: flex;
  justify-content: space-around;
}
.filter {
  display: flex;
}

.icons {
  display: flex;
  flex-direction: column;
}

.shopImg span {
  background-color: rgba(194, 206, 209, 0.5);
  padding-left: 0.266667rem;
}
.shopIntroduce {
  font-size: 0.4rem;
  padding-left: 0.266667rem;
  margin-top: 0.266667rem;
}

.shopIntroduce p:last-child {
  color: red;
  margin-top: 0.533333rem;
}
.shop-list ul {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  box-sizing: border-box;
}
.shop-list ul li {
  display: flex;
  width: 4.8rem;
  flex-direction: column;
  /* background-color: aqua; */
  margin: 0.053333rem;

  /* align-items: center; */
}
.shopImg {
  display: flex;
  flex-direction: column;
  font-size: 0.4rem;
}
.shop-list ul li img {
  width: 100%;
  height: 4.389333rem;
}

.active {
  color: red;
}
</style>

后端

后端这种取值方式第一次见有点懵逼
1. 获取前端发过来的数据 
// 创建搜索接口
router.get('/api/goods/shopList', function (req, res, next) {
  // 查看前端给后端传的数据 console.log(req.query);
  // 也可以这样获取    
 
  let [searchNames, orderName] = Object.keys(req.query);
  let [Name, order] = Object.values(req.query);

  console.log(searchNames, orderName, Name, order); // searchName num 绿茶 desc

  // let SearchNames = req.query.searchName;

  // 数据库进行 模糊查询
  connection.query('select * from shoplist where introduce like "%' + Name + '%" order by ' + orderName + ' ' + order + '', function (err, result) {
    // console.log(result);
    res.send({
      code: 0,
      data: result
    })
  })

})

mysql 表结构设计 zh代表综合

image.png

页面

image.png