vue实例:监听购物车数量变化、金额变化、物品模糊查询、计算属性的应用和分页功能的实现----纯手写

Vue中的计算属性是什么,为什么要用计算属性,有什么好处,computed计算属性和methods方法有什么区别

在模板中放入太多的逻辑会让模板过重且难以维护,在需要对数据进行复杂处理,且可能多次使用的情况下,尽量采取计算属性的方式。好处:①使得数据处理结构清晰;②依赖于数据,数据更新,处理结果自动更新;③计算属性内部this指向vm实例;④在template调用时,直接写计算属性名即可;⑤常用的是getter方法,获取数据,也可以使用set方法改变数据;⑥相较于methods,不管依赖的数据变不变,methods都会重新计算,但是依赖数据不变的时候computed从缓存中获取,不会重新计算。


效果图 

 实战例子:

代码块部分

<template>
  <div class="main">
    <div class="hand">
      <label>商品名称</label>
      <input type="text" placeholder="请输入查询内容" v-model="inputs" />
      <p>监听购物车数量变化、金额变化、物品模糊查询、计算属性的应用</p>
    </div>
    <div class="table">
      <table cellpadding="0" cellspacing="0">
        <tr>
          <th>
            <input type="checkbox" v-model="allCheck" @change="allClick" />
          </th>
          <th>编号</th>
          <th>商品图片</th>
          <th>商品名称</th>
          <th>商品数量</th>
          <th>商品单价(元)</th>
          <th>商品金额(元)</th>
        </tr>
        <tr v-for="(item, index) in searchData" :key="index">
          <td>
            <input type="checkbox" v-model="item.check" @click="checkClick" />
          </td>
          <td>{{ index + 1 }}</td>
          <td><img :src="item.imgUrl" alt="" /></td>
          <td>{{ item.name }}</td>
          <td>
            <div class="action">
              <span @click="reduce(item)">-</span>
              <span>{{ item.count }}</span>
              <span @click="add(item)">+</span>
            </div>
          </td>
          <td>{{ item.price | priceFilter(2) }}</td>
          <td>{{ (item.count * item.price) | priceFilter(2) }}</td>
        </tr>
      </table>
      <div class="hint">
        <span>
          {{ totalCount }}件商品总计(不含运费){{ totalPrice | priceFilter(2) }}
        </span>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      inputs: "",
      allCheck: false,
      dataInfo: [
        {
          name: "桃子",
          count: 0,
          price: 22.11,
          check: false,
          imgUrl:
            "https://img-blog.csdnimg.cn/7468e3fe65d549ac87d6f7ea40d831a6.png",
        },
        {
          name: "龙眼",
          count: 0,
          price: 9.01,
          check: false,
          imgUrl:
            "https://img-blog.csdnimg.cn/501ba15a36b94712b4a723dcfabe9521.png",
        },
        {
          name: "橘子",
          count: 0,
          price: 8.12,
          check: false,
          imgUrl:
            "https://img-blog.csdnimg.cn/7e681c2a7bc34dd98e67d39a370a2283.png",
        },
        {
          name: "芒果",
          count: 0,
          price: 6.01,
          check: false,
          imgUrl:
            "https://img-blog.csdnimg.cn/3d0e879501ad43ae823c6d33dc7e7a89.png",
        },
        {
          name: "提子",
          count: 0,
          price: 20.19,
          check: false,
          imgUrl:
            "https://img-blog.csdnimg.cn/b99515cb80b24ebe931669cdfc77d0a2.png",
        },
        {
          name: "蛇果",
          count: 0,
          price: 10.11,
          check: false,
          imgUrl:
            "https://img-blog.csdnimg.cn/c620d20124e346fa93407c7ae9ab13b6.png",
        },
        {
          name: "猕猴桃",
          count: 0,
          price: 30.11,
          check: false,
          imgUrl:
            "https://img-blog.csdnimg.cn/28c844412cd9486b968242dcc34b27bd.png",
        },
        {
          name: "苹果",
          count: 0,
          price: 10.01,
          check: false,
          imgUrl:
            "https://img-blog.csdnimg.cn/b21b6c6ec4fd4be1a3467adf3e9fc460.png",
        },
        {
          name: "椰子",
          count: 0,
          price: 17.15,
          check: false,
          imgUrl:
            "https://img-blog.csdnimg.cn/2daaa4a37d174b7ea8d719a93f9f8130.png",
        },
        {
          name: "哈密瓜",
          count: 0,
          price: 13.14,
          check: false,
          imgUrl:
            "https://img-blog.csdnimg.cn/25b9bf8e35324f028499e2ae1f4f2b19.png",
        },
        {
          name: "西瓜",
          count: 0,
          price: 8.15,
          check: false,
          imgUrl:
            "https://img-blog.csdnimg.cn/aff0d0181c2a4841b549466df16d4174.png",
        },
        {
          name: "梨子",
          count: 0,
          price: 4.19,
          check: false,
          imgUrl:
            "https://img-blog.csdnimg.cn/012638d866af4f939efd0b35507a5053.png",
        },
        {
          name: "火龙果",
          count: 0,
          price: 20.11,
          check: false,
          imgUrl:
            "https://img-blog.csdnimg.cn/0afbb3ef68ba42d3b4097ec2871b55df.png",
        },
        {
          name: "车厘子",
          count: 0,
          price: 50.1,
          check: false,
          imgUrl:
            "https://img-blog.csdnimg.cn/9baeef4238b24b9382172be32c00221c.png",
        },
      ],
    };
  },
  filters: {
    priceFilter: function (type, n) {
      //过滤器
      return "¥" + type.toFixed(n);
    },
  },
  computed: {
    totalCount: function () {
      //总件数
      var n = 0;
      for (var i = 0; i < this.searchData.length; i++) {
        if (this.searchData[i].check) {
          n += this.searchData[i].count;
        }
      }
      return n;
    },
    totalPrice: function () {
      //总价
      var n = 0;
      for (var i = 0; i < this.searchData.length; i++) {
        if (this.searchData[i].check) {
          n += this.searchData[i].count * this.searchData[i].price;
        }
      }
      return n;
    },
    searchData: function () {
      //查询
      if (!this.inputs) {
        return this.dataInfo;
      }
      return this.dataInfo.filter((item) => {
        return item.name.includes(this.inputs);
      });
    },
  },
  methods: {
    add(item) {
      //加加
      item.count = item.count + 1;
    },
    reduce(item) {
      //减减
      if (item.count > 0) {
        item.count = item.count - 1;
      }
    },
    allClick() {
      this.dataInfo.forEach((item) => {
        item.check = this.allCheck;
      });
    },
    checkClick() {
      var n = this.dataInfo.filter((item) => {
        return item.check == true;
      }).length;
      console.log(n, this.dataInfo.length - 1);
      if (n == this.dataInfo.length - 1) {
        this.allCheck = true;
      } else {
        this.allCheck = false;
      }
    },
  },
};
</script>
<style scoped>
* {
  padding: 0;
  margin: 0;
  user-select: none;
}
.hand {
  display: flex;
  padding: 20px 10px;
  box-sizing: border-box;
  border: 1px solid #c0c4cc;
  border-bottom: none;
  position: relative;
  border-top-left-radius: 10px;
  border-top-right-radius: 10px;
}

.hand label {
  font-size: 10px;
  color: #fff;
  background-color: #409eff;
  padding: 0 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "宋体";
  height: 27px;
  line-height: 27px;
}

.hand input {
  font-size: 12px;
  color: #666;
  box-sizing: border-box;
  padding: 0 8px;
  line-height: 27px;
  height: 27px;
  border: none;
  border: 1px solid #c0c4cc;
  outline: none;
  font-family: "宋体";
}

.hand p {
  font-size: 20px;
  color: #777;
  font-weight: bold;
  font-family: "宋体";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.table th,
td {
  border-left: 1px solid #c0c4cc;
  border-bottom: 1px solid #c0c4cc;
  text-align: center;
  font-size: 15px;
  color: #666;
  font-family: "宋体";
}

.table th {
  padding: 25px 0;
}

.table table {
  width: 100%;
  border: 1px solid #c0c4cc;
  border-left: none;
  border-bottom: none;
}

.table input {
  text-align: center;
}

.table .action span {
  font-size: 14px;
  color: #000;
  border: 1px solid #c8c7cc;
  display: inline-block;
  line-height: 25px;
  width: 30px;
  text-align: center;
  box-sizing: border-box;
}

.table .action span:nth-child(2) {
  border-left: none;
  border-right: none;
}

.table img {
  width: 100px;
  height: 100px;
}

.hint span {
  font-size: 20px;
  color: #222;
  border: 1px solid #c0c4cc;
  border-top: none;
  text-align: center;
  line-height: 60px;
  letter-spacing: 2px;
  display: block;
  font-family: "宋体";
}
</style>

 (2).分页功能

<template>
  <div class="main">
    <div class="hand">
      <p>商品信息统计表(商品一共{{ rows }}件)</p>
    </div>
    <div class="table">
      <table cellpadding="0" cellspacing="0">
        <tr>
          <th>商品序号</th>
          <th>商品图片</th>
          <th>商品名称</th>
          <th>商品原价</th>
          <th>商品现价</th>
        </tr>
        <tr v-for="(item, index) in list" :key="index">
          <td>{{ (Total - 1) * page + index + 1 }}</td>
          <td>
            <img :src="item.product_img_url" v-if="item.product_img_url" />
            <img v-else />
          </td>
          <td>{{ item.product_name }}</td>
          <td>{{ item.product_price | priceFilter(2) }}</td>
          <td>{{ item.product_uprice | priceFilter(1) }}</td>
        </tr>
      </table>
      <div class="hint">
        <div class="laypage">
          <div class="prew" @click="prew()">
            <span>-</span>
          </div>
          <div class="num">
            <span
              v-for="(item, index) in psges"
              :key="index"
              @click="click(item)"
              :class="item == Total ? 'active' : ''"
              >{{ item }}</span
            >
          </div>
          <div class="last" @click="next()">
            <span>+</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      list: [], //展示数据
      rows: 1, //总数据
      pageTotal: 1, //总页数
      Total: 1, //当前的页数
      page: 8, //条数
    };
  },
  methods: {
    getList(v) {
      this.Total = v || this.Total;
      this.$axios({
        method: "get",
        url: `http://1.117.165.21:7002/home/page/${this.Total}/${this.page}`,
      })
        .then((res) => {
          console.log(res);
          this.list = res.data.data; //赋值
          this.rows = res.data.rows; //总数据
          this.pageTotal = res.data.pageTotal; //总页数
        })
        .catch((error) => {
          console.log(error);
        });
    },
    click(v) {
      this.getList(v);
    },
    prew() {
      if (this.Total > 1) {
        this.Total--;
        this.getList();
      }
    },
    next() {
      if (this.Total < this.pageTotal) {
        this.Total++;
        this.getList();
      }
    },
  },
  mounted() {
    this.getList();
  },
  filters: {
    priceFilter(type, n) {
      //保留两位小数
      if (typeof type == "undefined") {
        return type;
      } else {
        return "¥" + type.toFixed(n);
      }
    },
  },
  computed: {
    psges() {
      var pageTotal = this.pageTotal;
      var Total = this.Total;
      if (Total <= 5) {
        return [1, 2, 3, 4, 5, 6, 7, 8, 9, "...", pageTotal];
      } else if (Total >= pageTotal - 5) {
        return [
          1,
          "...",
          pageTotal - 8,
          pageTotal - 7,
          pageTotal - 6,
          pageTotal - 5,
          pageTotal - 4,
          pageTotal - 3,
          pageTotal - 2,
          pageTotal - 1,
          pageTotal,
        ];
      } else {
        return [
          1,
          "...",
          Total - 3,
          Total - 2,
          Total - 1,
          Total,
          Total + 1,
          Total + 2,
          Total + 3,
          "...",
          pageTotal,
        ];
      }
    },
  },
};
</script>
<style scoped>
* {
  padding: 0;
  margin: 0;
  user-select: none;
  font-size: 0;
}
.main {
  width: 80%;
  margin: 0 auto;
}
.hand {
  padding: 10px;
  box-sizing: border-box;
  border: 1px solid #c0c4cc;
  border-bottom: none;
  border-top-left-radius: 10px;
  border-top-right-radius: 10px;
}

.hand p {
  font-size: 20px;
  color: #777;
  font-weight: bold;
  font-family: "宋体";
  line-height: 40px;
}

.table th,
td {
  border-left: 1px solid #c0c4cc;
  border-bottom: 1px solid #c0c4cc;
  text-align: center;
  font-size: 15px;
  color: #666;
  font-family: "宋体";
}

.table th {
  padding: 20px 0;
}

.table img {
  width: 60px;
  height: 60px;
  padding: 10px 0;
}

.table table {
  width: 100%;
  border: 1px solid #c0c4cc;
  border-left: none;
  border-bottom: none;
}

.table input {
  text-align: center;
}

.table .action span {
  font-size: 14px;
  color: #000;
  border: 1px solid #c8c7cc;
  display: inline-block;
  line-height: 25px;
  width: 30px;
  text-align: center;
  box-sizing: border-box;
}

.table .action span:nth-child(2) {
  border-left: none;
  border-right: none;
}

.hint {
  border: 1px solid #c0c4cc;
  border-top: none;
  padding: 20px;
  box-sizing: border-box;
}

.hint .laypage {
  margin: 0 auto;
  display: flex;
  width: 35%;
}

.hint .laypage .prew span {
  padding: 0 15px;
}

.hint .laypage .last span {
  padding: 0 15px;
}

.hint .laypage .num {
  display: flex;
  flex: 1;
}

.hint span {
  font-size: 20px;
  color: #222;
  border: 1px solid #c0c4cc;
  text-align: center;
  line-height: 40px;
  letter-spacing: 2px;
  display: block;
  font-family: "宋体";
  flex: 1;
}
.hint span.active {
  background-color: aqua;
}
</style>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值