vue京东案例 (搜索、详情、购物车、导航栏)

1.nav导航组件

nav导航组件`template`中
<template >
  <div>
    <div class="header">
      <van-search show-action placeholder="请输入搜索关键词" @click="gotosearch">
        <template #action>
          <div class="iconfont icon-gouwuche1-copy-copy" @click="gotogou"></div>
        </template>
      </van-search>
    </div>

    <div class="box">
      <van-row>
        <van-col span="6">
          <van-sidebar v-model="activeKey">
            <van-sidebar-item
              v-for="item  in nav1"
              :key="item.cid"
              :title="item.cname"
              @click="gotoNav2(item)"
            />
          </van-sidebar>
        </van-col>
        <van-col span="18">
          <van-grid :column-num="3">
            <van-grid-item
              v-for="item in nav2"
              :key="item.subcid"
              :icon="item.scpic"
              :text="item.subcname"
              @click="gotoList(item.subcid)"
            />
          </van-grid>
        </van-col>
      </van-row>
    </div>
  </div>
</template>
nav导航组件`script`中
<script>
export default {
     
  data() {
     
    return {
     
      activeKey: 0,
      nav1: [],
      nav2: [],
    };
  },
  created() {
     
    this.$axios.get(" http://api.kudesoft.cn/tdk/category", {
     }).then((res) => {
     
      this.nav1 = res.data.data.data;
      this.nav1.sort((a, b) => {
     
        return a.cid - b.cid;
      });
      console.log(res.data.data.data);
      this.nav2 = this.nav1[0].subcategories;
    });
  },
  methods: {
     
    gotoNav2(item) {
     
      this.nav2 = item.subcategories;
      this.activeKey = item.cid;
    },
    
    gotoList(id) {
     
      this.$router.push({
     
        path: "/list2",
        query: {
     
          id,
        },
      });
    },
    gotosearch() {
     
      this.$router.push({
     
        path: "/search",
      });
    },
    gotogou() {
     
      this.$router.push({
     
        path: "/cart",
      });
    },
  },
};
</script>
nav导航组件`style`中
<style scoped>
.van-search {
     
  overflow: hidden;
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  z-index: 100;
}
.box {
     
  margin-top: 50px;
}
</style>

2.商品列表页

商品列表页`template`中
<template>
  <div>
    <van-nav-bar title="商品列表" left-text="返回" left-arrow @click-left="onClickLeft" />

    <div class="box">
      <div @click="zonghepx" :class="{'active':isActive==1}">综合排序</div>
      <div @click="xiaoliang" :class="{'active':isActive==2}">销量</div>
      <div class="box-span" @click="jiage">
        <span class="red">价格</span>
        <span class="box-iconfont">
          <span class="iconfont icon-order-asce" :class="{'active':isActive==3}"></span>
          <span class="iconfont icon-paixu-shengxu" :class="{'active':isActive==4}"></span>
        </span>
      </div>
      <div>
        <van-dropdown-menu>
          <van-dropdown-item v-model="value1" :options="option1" @change="shopType" />
        </van-dropdown-menu>
      </div>
    </div>

    <ul>
      <li v-for="(item, index) in list" :key="index" @click="gotodetails(item.id)">
        <img :src="item.mainPic" width="100%" />
        <p>{
     {
     item.title}}</p>
        <span style="color:red"><span class="list-jiage">{
     {
     item.actualPrice}}</span>
        </span>
        <span class="list-yishou">已售:{
     {
     item.monthSales}}</span>
        <span>
          <van-tag mark type="danger" style="margin-left:10px">{
     {
     item.shopType == 1 ? '天猫':'淘宝'}}</van-tag>
        </span>
      </li>
    </ul>
  </div>
</template>
商品列表页`script`中
<script>
export default {
     
  data() {
     
    return {
     
      list: [],
      golist:[],
      value1: -1,
      option1: [
        {
      text: "店铺类型", value: -1 },
        {
      text: "淘宝", value: 0 },
        {
      text: "天猫", value: 1 }
      ],
      isActive: 1 //1为综合排序,2为销量排序,3价格升序,4价格降序
    };
  },
  created() {
     
    let id = this.$route.query.id;
    this.$axios
      .get("http://api.kudesoft.cn/tdk/goods", {
     
        params: {
     
        //   pageSize: 10,
          subcid: id
        }
      })
      .then(res => {
     
        console.log(res.data.data.data.list);
        this.list = res.data.data.data.list;
      });
  },
  methods: {
     
    onClickLeft() {
     
      this.$router.push({
     
        path: "/"
      });
    },
    gotodetails(id) {
     
      this.$router.push({
     
        path: "/xiangqing",
        query: {
     
          id
        }
      });
    },
    zonghepx() {
     
      this.isActive = 1;
      this.list.sort((a, b) => {
     
        return b.shopLevel - a.shopLevel;
      });
    },
    xiaoliang() {
     
      this.isActive = 2;
      this.list.sort((a, b) => {
     
        return b.monthSales - a.monthSales;
      });
    },
    jiage() {
     
      if (this.isActive < 3) {
     
        this.isActive = 3;

        this.list.sort((a, b) => {
     
          return a.actualPrice - b.actualPrice;
        });
      } else if (this.isActive == 3) {
     
        this.isActive = 4;

        this.list.sort((a, b) => {
     
          return b.actualPrice - a.actualPrice;
        });
      } else if ((this.isActive = 4)) {
     
        this.isActive = 3;

        this.list.sort((a, b) => {
     
          return a.actualPrice - b.actualPrice;
        });
      }
    },
    shopType(value) {
     
      console.log(value);
      this.list = [];
      if (value == -1) {
     
        let id = this.$route.query.id;
        this.$axios
          .get("http://api.kudesoft.cn/tdk/goods", {
     
            params: {
     
              subcid:id,
            //   pageSize: 10,
            }
          })
          .then(res => {
     
            
            this.list = res.data.data.data.list;
          });
      } else {
     
        let id = this.$route.query.id;
        this.$axios
          .get("http://api.kudesoft.cn/tdk/goods", {
     
            params: {
     
              subcid: id,
            //   pageSize: 10,
            }
          })
          .then(res=> {
     
            console.log(res.data.data.data.list);
           this.golist = res.data.data.data.list;
            this.golist.map(item => {
     
              if (item.shopType == value) {
     
                this.list.push(item);
              }
            });
          });
      }
    }
  }
};
</script>
商品列表页`style`中
<style scoped>
.red:hover {
     
  color: red;
}
.van-nav-bar {
     
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
}
.box {
     
  width: 100%;
  background-color: #fff;
  position: fixed;
  left: 0;
  right: 0;
  top: 44px;
  font-size: 14px;
  display: flex;
  justify-content: space-around;
  align-items: center;
}
ul {
     
  width: 95%;
  margin: 90px auto;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
  align-items: center;
}
li {
     
  margin-top: 10px;
  width: 45%;
  font-size: 13px;
}
li p {
     
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}
.list-jiage {
     
  font-size: 15px;
}
.list-yishou {
     
  font-size: 9px;
  float: right;
  color: gray;
}
.box-span {
     
  display: flex;
  align-items: center;
  justify-content: center;
}
.box-iconfont {
     
  display: flex;
  flex-direction: column;
}
.iconfont {
     
  font-size: 14px;
}
.active {
     
  color: red;
}
</style>

3.详情页组件

详情页组件template中
<template>
  <div>
    <h4>商品详情</h4>
    <van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
      <van-swipe-item v-for="(item, index) in xqList.imgs" :key="index">
        <img :src="item" />
      </van-swipe-item>
    </van-swipe>
    <p>{
     {
     xqList.title}}</p>
    <p>{
     {
     xqList.actualPrice}}</p>

    <van-goods-action>
      <van-goods-action-icon icon="chat-o" text="客服" />
      <van-goods-action-icon icon="cart-o" text="购物车" :badge="cart.length" @click="gotogou" />
      <van-goods-action-icon icon="star" text="已收藏" color="#ff5000" />
      <van-goods-action-button type="warning" @click="jia" text="加入购物车" />
      <van-goods-action-button type="danger" text="立即购买" />
    </van-goods-action>
  </div>
</template>
详情页组件script中
<script>
export default {
     
  data() {
     
    return {
     
      xqList: {
     },
      cart: [],
    };
  },
  created() {
     
    let id = this.$route.query.id;
    this.$axios
      .get("http://api.kudesoft.cn/tdk/details", {
     
        params: {
     
          id,
        },
      })
      .then((res) => {
     
        console.log(res.data.data.data);
        this.xqList = res.data.data.data;
        this.xqList.imgs = this.xqList.imgs.split(",");
      });

    if (localStorage.cart) {
     
      this.cart = JSON.parse(localStorage.cart);
    }
  },
  methods: {
     
    // 添加并去重
    jia() {
     
      // 设置一个布尔值来确认是否是第一次添加
      let show = true;

      // 遍历循环数组cart通过id来确认是否是多次添加,是就num++,并返回布尔值
      this.cart.map((item) => {
     
        if (item.gou.id == this.xqList.id) {
     
          //判断购物车中的数组的id来确认是否重复
          item.num++; //重复 就++
          show = false; //false 表示重复添加
          return;
        }
        
      });

      //第一次添加
      if (show) {
     
        this.cart.unshift({
     
          gou: this.xqList,
          num: 1
        });
      }

      //保存到本地
      localStorage.cart = JSON.stringify(this.cart);
    },
    gotogou() {
     
      this.$router.push({
     
        path: "/cart",
      });
    },
  },
};
</script>

详情页组件style中
<style scoped>
img {
     
  width: 95%;
  height: 280px;
}
.van-swipe__track {
     
  text-align: center;
}
</style>

4.购物车组件

购物车组件template中
<template>
  <div>
    <van-nav-bar left-text="返回" left-arrow @click-left="back" title="购物车" />

    <van-checkbox-group v-model="result" @change="bian">
      <van-swipe-cell v-for="(item, index) in cart" :key="index">
        <van-row align="center">
          <van-col span="2">
            <van-checkbox :name="item"></van-checkbox>
          </van-col>
          <van-col span="22">
            <van-card
              :price="item.gou.actualPrice"
              :desc="item.gou.dtitle"
              :title="item.gou.title"
              class="goods-card"
              :thumb="item.gou.mainPic"
            >
              <template #num>
                <van-stepper v-model="item.num" theme="round" button-size="22" disable-input />
              </template>
            </van-card>
          </van-col>
        </van-row>
        <template #right>
          <van-button square text="删除" type="danger" class="delete-button" @click="del(index)" />
        </template>
      </van-swipe-cell>
    </van-checkbox-group>

    <van-submit-bar :price="zong" button-text="提交订单">
      <van-checkbox v-model="checked" @click="xuan">全选</van-checkbox>
    </van-submit-bar>
  </div>
</template>
购物车组件script中
<script>
export default {
     
  data() {
     
    return {
     
      cart: [],
      result: [],
      checked: false, //全选绑定的布尔值
    };
  },
  computed: {
     
    zong() {
     
      let zong = 0;
      // 计算result数组的总价
      this.result.map((item) => {
     
        // 乘以100是因为提交订单栏默认是分
        zong += item.gou.actualPrice * 100 * item.num;
      });
      // 友情提醒:不要忘记return
      return zong;
    },
  },
  created() {
     
    if (localStorage.cart) {
     
      this.cart = JSON.parse(localStorage.cart);
    }
  },
  methods: {
     
    back() {
     
      window.history.back();
    },
    xuan() {
     
      if (this.checked) {
     
        this.result = this.cart;
      } else {
     
        this.result = [];
      }
    },
    // 当result数组发生变化时要做的事
    bian() {
     
      // 当result数组长度和list数组的长度相同时
      if (this.result.length == this.cart.length) {
     
        this.checked = true; //把全选的布尔值变为true
      } else {
     
        this.checked = false; //否则变为false
      }
    },
    del(index) {
     
      let del = this.cart.splice(index, 1);
      this.result.map((item, index) => {
     
        if (item.gou.id == del[0].gou.id) {
     
          this.result.splice(index, 1);
        }
      });
      this.save();
    },
    save() {
     
      localStorage.cart = JSON.stringify(this.cart);
    },
  },
};
</script>
购物车组件style中
<style>
.goods-card {
     
  margin: 0;
  background-color: white;
}

.delete-button {
     
  height: 100%;
}
.van-col--2 {
     
  margin-top: 45px;
}
</style>

5.搜索组件

搜索组件template中
<template>
  <div>
    <van-search
      v-model="kw"
      autofocus
      show-action
      placeholder="请输入搜索关键词"
      @search="sousuo"
      @input="inputValue"
      @keydown.enter="sousuo()"
    >
      <template #action>
        <div class="iconfont icon-gouwuche1-copy-copy" @click="gotogou"></div>
      </template>
      <template #left>
        <div class="iconfont icon-fanhui" @click="gotohome"></div>
      </template>
    </van-search>
    <div class="body" v-if="show">
      <b>搜索记录</b>
      <van-icon name="delete" @click="qk" />
      <br />
      <div class="jilu">
        <span v-for="(item, index) in hisList" :key="index" @click="clickKw(item)">{
     {
     item}}</span>
      </div>
    </div>

    <div class="hot-keywords" v-if="!show">
      <van-cell-group>
        <van-cell
          v-for="(item, index) in hot"
          :key="index"
          :title="item.kw"
          @click="clickKw(item.kw)"
        />
      </van-cell-group>
    </div>
  </div>
</template>
搜索组件script中
<script>
export default {
     
  data() {
     
    return {
     
      kw: "",
      hisList: [], //搜索历史数组
      show: true,
      hot: [], //热搜词
    };
  },
  created() {
     
    let hisList = localStorage.hisList;
    if (hisList) {
     
      this.hisList = JSON.parse(hisList);
    }
  },
  methods: {
     
    gotohome() {
     
      this.$router.push({
     
        path: "/",
      });
    },
    sousuo() {
     
      if (this.kw.trim() == "") {
     
        return;
      }
      if (!this.hisList.includes(this.kw)) {
     
        this.hisList.unshift(this.kw);
        this.save();
      }
      if (this.hisList && this.hisList.length && this.hisList.length > 5) {
     
        this.hisList = this.hisList.splice(0, 5);
        this.save();
      }

      this.$router.push({
     
        path: "/list",
        query: {
     
          kw: this.kw,
        },
      });
    },
    inputValue(kw) {
     
      if (kw) {
     
        this.show = false;
        this.hot = [];
        this.$axios.get("/data2.json").then((res) => {
     
          let List = res.data.data.data;
          List.map((item) => {
     
            if (item.kw.includes(kw)) {
     
              this.hot.push(item);
            }
          });
        });
      } else {
     
        this.show = true;
      }
    },
    save() {
     
      localStorage.hisList = JSON.stringify(this.hisList);
    },
    clickKw(kw) {
     
      this.kw = kw;
      this.sousuo();
    },
    gotogou() {
     
      this.$router.push({
     
        path: "/cart",
      });
    },
    qk() {
     
      this.$dialog
        .confirm({
     
          message: "确定要清空记录吗?",
        })
        .then(() => {
     
          this.hisList = [];
          this.save();
        });
    },
  },
};
</script>
搜索组件style中
<style scoped>
.van-icon-delete {
     
  float: right;
}
.body {
     
  width: 95%;
  margin: 0 auto;
  /* margin-top: 55px; */
}
.jilu {
     
  margin-top: 5px;
  display: flex;
}
.jilu span {
     
  border-radius: 3px;
  padding: 3px 12px;
  margin-left: 5px;
  background-color: #eeeeee;
  font-size: 12px;
  color: gray;
}
</style>

6.搜索到的列表

搜索列表template中
<template>
  <div>
       <van-nav-bar left-text="返回" left-arrow @click-left="back" />
      <ul>
      <li v-for="(item, index) in shoulist" :key="index" @click="gotodetails(item.id)">
        <img :src="item.mainPic" width="100%" />
        <p>{
     {
     item.title}}</p>
        <span style="color:red"><span class="list-jiage">{
     {
     item.actualPrice}}</span>
        </span>
        <span class="list-yishou">已售:{
     {
     item.monthSales}}</span>
        <span>
          <van-tag mark type="danger" style="margin-left:10px">{
     {
     item.shopType == 1 ? '天猫':'淘宝'}}</van-tag>
        </span>
      </li>
    </ul>
  </div>
</template>
搜索列表script中
<script>
export default {
     
  data() {
     
    return {
     
    //   list: [], //临时保存数据数组
      shoulist: [], //要显示数据的数组
    };
  },
  created(){
     
this.$axios.get('http://api.kudesoft.cn/tdk/goods',{
     

}).then(res=>{
     
     let kw = this.$route.query.kw
    let List=res.data.data.data.list
    if(kw){
     
        List.map(item=>{
     
            if(item.title.includes(kw)){
     
                this.shoulist.push(item)
            }
        })
    }else{
     
        this.shoulist=List
    }
})
  },
  methods: {
     
    gotodetails(id) {
     
      this.$router.push({
     
        path: "/xiangqing",
        query: {
     
          id,
        },
      });
      console.log(id);
    },
    back(){
     
        window.history.back()
    }
  },
};
</script>
搜索列表style中
<style scoped>
ul {
     
  width: 90%;
  margin: 0px auto;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
}
li {
     
  margin-top: 10px;
  width: 45%;
  font-size: 13px;
}
li p {
     
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}
.list-jiage {
     
  font-size: 15px;
}
.list-yishou {
     
  font-size: 9px;
  float: right;
  color: gray;
}
</style>

你可能感兴趣的:(vue,vue,json,javascript,vue.js)