Register Search shopcart trade store文件夹

Register

<template>
  <div class="register-container">
    <!-- 注册内容 -->
    <div class="register">
      <h3>
        注册新用户
        <span class="go"
          >我有账号,去 <a href="login.html" target="_blank">登陆</a>
        </span>
      </h3>
      <div class="content">
        <label>手机号:</label>
        <!-- <input type="text" placeholder="请输入你的手机号" v-model="phone" /> -->

        <input
          placeholder="请输入你的手机号"
          v-model="phone"
          name="phone"
          v-validate="{ required: true, regex: /^1\d{10}$/ }"
          :class="{ invalid: errors.has('phone') }"
        />
        <span class="error-msg">{
    
    {
    
     errors.first("phone") }}</span>
        <!-- <span class="error-msg">错误提示信息</span> -->
      </div>
      <div class="content">
        <label>验证码:</label>
        <!-- <input type="text" placeholder="请输入验证码" v-model="code" /> -->
        <input
          placeholder="请输入你的验证码"
          v-model="code"
          name="code"
          v-validate="{ required: true, regex: /^\d{6}$/ }"
          :class="{ invalid: errors.has('code') }"
        />
        <!-- <img ref="code" src="http://182.92.128.115/api/user/passport/code" alt="code"> -->
        <button style="height: 38px; width: 100px" @click="getCode">
          获取验证码
        </button>

        <span class="error-msg">{
    
    {
    
     errors.first("code") }}</span>
      </div>
      <div class="content">
        <label>登录密码:</label>
        <input
          placeholder="请输入你的登录密码"
          v-model="password"
          name="password"
          v-validate="{ required: true, regex: /^[0-9A-Za-z]{8,20}$/ }"
          :class="{ invalid: errors.has('password') }"
        />

        <span class="error-msg">{
    
    {
    
     errors.first("password") }}</span>
      </div>
      <div class="content">
        <label>确认密码:</label>

        <input
          placeholder="请输入你的确认密码"
          v-model="password1"
          name="password1"
          v-validate="{ required: true, is: password }"
          :class="{ invalid: errors.has('password1') }"
        />

        <span class="error-msg">{
    
    {
    
     errors.first("password1") }}</span>
      </div>
      <div class="controls">
        <!-- <input name="m1" type="checkbox" :checked="agree" @change="handler" /> -->
        <input
          v-model="agree"
          name="agree"
          type="checkbox"
       
          v-validate="{ required: true, tongyi: true }"
          :class="{ invalid: errors.has('agree') }"
        />
        <span>同意协议并注册《尚品汇用户协议》</span>
        <!-- <span class="error-msg">错误提示信息</span> -->
        <span class="error-msg">{
    
    {
    
     errors.first("agree") }}</span>
      </div>
      <div class="btn">
        <button @click="userRegister">完成注册</button>
      </div>
    </div>

    <!-- 底部 -->
    <div class="copyright">
      <ul>
        <li>关于我们</li>
        <li>联系我们</li>
        <li>联系客服</li>
        <li>商家入驻</li>
        <li>营销中心</li>
        <li>手机尚品汇</li>
        <li>销售联盟</li>
        <li>尚品汇社区</li>
      </ul>
      <div class="address">地址:北京市昌平区宏福科技园综合楼6</div>
      <div class="beian">京ICP备19006430</div>
    </div>
  </div>
</template>

<script>
export default {
    
    
  name: "Register",
  data() {
    
    
    return {
    
    
      //收集表单数据
      phone: "",
      code: "", //验证码
      password: "",
      password1: "",
      agree: true, //是否统一协议(默认同意)
    };
  },

  methods: {
    
    
    async getCode() {
    
    
      let {
    
     phone } = this; //解构
      // console.log(phone);
      //判断一下phone是不是空
      try {
    
    
        phone && (await this.$store.dispatch("getCode", phone));
        //  console.log(this.$store);
        this.code = this.$store.state.user.code;
      } catch (error) {
    
    
        alert(error.message);
      }
    },
    async userRegister() {
    
    
      //全部表单验证都成功了
      const success = await this.$validator.validateAll();
      if (success) {
    
    
         //全部表单验证都成功了,在向服务器发请求
        //解构参数
        let {
    
     phone, code, password, password1 } = this;
        try {
    
    
          if (password == password1 && phone && code) {
    
    
            await this.$store.dispatch("userRegister", {
    
    
              phone,
              code,
              password,
            });
            this.$router.push("/login");
          }
        } catch (error) {
    
    
          alert(error.message);
        }
      }
    },
    handler() {
    
    
      console.log(this.agree);
    },
  },
};
</script>

<style lang="less" scoped>
.register-container {
    
    
  .register {
    
    
    width: 1200px;
    height: 445px;
    border: 1px solid rgb(223, 223, 223);
    margin: 0 auto;

    h3 {
    
    
      background: #ececec;
      margin: 0;
      padding: 6px 15px;
      color: #333;
      border-bottom: 1px solid #dfdfdf;
      font-size: 20.04px;
      line-height: 30.06px;

      span {
    
    
        font-size: 14px;
        float: right;

        a {
    
    
          color: #e1251b;
        }
      }
    }

    div:nth-of-type(1) {
    
    
      margin-top: 40px;
    }

    .content {
    
    
      padding-left: 390px;
      margin-bottom: 18px;
      position: relative;

      label {
    
    
        font-size: 14px;
        width: 96px;
        text-align: right;
        display: inline-block;
      }

      input {
    
    
        width: 270px;
        height: 38px;
        padding-left: 8px;
        box-sizing: border-box;
        margin-left: 5px;
        outline: none;
        border: 1px solid #999;
      }

      img {
    
    
        vertical-align: sub;
      }

      .error-msg {
    
    
        position: absolute;
        top: 100%;
        left: 495px;
        color: red;
      }
    }

    .controls {
    
    
      text-align: center;
      position: relative;

      input {
    
    
        vertical-align: middle;
      }

      .error-msg {
    
    
        position: absolute;
        top: 100%;
        left: 495px;
        color: red;
      }
    }

    .btn {
    
    
      text-align: center;
      line-height: 36px;
      margin: 17px 0 0 55px;

      button {
    
    
        outline: none;
        width: 270px;
        height: 36px;
        background: #e1251b;
        color: #fff !important;
        display: inline-block;
        font-size: 16px;
      }
    }
  }

  .copyright {
    
    
    width: 1200px;
    margin: 0 auto;
    text-align: center;
    line-height: 24px;

    ul {
    
    
      li {
    
    
        display: inline-block;
        border-right: 1px solid #e4e4e4;
        padding: 0 20px;
        margin: 15px 0;
      }
    }
  }
}
</style>

Search

index.vue

<template>
  <div>
    <!-- 商品分类三级列表 -->
    <TypeNav />
    <div class="main">
      <div class="py-container">
        <!--bread面包屑,带有x的结构-->
        <div class="bread">
          <ul class="fl sui-breadcrumb">
            <li>
              <a href="#">全部结果</a>
            </li>
          </ul>
          <ul class="fl sui-tag">
            <!-- 分类的面包屑 -->
            <li class="with-x" v-if="searchParams.categoryName">
              {
    
    {
    
     searchParams.categoryName
              }}<i @click="deleteSearchParams"> ×</i>
            </li>
            <!-- 关键字的面包屑 -->
            <li class="with-x" v-if="searchParams.keyword">
              {
    
    {
    
     searchParams.keyword }}<i @click="deleteKeyword"> ×</i>
            </li>
            <!-- 品牌的面包屑 -->
            <li class="with-x" v-if="searchParams.trademark">
              {
    
    {
    
     searchParams.trademark.split(":")[1]
              }}<i @click="deleteTrademark"> ×</i>
            </li>
            <!-- 平台的售卖的属性值展示 -->
            <li
              class="with-x"
              v-for="(attrValue, index) in searchParams.props"
              :key="index"
            >
              {
    
    {
    
     attrValue.split(":")[1]
              }}<i @click="deleteAttrValue(index)"> ×</i>
            </li>
          </ul>
        </div>

        <!--selector-->
        <SearchSelector @trademarkInfo="trademarkInfo" @attrInfo="attrInfo" />

        <!--details-->
        <div class="details clearfix">
          <div class="sui-navbar">
            <div class="navbar-inner filter">
              <!-- 排序的结构 -->
              <ul class="sui-nav">
                <li :class="{ active: isOne }" @click="changeOrder(1)">
                  <a href="#"
                    >综合<span
                      v-show="isOne"
                      class="iconfont"
                      :class="{
    
    
                        'icon-direction-up': isAsc,
                        'icon-down_light': isDesc,
                      }"
                    ></span
                  ></a>
                </li>
                <li :class="{ active: isTwo }" @click="changeOrder(2)">
                  <a href="#"
                    >价格<span
                      v-show="isTwo"
                      class="iconfont"
                      :class="{
    
    
                        'icon-direction-up': isAsc,
                        'icon-down_light': isDesc,
                      }"
                    ></span>
                  </a>
                </li>
              </ul>
            </div>
          </div>
          <div class="goods-list">
            <!-- 销售产品列表 -->
            <ul class="yui3-g">
              <li
                class="yui3-u-1-5"
                v-for="(good, index) in goodsList"
                :key="good.id"
              >
                <div class="list-wrap">
                  <div class="p-img">
                    <!-- <a href="item.html" target="_blank"
                      ></a> -->

                    <router-link :to="`/detail/${good.id}`"
                      ><img v-lazy="good.defaultImg"
                    /></router-link>
                  </div>
                  <div class="price">
                    <strong>
                      <em>¥</em>
                      <i>{
    
    {
    
     good.price }}.00</i>
                    </strong>
                  </div>
                  <div class="attr">
                    <a
                      target="_blank"
                      href="item.html"
                      title="促销信息,下单即赠送三个月CIBN视频会员卡!【小米电视新品4A 58 火爆预约中】"
                      >{
    
    {
    
     good.title }}</a
                    >
                  </div>
                  <div class="commit">
                    <i class="command">已有<span>2000</span>人评价</i>
                  </div>
                  <div class="operate">
                    <a
                      href="success-cart.html"
                      target="_blank"
                      class="sui-btn btn-bordered btn-danger"
                      >加入购物车</a
                    >
                    <a href="javascript:void(0);" class="sui-btn btn-bordered"
                      >收藏</a
                    >
                  </div>
                </div>
              </li>
            </ul>
          </div>
          <!-- 分页器 -->
          <Pagination
            :pageNo="searchParams.pageNo"
            :pageSize="searchParams.pageSize"
            :total="total"
            :continues="5"
            @getPageNo="getPageNo"
          />
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import SearchSelector from "./SearchSelector/SearchSelector";
import {
    
     mapState } from "vuex";
import {
    
     mapGetters } from "vuex";
export default {
    
    
  name: "Search",

  data() {
    
    
    //带给服务器的数据
    return {
    
    
      searchParams: {
    
    
        //三级分类的id
        category1Id: "",
        category2Id: "",
        category3Id: "",
        //分类的名字
        categoryName: "",
        //关键字
        keyword: "",
        //排序:初始的状态应该是综合&降序
        order: "2:desc",
        pageNo: 1, //分页器数据,默认值是1
        //每页展示数据的个数
        pageSize: 10,
        //平台售卖的属性操作带的参数
        props: [],
        //品牌
        trademark: "",
      },
    };
  },
  components: {
    
    
    SearchSelector,
  },
  beforeMount() {
    
    
    /*在挂载之前把传来的参数整理好
     console.log(this.$route.params);
    this.searchParams.category1Id=this.$route.query.category1Id;
    this.searchParams.category2Id=this.$route.query.category2Id;
    this.searchParams.category3Id=this.$route.query.category3Id;
    this.searchParams.categoryName=this.$route.query.categoryName;
    this.searchParams.keyword=this.$route.params.keyword;*/
    Object.assign(this.searchParams, this.$route.query, this.$route.params);
    // console.log( "1111",Object.assign(this.searchParams,this.$route.query,this.$route.params));
  },
  mounted() {
    
    
    /*派发actions,先测试一下接口返回的数据格式,确保state定义的时候不出错(只执行一次)
     this.$store.dispatch("getSearchList",{})*/
    this.getData();
  },
  methods: {
    
    
    getData() {
    
    
      //把请求封装为一个函数,当需要调用的时候调用即可
      this.$store.dispatch("getSearchList", this.searchParams);
    },
    //删除分类名字
    deleteSearchParams() {
    
    
      /*1.修改传递给服务器的数据
      把这个地方设置为空串""和undefined的区别,设置undefined的字段不会被带给服务器*/
      this.searchParams.categoryName = undefined;
      this.searchParams.category1Id = undefined;
      this.searchParams.category2Id = undefined;
      this.searchParams.category3Id = undefined;
      // this.getData();不需要写这行也行,因为监视的时候也会发一个请求
      /*修改路径信息 */
      this.$router.push({
    
     name: "search", params: this.$route.params });
    },
    //删除关键字
    deleteKeyword() {
    
    
      this.searchParams.keyword = "";

      this.$bus.$emit("isclear"); //也可以不传参数;(传给header组件)
      //进行路由的跳转
      this.$router.push({
    
     name: "search", query: this.$route.query });
    },
    trademarkInfo(trademark) {
    
    
      // console.log("我是父组件",trademark);
      this.searchParams.trademark = `${
    
    trademark.tmId}:${
    
    trademark.tmName}`;
      // console.log(this.searchParams);
      //再次发请求
      this.getData();
    },
    deleteTrademark() {
    
    
      this.searchParams.trademark = undefined;
      this.getData(); //这里路径没变化,监听没有用,所以一定要再次请求服务器
    },
    //手机平台属性地方回调函数
    attrInfo(attr, attrValue) {
    
    
      // console.log(attr,attrValue);
      let props = `${
    
    attr.attrId}:${
    
    attrValue}:${
    
    attr.attrName}`;
      //判断新增的元素在数组中有没有
      if (this.searchParams.props.indexOf(props) == -1) {
    
    
        this.searchParams.props.push(props);
      }

      this.getData();
    },
    deleteAttrValue(index) {
    
    
      //知道索引值才可以删除呀
      // console.log(index);
      //再次整理参数,把要删掉的删除
      this.searchParams.props.splice(index, 1);
      this.getData();
    },

    changeOrder(flag) {
    
    
      let originOrder = this.searchParams.order;
      let originFlag = this.searchParams.order.split(":")[0];
      let originSort = this.searchParams.order.split(":")[1];

      let newOrder = "";
      //如果当前点击的就是active的那个,那就是要更改箭头了
      if (flag == originFlag) {
    
    
        newOrder = `${
    
    flag}:${
    
    originSort == "desc" ? "asc" : "desc"}`;
        // console.log(newOrder);
      }

      //如果当前点击的不是active那个,那就是要更改active
      else {
    
    
        newOrder = `${
    
    flag}:${
    
    "desc"}`;
        // console.log(newOrder);
      }
      this.searchParams.order = newOrder;
      this.getData();
    },
    //自定义事件,将当前那一页传递给父组件
    getPageNo(pageNo) {
    
    
      this.searchParams.pageNo = pageNo;
      this.getData();
    },
  },
  computed: {
    
    
    // ...mapState({ SearchList:(state)=>state.search.SearchList.goodsList}),
    //传递的数组,因为getters计算时没有划分模块的
    ...mapGetters(["goodsList"]),
    isOne() {
    
    
      return this.searchParams.order.indexOf("1") != -1; //表示包含1
    },
    isTwo() {
    
    
      return this.searchParams.order.indexOf("2") != -1; //表示包含2
    },
    isAsc() {
    
    
      return this.searchParams.order.indexOf("asc") != -1;
    },
    isDesc() {
    
    
      return this.searchParams.order.indexOf("desc") != -1;
    },
    ...mapState({
    
    
      total: (state) => state.search.SearchList.total,
    }),
  },

  //数据监听:监听组件实例身上的属性的属性值变化(从Vuex开发者工具看到有¥route属性)
  watch: {
    
    
    $route(to, from) {
    
    
      // console.log("2222",to,from);

      // this.searchParams = "";//万一keywords没改,给设置空了,这个地方就错了,一旦写了,后面一准出错上面的删除函数就出错
      // console.log("222",this.searchParams);
      this.searchParams.categoryName = undefined;
      this.searchParams.category1Id = undefined;
      this.searchParams.category2Id = undefined;
      this.searchParams.category3Id = undefined;
      Object.assign(this.searchParams, this.$route.query, this.$route.params);
      // console.log("333",Object.assign(this.searchParams,to.query,to.params));
      // console.log("444", this.searchParams);
      this.getData(); //再次发送Ajax请求
    },
  },
};
</script>

<style lang="less" scoped>
.main {
    
    
  margin: 10px 0;

  .py-container {
    
    
    width: 1200px;
    margin: 0 auto;

    .bread {
    
    
      margin-bottom: 5px;
      overflow: hidden;

      .sui-breadcrumb {
    
    
        padding: 3px 15px;
        margin: 0;
        font-weight: 400;
        border-radius: 3px;
        float: left;

        li {
    
    
          display: inline-block;
          line-height: 18px;

          a {
    
    
            color: #666;
            text-decoration: none;

            &:hover {
    
    
              color: #4cb9fc;
            }
          }
        }
      }

      .sui-tag {
    
    
        margin-top: -5px;
        list-style: none;
        font-size: 0;
        line-height: 0;
        padding: 5px 0 0;
        margin-bottom: 18px;
        float: left;

        .with-x {
    
    
          font-size: 12px;
          margin: 0 5px 5px 0;
          display: inline-block;
          overflow: hidden;
          color: #000;
          background: #f7f7f7;
          padding: 0 7px;
          height: 20px;
          line-height: 20px;
          border: 1px solid #dedede;
          white-space: nowrap;
          transition: color 400ms;
          cursor: pointer;

          i {
    
    
            margin-left: 10px;
            cursor: pointer;
            font: 400 14px tahoma;
            display: inline-block;
            height: 100%;
            vertical-align: middle;
          }

          &:hover {
    
    
            color: #28a3ef;
          }
        }
      }
    }

    .details {
    
    
      margin-bottom: 5px;

      .sui-navbar {
    
    
        overflow: visible;
        margin-bottom: 0;

        .filter {
    
    
          min-height: 40px;
          padding-right: 20px;
          background: #fbfbfb;
          border: 1px solid #e2e2e2;
          padding-left: 0;
          border-radius: 0;
          box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065);

          .sui-nav {
    
    
            position: relative;
            left: 0;
            display: block;
            float: left;
            margin: 0 10px 0 0;

            li {
    
    
              float: left;
              line-height: 18px;

              a {
    
    
                display: block;
                cursor: pointer;
                padding: 11px 15px;
                color: #777;
                text-decoration: none;
              }

              &.active {
    
    
                a {
    
    
                  background: #e1251b;
                  color: #fff;
                }
              }
            }
          }
        }
      }

      .goods-list {
    
    
        margin: 20px 0;

        ul {
    
    
          display: flex;
          flex-wrap: wrap;

          li {
    
    
            height: 100%;
            width: 20%;
            margin-top: 10px;
            line-height: 28px;

            .list-wrap {
    
    
              .p-img {
    
    
                padding-left: 15px;
                width: 215px;
                height: 255px;

                a {
    
    
                  color: #666;

                  img {
    
    
                    max-width: 100%;
                    height: auto;
                    vertical-align: middle;
                  }
                }
              }

              .price {
    
    
                padding-left: 15px;
                font-size: 18px;
                color: #c81623;

                strong {
    
    
                  font-weight: 700;

                  i {
    
    
                    margin-left: -5px;
                  }
                }
              }

              .attr {
    
    
                padding-left: 15px;
                width: 85%;
                overflow: hidden;
                margin-bottom: 8px;
                min-height: 38px;
                cursor: pointer;
                line-height: 1.8;
                display: -webkit-box;
                -webkit-box-orient: vertical;
                -webkit-line-clamp: 2;

                a {
    
    
                  color: #333;
                  text-decoration: none;
                }
              }

              .commit {
    
    
                padding-left: 15px;
                height: 22px;
                font-size: 13px;
                color: #a7a7a7;

                span {
    
    
                  font-weight: 700;
                  color: #646fb0;
                }
              }

              .operate {
    
    
                padding: 12px 15px;

                .sui-btn {
    
    
                  display: inline-block;
                  padding: 2px 14px;
                  box-sizing: border-box;
                  margin-bottom: 0;
                  font-size: 12px;
                  line-height: 18px;
                  text-align: center;
                  vertical-align: middle;
                  cursor: pointer;
                  border-radius: 0;
                  background-color: transparent;
                  margin-right: 15px;
                }

                .btn-bordered {
    
    
                  min-width: 85px;
                  background-color: transparent;
                  border: 1px solid #8c8c8c;
                  color: #8c8c8c;

                  &:hover {
    
    
                    border: 1px solid #666;
                    color: #fff !important;
                    background-color: #666;
                    text-decoration: none;
                  }
                }

                .btn-danger {
    
    
                  border: 1px solid #e1251b;
                  color: #e1251b;

                  &:hover {
    
    
                    border: 1px solid #e1251b;
                    background-color: #e1251b;
                    color: white !important;
                    text-decoration: none;
                  }
                }
              }
            }
          }
        }
      }

      .page {
    
    
        width: 733px;
        height: 66px;
        overflow: hidden;
        float: right;

        .sui-pagination {
    
    
          margin: 18px 0;

          ul {
    
    
            margin-left: 0;
            margin-bottom: 0;
            vertical-align: middle;
            width: 490px;
            float: left;

            li {
    
    
              line-height: 18px;
              display: inline-block;

              a {
    
    
                position: relative;
                float: left;
                line-height: 18px;
                text-decoration: none;
                background-color: #fff;
                border: 1px solid #e0e9ee;
                margin-left: -1px;
                font-size: 14px;
                padding: 9px 18px;
                color: #333;
              }

              &.active {
    
    
                a {
    
    
                  background-color: #fff;
                  color: #e1251b;
                  border-color: #fff;
                  cursor: default;
                }
              }

              &.prev {
    
    
                a {
    
    
                  background-color: #fafafa;
                }
              }

              &.disabled {
    
    
                a {
    
    
                  color: #999;
                  cursor: default;
                }
              }

              &.dotted {
    
    
                span {
    
    
                  margin-left: -1px;
                  position: relative;
                  float: left;
                  line-height: 18px;
                  text-decoration: none;
                  background-color: #fff;
                  font-size: 14px;
                  border: 0;
                  padding: 9px 18px;
                  color: #333;
                }
              }

              &.next {
    
    
                a {
    
    
                  background-color: #fafafa;
                }
              }
            }
          }

          div {
    
    
            color: #333;
            font-size: 14px;
            float: right;
            width: 241px;
          }
        }
      }
    }
  }
}
</style>

SearchSelector

<template>
  <div class="clearfix selector">
    <div class="type-wrap logo">
      <div class="fl key brand">品牌</div>
      <div class="value logos">
        <!-- 品牌 -->
        <ul class="logo-list">
          <li v-for="(trademark,index) in trademarkList" :key="trademark.tmId" @click="tradeMarkHandler(trademark)">{
    
    {
    
    trademark.tmName}}</li>
         
        </ul>
      </div>
      <div class="ext">
        <a href="javascript:void(0);" class="sui-btn">多选</a>
        <a href="javascript:void(0);">更多</a>
      </div>
    </div>
    <!-- 下面的其他属性 -->
    <div class="type-wrap" v-for="(attr,index) in attrsList" :key="attr.attrId">
      <!-- 属性名 -->
      <div class="fl key">{
    
    {
    
    attr.attrName}}</div>
      <div class="fl value">
        <!-- 属性值 -->
        <ul class="type-list">
          <li v-for="(attrValue,index) in attr.attrValueList" :key="index" @click="attrInfo(attr,attrValue)">
            <a>{
    
    {
    
    attrValue}}</a>
          </li>
         
        </ul>
      </div>
      <div class="fl ext"></div>
    </div>
   
  </div>
</template>

<script>
import {
    
    mapGetters} from"vuex"
  export default {
    
    
    name: 'SearchSelector',
    computed:{
    
    
      ...mapGetters(['trademarkList',"attrsList"])
    },
    methods:{
    
    
      tradeMarkHandler(trademark){
    
    
        //点击品牌,还需要整理参数,向服务器发请求获取响应的参数进行展示
        //在哪个组件向服务器发送请求,应该是父组件
        //因为父组件中searchParams参数是带给服务器参数,子组件把点击的哪个品牌,传给父--自定义事件
        this.$emit('trademarkInfo',trademark)
      },
      //平台售卖属性值的点击事件
      attrInfo(attr,attrValue){
    
    
        this.$emit("attrInfo",attr,attrValue);
      }
    }
  }
</script>

<style lang="less" scoped>
  .selector {
    
    
    border: 1px solid #ddd;
    margin-bottom: 5px;
    overflow: hidden;

    .logo {
    
    
      border-top: 0;
      margin: 0;
      position: relative;
      overflow: hidden;

      .key {
    
    
        padding-bottom: 87px !important;
      }
    }

    .type-wrap {
    
    
      margin: 0;
      position: relative;
      border-top: 1px solid #ddd;
      overflow: hidden;

      .key {
    
    
        width: 100px;
        background: #f1f1f1;
        line-height: 26px;
        text-align: right;
        padding: 10px 10px 0 15px;
        float: left;
      }

      .value {
    
    
        overflow: hidden;
        padding: 10px 0 0 15px;
        color: #333;
        margin-left: 120px;
        padding-right: 90px;

        .logo-list {
    
    
          li {
    
    
            float: left;
            border: 1px solid #e4e4e4;
            margin: -1px -1px 0 0;
            width: 105px;
            height: 52px;
            text-align: center;
            line-height: 52px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            font-weight: 700;
            color: #e1251b;
            font-style: italic;
            font-size: 14px;

            img {
    
    
              max-width: 100%;
              vertical-align: middle;
            }
          }
        }

        .type-list {
    
    
          li {
    
    
            float: left;
            display: block;
            margin-right: 30px;
            line-height: 26px;

            a {
    
    
              text-decoration: none;
              color: #666;
            }
          }
        }
      }

      .ext {
    
    
        position: absolute;
        top: 10px;
        right: 10px;

        .sui-btn {
    
    
          display: inline-block;
          padding: 2px 14px;
          box-sizing: border-box;
          margin-bottom: 0;
          font-size: 12px;
          line-height: 18px;
          text-align: center;
          vertical-align: middle;
          cursor: pointer;
          padding: 0 10px;
          background: #fff;
          border: 1px solid #d5d5d5;
        }

        a {
    
    
          color: #666;
        }
      }
    }
  }
</style>

shopcart

<template>
  <div class="cart">
    <h4>全部商品</h4>
    <div class="cart-main">
      <div class="cart-th">
        <div class="cart-th1">全部</div>
        <div class="cart-th2">商品</div>
        <div class="cart-th3">单价(元)</div>
        <div class="cart-th4">数量</div>
        <div class="cart-th5">小计(元)</div>
        <div class="cart-th6">操作</div>
      </div>
      <div class="cart-body">
        <ul
          class="cart-list"
          v-for="(cart, index) in CartInfoList"
          :key="cart.id"
        >
          <li class="cart-list-con1">
            <input
              type="checkbox"
              name="chk_list"
              :checked="cart.isChecked == 1"
              @click="handlerCheckedById(cart, $event)"
            />
          </li>
          <li class="cart-list-con2">
            <img :src="cart.imgUrl" />
            <div class="item-msg">{
    
    {
    
     cart.skuName }}</div>
          </li>

          <li class="cart-list-con4">
            <span class="price">{
    
    {
    
     cart.skuPrice }}.00</span>
          </li>
          <li class="cart-list-con5">
            <a
              href="javascript:void(0)"
              class="mins"
              @click="handlerNum('minus', -1, cart)"
              >-</a
            >
            <input
              autocomplete="off"
              type="text"
              :value="cart.skuNum"
              minnum="1"
              class="itxt"
              @change="handlerNum('change', $event.target.value * 1, cart)"
            />
            <a
              href="javascript:void(0)"
              class="plus"
              @click="handlerNum('add', 1, cart)"
              >+</a
            >
          </li>
          <li class="cart-list-con6">
            <span class="sum">{
    
    {
    
     cart.skuNum * cart.skuPrice }}</span>
          </li>
          <li class="cart-list-con7">
            <a class="sindelet" @click="deleteCartById(cart)">删除</a>
            <br />
            <a href="#none">移到收藏</a>
          </li>
        </ul>
      </div>
    </div>
    <!-- 下部位置 -->
    <div class="cart-tool">
      <div class="select-all">
        <input
          class="chooseAll"
          type="checkbox"
          :checked="isAllchecked && CartInfoList.length > 0"
          @change="CheckedAll($event)"
        />
        <span>全选</span>
      </div>
      <div class="option">
        <a @click="deleteAllCheckedCart">删除选中的商品</a>
        <a href="#none">移到我的关注</a>
        <a href="#none">清除下柜商品</a>
      </div>
      <div class="money-box">
        <div class="chosed">已选择 <span>0</span>件商品</div>
        <div class="sumprice">
          <em>总价(不含运费) :</em>
          <i class="summoney">{
    
    {
    
     totalPrice }}</i>
        </div>
        <div class="sumbtn">
          <!-- <a class="sum-btn"  target="_blank"  @click="$router.push('/trade')">结算</a> -->
          <router-link to="/trade" class="sum-btn">结算</router-link>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import {
    
     mapGetters } from "vuex";
import throttle from "lodash/throttle";
export default {
    
    
  name: "ShopCart",
  data() {
    
    
    return {
    
    
      num: "50",
    };
  },
  mounted() {
    
    
    //防止修改数据时,购物车的数据发多次
    this.getData();
  },
  methods: {
    
    
    getData() {
    
    
      this.$store.dispatch("getCartList");
    },
    //修改产品数量要节流
    handlerNum: throttle(async function (type, disNum, cart) {
    
    
      /*  type 代表三种类型中的哪一种类型
          disNum代表变化量:加1或者减1,或者input中最终的个数
          cart 中有id,可以区别是哪一个商品
      */
      //  console.log(type,disNum,cart);
      //向服务器发请求修改数量

      switch (type) {
    
    
        case "add":
          disNum = 1;
          break;
        case "minus":
          /* if (disNum > 1) {
            disNum = -1; //传值的只需要传入变化量,怎么操作后端
          } else {
            disNum = 0; //保持原来的数值不变
          }*/
          disNum = cart.skuNum > 1 ? -1 : 0;
          break;

        case "change":
          //如果有非法的(带汉字||负数)带给服务器0,也就是不变化
          if (isNaN(disNum) || disNum < 1) {
    
    
            disNum = 0;
          } else {
    
    
            //属于正常情况(小数:取整),带给服务器变化的量,永华输入进来的-产品的起始个数
            disNum = parseInt(disNum) - cart.skuNum;
          }
          break;
      }

      try {
    
    
        //代表的是修改服务器中的数据成功
        await this.$store.dispatch("addorUpdateShopCart", {
    
    
          skuId: cart.skuId,
          skuNum: disNum,
        });
        //修改成功之后,再一次获取服务器的数据展示
        this.getData();
      } catch (error) {
    
    
        //失败,
        alert(error.message);
      }
    }, 1000),


    async deleteCartById(cart) {
    
    
      try {
    
    
        //如果成功,接着发送请求
        await this.$store.dispatch("deleteCartListBySkuId", cart.skuId);
        this.getData();
      } catch (error) {
    
    
        alert(error.message);
      }
    },
    async handlerCheckedById(cart, event) {
    
    
      // console.log(event.target.checked);
      let isTrue = event.target.checked == true ? 1 : 0;
      // console.log(isChecked);
      try {
    
    
        //如果成功
        await this.$store.dispatch("checkedById", {
    
    
          skuId: cart.skuId,
          isChecked: isTrue,
        });

        this.getData();
      } catch (error) {
    
    
        alert(error.message);
      }
    },
    async deleteAllCheckedCart() {
    
    
      try {
    
    
        //如果成功删除
        await this.$store.dispatch("deleteAllCheckedCart"); //跟请求重名是可以的
        //再发请求
        this.getData();
      } catch (error) {
    
    
        alert(error.message);
      }
    },

    async CheckedAll(event) {
    
    
      //上面函数不写event也行
      // console.log(event.target.checked);
      let Checked = event.target.checked;
      try {
    
    
        await this.$store.dispatch("checkedAll", Checked);
        this.getData();
      } catch (error) {
    
    
        alert(error.message);
      }
    },
  },
  computed: {
    
    
    ...mapGetters(["CartList"]),
    //购物车数据
    CartInfoList() {
    
    
      return this.CartList.cartInfoList || [];
    },
    //计算购买产品的总价
    totalPrice() {
    
    
      let sum = 0;
      this.CartInfoList.forEach((item) => {
    
    
        sum += item.skuNum * item.skuPrice;
      });
      return sum;
    },
    //判断全选,如果上面的每一个都选中了这个地方要变成全选
    isAllchecked() {
    
    
      // 判断所有的isChecked是不是1,如果是,res=1,如果不是 res=false
      let res = this.CartInfoList.every((item) => {
    
    
        return item.isChecked == 1;
      });

      return res;
      // let count = 0;
      // let res =true;
      //  this.CartInfoList.forEach((item) => {
    
    
      //   if (item.isChecked != 1) {
    
    
      //     count++;
      //   }
      // });
      // if (count > 0) res = false;
      // return res;
    },
  },
};
</script>



<style lang="less" scoped>
.cart {
    
    
  width: 1200px;
  margin: 0 auto;

  h4 {
    
    
    margin: 9px 0;
    font-size: 14px;
    line-height: 21px;
  }

  .cart-main {
    
    
    .cart-th {
    
    
      background: #f5f5f5;
      border: 1px solid #ddd;
      padding: 10px;
      overflow: hidden;

      & > div {
    
    
        float: left;
      }

      .cart-th1 {
    
    
        width: 25%;

        input {
    
    
          vertical-align: middle;
        }

        span {
    
    
          vertical-align: middle;
        }
      }

      .cart-th2 {
    
    
        width: 25%;
      }

      .cart-th3,
      .cart-th4,
      .cart-th5,
      .cart-th6 {
    
    
        width: 12.5%;
      }
    }

    .cart-body {
    
    
      margin: 15px 0;
      border: 1px solid #ddd;

      .cart-list {
    
    
        padding: 10px;
        border-bottom: 1px solid #ddd;
        overflow: hidden;

        & > li {
    
    
          float: left;
        }

        .cart-list-con1 {
    
    
          width: 15%;
        }

        .cart-list-con2 {
    
    
          width: 35%;

          img {
    
    
            width: 82px;
            height: 82px;
            float: left;
          }

          .item-msg {
    
    
            float: left;
            width: 150px;
            margin: 0 10px;
            line-height: 18px;
          }
        }

        // .cart-list-con3 {
    
    
        //   width: 20.8333%;

        //   .item-txt {
    
    
        //     text-align: center;
        //   }
        // }

        .cart-list-con4 {
    
    
          width: 10%;
        }

        .cart-list-con5 {
    
    
          width: 17%;

          .mins {
    
    
            border: 1px solid #ddd;
            border-right: 0;
            float: left;
            color: #666;
            width: 6px;
            text-align: center;
            padding: 8px;
          }

          input {
    
    
            border: 1px solid #ddd;
            width: 40px;
            height: 33px;
            float: left;
            text-align: center;
            font-size: 14px;
          }

          .plus {
    
    
            border: 1px solid #ddd;
            border-left: 0;
            float: left;
            color: #666;
            width: 6px;
            text-align: center;
            padding: 8px;
          }
        }

        .cart-list-con6 {
    
    
          width: 10%;

          .sum {
    
    
            font-size: 16px;
          }
        }

        .cart-list-con7 {
    
    
          width: 13%;

          a {
    
    
            color: #666;
          }
        }
      }
    }
  }

  .cart-tool {
    
    
    overflow: hidden;
    border: 1px solid #ddd;

    .select-all {
    
    
      padding: 10px;
      overflow: hidden;
      float: left;

      span {
    
    
        vertical-align: middle;
      }

      input {
    
    
        vertical-align: middle;
      }
    }

    .option {
    
    
      padding: 10px;
      overflow: hidden;
      float: left;

      a {
    
    
        float: left;
        padding: 0 10px;
        color: #666;
      }
    }

    .money-box {
    
    
      float: right;

      .chosed {
    
    
        line-height: 26px;
        float: left;
        padding: 0 10px;
      }

      .sumprice {
    
    
        width: 200px;
        line-height: 22px;
        float: left;
        padding: 0 10px;

        .summoney {
    
    
          color: #c81623;
          font-size: 16px;
        }
      }

      .sumbtn {
    
    
        float: right;

        a {
    
    
          display: block;
          position: relative;
          width: 96px;
          height: 52px;
          line-height: 52px;
          color: #fff;
          text-align: center;
          font-size: 18px;
          font-family: "Microsoft YaHei";
          background: #e1251b;
          overflow: hidden;
        }
      }
    }
  }
}
</style>

trade

<template>
  <div class="trade-container">
    <h3 class="title">填写并核对订单信息</h3>
    <div class="content">
      <h5 class="receive">收件人信息</h5>
      <div
        class="address clearFix"
        v-for="(userAdd, index) in userAddress"
        :key="userAdd.id"
      >
        <span class="username" :class="{ selected: userAdd.isDefault == 1 }">{
    
    {
    
    
          userAdd.consignee
        }}</span>
        <p @click="changeDefault(userAdd, userAddress)">
          <span class="s1">{
    
    {
    
     userAdd.fullAddress }}</span>
          <span class="s2">{
    
    {
    
     userAdd.phoneNum }}</span>
          <span class="s3" v-show="userAdd.isDefault == 1">默认地址</span>
        </p>
      </div>

      <div class="line"></div>
      <h5 class="pay">支付方式</h5>
      <div class="address clearFix">
        <span class="username selected">在线支付</span>
        <span class="username" style="margin-left: 5px">货到付款</span>
      </div>
      <div class="line"></div>
      <h5 class="pay">送货清单</h5>
      <div class="way">
        <h5>配送方式</h5>
        <div class="info clearFix">
          <span class="s1">天天快递</span>
          <p>配送时间:预计810日(周三)09:00-15:00送达</p>
        </div>
      </div>
      <div class="detail">
        <h5>商品清单</h5>
        <ul
          class="list clearFix"
          v-for="(order, index) in orderInfo.detailArrayList"
          :key="order.skuId"
        >
          <li>
            <img :src="order.imgUrl" style="width: 100px; height: 100px" />
          </li>
          <li>
            <p>
              {
    
    {
    
     order.skuName }}
            </p>
            <h4>7天无理由退货</h4>
          </li>
          <li>
            <h3>{
    
    {
    
     order.orderPrice }}.00</h3>
          </li>
          <li>X{
    
    {
    
     order.skuNum }}</li>
          <li>有货</li>
        </ul>
      </div>
      <div class="bbs">
        <h5>买家留言:</h5>
        <textarea
          placeholder="建议留言前先与商家沟通确认"
          class="remarks-cont"
          v-model="msg"
        ></textarea>
      </div>
      <div class="line"></div>
      <div class="bill">
        <h5>发票信息:</h5>
        <div>普通发票(电子) 个人 明细</div>
        <h5>使用优惠/抵用</h5>
      </div>
    </div>
    <div class="money clearFix">
      <ul>
        <li>
          <b
            ><i>{
    
    {
    
     orderInfo.totalNum }}</i
            >件商品,总商品金额</b
          >
          <span>¥{
    
    {
    
     orderInfo.totalAmount }}.00</span>
        </li>
        <li>
          <b>返现:</b>
          <span>0.00</span>
        </li>
        <li>
          <b>运费:</b>
          <span>0.00</span>
        </li>
      </ul>
    </div>
    <div class="trade">
      <div class="price">
        应付金额:<span>¥{
    
    {
    
     orderInfo.totalAmount }}.00</span>
      </div>
      <div class="receiveInfo">
        寄送至:
        <span>{
    
    {
    
     userDefaultAddress.fullAddress }}</span>
        收货人:<span>{
    
    {
    
     userDefaultAddress.consignee }}</span>
        <span>{
    
    {
    
     userDefaultAddress.phoneNum }}</span>
      </div>
    </div>
    <div class="sub clearFix">
      <!-- <router-link  to="/pay"></router-link> -->
      <a class="subBtn" @click="submitOrder">提交订单</a>
    </div>
  </div>
</template>

<script>
import {
    
     mapState } from "vuex";
import {
    
     reqSubmitOrder } from "@/api";
export default {
    
    
  name: "Trade",
  data() {
    
    
    return {
    
    
      //收集买家的留言信息
      msg: "",
      //订单号
      orderId: "",
    };
  },
  mounted() {
    
    
    this.$store.dispatch("getUserAddress");
    this.$store.dispatch("getOrderInfo");
  },

  computed: {
    
    
    ...mapState({
    
    
      userAddress: (state) => {
    
    
        return state.trade.address;
      },
    }),
    ...mapState({
    
    
      orderInfo: (state) => {
    
    
        return state.trade.orderInfo;
      },
    }),
    //将来提交最终选中 的地址
    userDefaultAddress() {
    
    
      //find 查找数组当中符合提交的元素
      return this.userAddress.find((item) => item.isDefault == 1) || {
    
    }; //这个地方一定要加一个[],要不然会出错
    },
  },
  methods: {
    
    
    changeDefault(userAdd, userAddress) {
    
    
      //全部的isDefault为0,不传第二个参数也行,因为计算属性那个地方有
      userAddress.forEach((item) => {
    
    
        return (item.isDefault = 0);
      });
      userAdd.isDefault = 1;
    },
    //提交订单
    async submitOrder() {
    
    
      //交易编码
      let {
    
     tradeNo } = this.orderInfo;
      //其余六个必须携带的参数
      let data = {
    
    
        consignee: this.userDefaultAddress.consignee, //最终收集人的名字
        consigneeTel: this.userDefaultAddress.phoneNum,
        deliveryAddress: this.userDefaultAddress.fullAddress,
        paymentWay: "ONLINE", //支付方式
        orderComment: this.msg, //买家留言信息
        orderDetailList: this.orderInfo.detailArrayList, //商品清单
      };
      //需要带参数的:tradeNo
      let res = await this.$API.reqSubmitOrder(tradeNo, data);

      // console.log(this.$API);
      // console.log(result);
      if (res.code == 200) {
    
    
        this.orderId = res.data;
        //路由跳转
        // this.$router.push('/pay?orderId='+this.orderId)//都可以两种方式
        this.$router.push(`/pay?orderId=${
    
    this.orderId}`)
      }else{
    
    
        //提交的订单失败
        alert(res.data);
        console.log("trade界面的",res);
      }
    },
  },
};
</script>

<style lang="less" scoped>
.trade-container {
    
    
  .title {
    
    
    width: 1200px;
    margin: 0 auto;
    font-size: 14px;
    line-height: 21px;
  }

  .content {
    
    
    width: 1200px;
    margin: 10px auto 0;
    border: 1px solid rgb(221, 221, 221);
    padding: 25px;
    box-sizing: border-box;

    .receive,
    .pay {
    
    
      line-height: 36px;
      margin: 18px 0;
    }

    .address {
    
    
      padding-left: 20px;
      margin-bottom: 15px;

      .username {
    
    
        float: left;
        width: 100px;
        height: 30px;
        line-height: 30px;
        text-align: center;
        border: 1px solid #ddd;
        position: relative;
      }

      .username::after {
    
    
        content: "";
        display: none;
        width: 13px;
        height: 13px;
        position: absolute;
        right: 0;
        bottom: 0;
        background: url(./images/choosed.png) no-repeat;
      }

      .username.selected {
    
    
        border-color: #e1251b;
      }

      .username.selected::after {
    
    
        display: block;
      }

      p {
    
    
        width: 610px;
        float: left;
        line-height: 30px;
        margin-left: 10px;
        padding-left: 5px;
        cursor: pointer;

        .s1 {
    
    
          float: left;
        }

        .s2 {
    
    
          float: left;
          margin: 0 5px;
        }

        .s3 {
    
    
          float: left;
          width: 56px;
          height: 24px;
          line-height: 24px;
          margin-left: 10px;
          background-color: #878787;
          color: #fff;
          margin-top: 3px;
          text-align: center;
        }
      }

      p:hover {
    
    
        background-color: #ddd;
      }
    }

    .line {
    
    
      height: 1px;
      background-color: #ddd;
    }

    .way {
    
    
      width: 1080px;
      height: 110px;
      background: #f4f4f4;
      padding: 15px;
      margin: 0 auto;

      h5 {
    
    
        line-height: 50px;
      }

      .info {
    
    
        margin-top: 20px;

        .s1 {
    
    
          float: left;
          border: 1px solid #ddd;
          width: 120px;
          height: 30px;
          line-height: 30px;
          text-align: center;
          margin-right: 10px;
        }

        p {
    
    
          line-height: 30px;
        }
      }
    }

    .detail {
    
    
      width: 1080px;

      background: #feedef;
      padding: 15px;
      margin: 2px auto 0;

      h5 {
    
    
        line-height: 50px;
      }

      .list {
    
    
        display: flex;
        justify-content: space-between;

        li {
    
    
          line-height: 30px;

          p {
    
    
            margin-bottom: 20px;
          }

          h4 {
    
    
            color: #c81623;
            font-weight: 400;
          }

          h3 {
    
    
            color: #e12228;
          }
        }
      }
    }

    .bbs {
    
    
      margin-bottom: 15px;

      h5 {
    
    
        line-height: 50px;
      }

      textarea {
    
    
        width: 100%;
        border-color: #e4e2e2;
        line-height: 1.8;
        outline: none;
        resize: none;
      }
    }

    .bill {
    
    
      h5 {
    
    
        line-height: 50px;
      }

      div {
    
    
        padding-left: 15px;
      }
    }
  }

  .money {
    
    
    width: 1200px;
    margin: 20px auto;

    ul {
    
    
      width: 220px;
      float: right;

      li {
    
    
        line-height: 30px;
        display: flex;
        justify-content: space-between;

        i {
    
    
          color: red;
        }
      }
    }
  }

  .trade {
    
    
    box-sizing: border-box;
    width: 1200px;
    padding: 10px;
    margin: 10px auto;
    text-align: right;
    background-color: #f4f4f4;
    border: 1px solid #ddd;

    div {
    
    
      line-height: 30px;
    }

    .price span {
    
    
      color: #e12228;
      font-weight: 700;
      font-size: 14px;
    }

    .receiveInfo {
    
    
      color: #999;
    }
  }

  .sub {
    
    
    width: 1200px;
    margin: 0 auto 10px;

    .subBtn {
    
    
      float: right;
      width: 164px;
      height: 56px;
      font: 700 18px "微软雅黑";
      line-height: 56px;
      text-align: center;
      color: #fff;
      background-color: #e1251b;
    }
  }
}
</style>

store文件夹

index.js

import Vue from "vue"
import Vuex from "vuex"

Vue.use(Vuex);
/*
//state:仓库储存数据的地方
const state={};
//mutations:修改state的唯一手段
const mutations={};
//action:处理action,可以书写自己的业务逻辑,也可以处理异步
const actions={};
//getters:理解为计算属性,用于简化仓库数据,让组件获取仓库的数据更加方便
const getters={};

*/

// 引入小仓库
import home from "./home"
import search from "./search";
import detail from "./detail"
import shopcart from "./shopcart"
import user from "./user"
import trade from "./trade/trade.js"
//对外暴露Store类的一个实例
export default new Vuex.Store({
    
    
/*state,
mutations,
actions,
getters,*/

//实现Vuex仓库模块式开发存储数据
modules:{
    
    
    home,
    search,
    detail,
    shopcart,
    user,
    trade,
}
});

detail

import {
    
     reqGetDetailInfo, reqAddorUpdateShopCart } from "@/api"
import {
    
     getUUID } from "@/utils/uuid_token"

const state = {
    
    
    GoodInfo: [],
    //游客临时身份
    uuid_token: getUUID()
}
const mutations = {
    
    

    GETGOODINFO(state, GoodInfo) {
    
    
        state.GoodInfo = GoodInfo;
    }
}
const actions = {
    
    
    async GoodInfo({
    
     commit }, id) {
    
    
        let res = await reqGetDetailInfo(id)
        // console.log(res);
        if (res.code == 200) {
    
    
            commit("GETGOODINFO", res.data)
        }
    },


    /*
    将产品添加到购物车中
    因为action只能传两个参数,所以第二个参数我们使用对象的形式传递两个参数
    addorUpdateShopCart这个函数返回的是promise,要么成功,要么失败
    */
    async addorUpdateShopCart({
    
     commit }, {
    
     skuId, skuNum }) {
    
    
        let res = await reqAddorUpdateShopCart(skuId, skuNum);
        // console.log(res);
        // console.log(skuId,skuNum);
        //代表在服务器中加入购物车成功
        if (res.code == 200) {
    
    
            return 'ok';
        } else {
    
    
            return Promise.reject(new Error('faile'));
        }

    }

}
const getters = {
    
    

    categoryView() {
    
    
        return state.GoodInfo.categoryView || {
    
    };
    },
    skuInfo() {
    
    
        return state.GoodInfo.skuInfo || {
    
    }
    },
    spuSaleAttrList() {
    
    
        return state.GoodInfo.spuSaleAttrList || [];//因为它本身就是个数组
    }
}

export default {
    
    
    state, getters, actions, mutations
}

home

import {
    
     reqCategoryList, reqGetBannerList, reqGetFloorList } from "@/api";

//home模块的小仓库
const state = {
    
    
    //state 中的数据不要乱写
    categoryList: [],//根据接口的返回值初始化的
    bannerList: [],
    FloorList: [],//json文件最外面返回的是一个数组

};
const mutations = {
    
    
    CATEGOTYLIST(state, categoryList) {
    
    
        state.categoryList = categoryList;
    },
    BANNERLIST(state, bannerList) {
    
    
        state.bannerList = bannerList;
    },
    FLOORLIST(state, FloorList) {
    
    
        state.FloorList = FloorList

    },
};
const actions = {
    
    
    async categoryList({
    
     commit }) {
    
    //或者说这个地方写context,然后context。commit
        let res = await reqCategoryList();
        // console.log(res);//打印出来是一个promise,然后才使用async和await一起搭配
        if (res.code == 200) {
    
    
            commit("CATEGOTYLIST", res.data)
        }
    },
    async bannerList({
    
     commit }) {
    
    
        let res = await reqGetBannerList();//axios发送的数据都用用async
        // console.log(res);
        if (res.code == 200) {
    
    
            commit("BANNERLIST", res.data);
        }
    },
    async FloorList(context) {
    
    
        let res = await reqGetFloorList();
        // console.log(res);
        if (res.code == 200)
            context.commit("FLOORLIST", res.data);
    }
};
const getters = {
    
    

};

export default {
    
    
    state,
    mutations,
    actions,
    getters,
}

search

//search模块的小仓库
import {
    
     reqGetSearchInfo } from "@/api"

const state = {
    
    
    SearchList: {
    
    },//是数组还是对象,是由服务器决定的
};
const mutations = {
    
    
    GETSEARCHLIST(state, SearchList) {
    
    
        state.SearchList = SearchList;
    }
};
const actions = {
    
    
    async getSearchList({
    
    commit}, params = {
    
    }) {
    
    //默认值至少是一个空对象
        let res = await reqGetSearchInfo(params);
        //   console.log(res);
      if(res.code==200){
    
    
        commit("GETSEARCHLIST", res.data);
      }
    }
};

//为了简化数据而生(到时候从仓库中拿数据就很方便了)
const getters = {
    
    
/*当前state是当前仓库的state中所有数据,而不是大仓库中的数据
加入没网,就会返回undefined,是个空对象,所以要加一个[]
*/
    goodsList(state){
    
    
        return state.SearchList.goodsList||[];
    },
    trademarkList(state){
    
    
        return state.SearchList.trademarkList;
    },
    attrsList(state){
    
    
        return state.SearchList.attrsList;
    }

};

export default {
    
    
    state,
    mutations,
    actions,
    getters,
}

shopcart

import {
    
     reqGetCartList, reqDeleteCartById, reqCheckedById } from "@/api"

const actions = {
    
    
    async getCartList({
    
     commit }) {
    
    
        let res = await reqGetCartList();
        // console.log(res);//获取是否可以获取个人购物车信息
        if (res.code == 200) {
    
    
            commit("CARTLIST", res.data);
        }
    },
    //删除购物车某一个产品,也不需要服务器返回信息,只需要知道成功还是失败
    async deleteCartListBySkuId({
    
     commit }, skuId) {
    
    
        let res = await reqDeleteCartById(skuId);
        if (res.code == 200) {
    
    
            return 'ok'
        } else {
    
    
            return Promise.reject(new Error("Faile"));
        }
    },
    async checkedById({
    
     commit }, {
    
     skuId, isChecked }) {
    
    
        // console.log(skuId, isChecked);
        let res = await reqCheckedById(skuId, isChecked);
        //    console.log(res);
        if (res.code == 200) {
    
    
            return "ok"
        }
        else {
    
    
            Promise.reject(new Error("Faile"));
        }
    },
    /* deleteAllCheckedCart(context){
  /
            console.log(context);
          打印context,发现有
          {getters: {…}, state: {…}, rootGetters: {…}, dispatch: ƒ, commit: ƒ, …}
          其中有dispatch,可以调用仓库中其他的方法
          */
    deleteAllCheckedCart({
    
     dispatch, getters }) {
    
    
        let PromiseAll = [];//把得到的所有Promise保存在这个数组中
        getters.CartList.cartInfoList.forEach((item) => {
    
    

            if (item.isChecked) {
    
    
                let res = dispatch("deleteCartListBySkuId", item.skuId);
                //console.log(res);//每次这么调用返回的res都是promise
                PromiseAll.push(res);
            }
        })
        //如果PromiseAll这个数组中返回的都是成功的结果,那是.all方法返回的就是成功,有一个不成功,.all方法返回的就是不成功
        // console.log(Promise.all(PromiseAll));
        return Promise.all(PromiseAll)
    },
    checkedAll({
    
    dispatch,state},Checked){
    
    
        // console.log(dispatch,getters);
        // console.log(isChecked);
        let PromiseAll = [];
        let isTrue=Checked?1:0
        // console.log(isTrue);
        // getters.CartList.cartInfoList.forEach((item)=>{ getter+state都可以,要去Vue里面看具体的名字
            state.cartList[0].cartInfoList.forEach((item)=>{
    
    
            let res =  dispatch("checkedById",{
    
    skuId:item.skuId,isChecked:isTrue})
            PromiseAll.push(res);
        })

        return Promise.all(PromiseAll)
    }

}
const mutations = {
    
    
    CARTLIST(state, cartList) {
    
    
        state.cartList = cartList;
    }
}
const state = {
    
    
    cartList: [],
}
const getters = {
    
    
    CartList(state) {
    
    
        //所以,简化属性的时候可以重名吗?
        return state.cartList[0] || {
    
    };//cartList[0]是个对象{}
    }
}

export default {
    
    
    actions, mutations, getters, state
}

trade

import {
    
    reqAddressInfo,reqOrderInfo} from "@/api"
const actions={
    
    

    async getUserAddress({
    
    commit}){
    
    
       let res= await reqAddressInfo();
    //    console.log(res);
    if(res.code==200){
    
    
        commit("GETUSERADDRESS",res.data)
    }
    },
    async getOrderInfo({
    
    commit}){
    
    
        let res= await reqOrderInfo();
        // console.log(res);
        if(res.code==200){
    
    
            commit("GETORDERINFO",res.data)
        }
    }
   

}
const mutations={
    
    
    GETUSERADDRESS(state,address){
    
    
        state.address=address;
    },
    GETORDERINFO(state,orderInfo){
    
    
        state.orderInfo=orderInfo
    }
}
const state={
    
    
    address:[],
    orderInfo:{
    
    }
}
const getters={
    
    }

export default{
    
    
    actions, mutations, getters, state
}

user


//登录注册用的是同一个
import {
    
     reqGetCode, reqUserRegister, reqUserLogin, reqUSerInfo ,reqLogout} from "@/api";
import{
    
     setToken ,getToken,removeToken} from "@/utils/token"


const state = {
    
    
  code: "",//code初始条件下是个空字符串
  // token: "",
  token:getToken(),
  userInfo:{
    
    },
}

const mutations = {
    
    
  GETCODE(state, code) {
    
    
    state.code = code
  },
  USERLOGIN(state, token) {
    
    
    state.token = token;
  },
  GETUSERINFO(state, userInfo) {
    
    
    state.userInfo = userInfo;
  },
  CLEAR(state){
    
    
    //把仓库中先关用户信息情况
    state.userInfo={
    
    };
    state.token='';
    //本地存储信息情况
    removeToken();
  }
}

const actions = {
    
    
  async getCode({
    
     commit }, phone) {
    
    
    //获取验证码的接口:把验证码返回,正常情况下,发到手机上(费钱)
    let res = await reqGetCode(phone);
    // let res=phone;
    // console.log(res);
    if (res.code == 200) {
    
    
      commit("GETCODE", res.data)
      return "ok"

    } else {
    
    
      return Promise.reject(new Error("faile"))
    }
  },
  //用户注册的接口
  async userRegister({
    
     commit }, user) {
    
    
    let res = await reqUserRegister(user);
    // console.log(res);
    if (res.code == 200) {
    
    
      return 'ok'
    } else {
    
    
      return Promise.reject(new Error("faile"))
    }
  },
  //登录业务
  async userLogin({
    
     commit }, data) {
    
    
    let res = await reqUserLogin(data);
    //  console.log(res);
    /*服务器下发token,用户唯一标识符(uuid很像)
    将来经常通过带token找服务器要用户信息进行展示
    */
    if (res.code == 200) {
    
    
      //用户已经登录成功并且获取到token
      commit("USERLOGIN", res.data.token);
      //实现持久化存储token
      // localStorage.setItem("TOKEN",res.data.token)
      setToken(res.data.token);
      return "ok"
    } else {
    
    
      return Promise.reject(new Error("faile"))
    }
  },
  //获取用户信息
  async getUserInfo({
    
     commit }) {
    
    
    let res = await reqUSerInfo();
    // console.log(res);
    if (res.code == 200) {
    
    
      commit("GETUSERINFO", res.data)
      return "ok"
    
    } else {
    
    
      return Promise.reject(new Error("faile"))
    }
  },
  async userLogout({
    
    commit}){
    
    
    let res= await reqLogout();
    // console.log(res);
    if(res.code==200){
    
    
      commit("CLEAR")
      return "ok"
    }else{
    
    
      return Promise.reject(new Error("faile"))
    }

  }
}

const getters = {
    
    

}
export default {
    
    
  actions, mutations, getters, state
}

猜你喜欢

转载自blog.csdn.net/Kerryliuyue/article/details/125471932