Vue's methods method and computed calculation attribute and filter filter attachment. Shopping cart code

1.methods method

Through the v-on: event type () binding method , multiple parameters can be passed in the brackets or no parameters can be passed

<button @click="del(index)">删除</button>
<button v-if="key == 'num'" @click="min(item.num,index)"> - </button>

Do data processing in methods

          methods: {
                // 传入当前数据的值和索引 通过索引操作arr里面的num数据
                min(num, index) {
                    if (num - 1 >= 1) {
                        this.arr[index].num--
                    } else if (confirm("确认删除吗?")) {
                        this.arr.splice(index, 1)
                    }
                },
                max(num, index) {
                    // console.log(num, index);
                    this.arr[index].num++
                },
                del(index) {
                    // 删除数据的核心 通过传递index下标使用splice方法删除数组里面的数据
                    // console.log(index);
                    if (confirm("确认删除吗?")) {
                        this.arr.splice(index, 1)
                    }
                }
            },

2.computed computed property

Must use return to return data

Use this attribute directly on the page

Data loading is automatically updated once and the stored data is automatically refreshed when the data changes

<td colspan="6">总价:{
   
   {sum | money}}</td>

Process data in computed

            computed: {
                sum() {
                    let sum = 0
                    for (var i = 0; i < this.arr.length; i++) {
                        // console.log(this.arr[i].price);
                        sum += this.arr[i].price * this.arr[i].num
                    }
                    return sum
                }
            },

 get() method and set() method

Effect: Enter the first and last names and splicing them into the name, and enter the first and last names in the name and split them into the first and last names

    <div id="app">
        姓:<input type="text" v-model.lizy.trim="inp1">
        名:<input type="text" v-model.lizy.trim="inp2">
        <br>
        姓名:<input type="text" v-model.lizy.trim="inp3">
    </div>

Use get() to get data for modification

Use set() to achieve the purpose of reversely modifying data

         computed: {
                // inp3() {
                //     console.log(this.inp1 + this.inp2);
                //     return this.inp1 + this.inp2
                // }
                inp3: {
                    // 只读 页面数据发生改变 计算属性才改变
                    get() {
                        return this.inp1 + this.inp2
                    },
                    // 计算属性里面的数据改变页面的也改变
                    set(val) {
                        let arr = val.split("")
                        let [
                            a,
                            ...b
                        ] = arr
                        // b通过解构出来是数组 然后通过join转为字符串
                        // console.log(a, b.join(""));
                        this.inp1 = a || ""
                        this.inp2 = b.join("") || ""
                    }
                }
            },

3. filter filter

Must use return to return data

Use the pipe symbol | to multiple filters and pay attention to the order

        <!-- 使用多个注意顺序 先数字类型计算再做字符串拼接 -->
        <!-- 10打五折 5 -->
        <p>{
   
   {money | getmoney(5) | sum}}</p>
        <!-- 20打8折 16 -->
        <p>{
   
   {money2 | getmoney(8) | sum}}</p>
内容上使用
{
   
   {item2 | nomover(key)}}
属性上使用
<a :href="item.href | urltop($data._this)">{
   
   {item.name}}</a><br>

Processing data in filter  can pass multiple parameters

The default parameter is | The value on the left The second value starts with the passed parameter

            // 过滤器 中的this指向window
            filters: {
                // val参数默认参数 就是|前面的值
                getgender(val) {
                    // 必须使用return 返回结果
                    if (val == '0') {
                        return "女"
                    } else if (val == '1') {
                        return "男"
                    } else {
                        return "保密"
                    }
                },
                getage(age) {
                    if (age => 18) {
                        return "已成年"
                    } else {
                        return "未成年"
                    }
                },
                // 过滤器使用多个参数
                getmoney(moneys, dis) {
                    // 打折 根据上面传递的参数打不同的折第一个参数是默认|前面的值
                    // 第二个参数就是上面自己写的参数 设置为打的折数
                    return moneys * (dis / 10)
                },
                // 添加¥符号和加 .00
                sum(money) {
                    return '¥' + money + '.00'
                },
                // 设置统一的网址开头
                urltop(url, i) {
                    console.log(i);
                    return `${i.http}${url}`
                }
            }

 Shopping bar effect made using the above method

Using the map and filter methods 

   data(){
        return {
            // 状态数据
           checks: [false, false, false, false],
             }
        }


  computed: {
    // 全选/不全选
    checkAll: {
      get() {
        // 如果有一个为false就为false
        return !this.checks.includes(false);
      },
      set(newVal) {
        // 修改全部的为当前相同的状态
        return (this.checks = this.checks.map(() => {
          return newVal;
        }));
      },
    },
    // 计算勾选的总价
    sum() {
      // var money = 0;
      // this.checks.forEach((item, index) => {
      //   if (item) {
      //     return (money += this.books[index].price * this.books[index].num);
      //   }
      // });
      // return money;
      let total = this.books.reduce((pre, item, index) => {
        return pre + (this.checks[index] ? item.price * item.num : 0);
      }, 0);
      return total;
    },
  },
  watch: {},
  methods: {
    // 增加
    add(index, item) {
       // 通过下标修改
      // this.books[index].num++;
      // 直接修改当前传递过来的数量
         item.num++;
    },
    // 减少
    del(index) {
      if (this.books[index].num > 1) {
        this.books[index].num--;
      }
    },
  },

 full code

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title></title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <style>
        table,
        tr,
        td,
        th {
            border: 2px solid black;
            text-align: center;
            /* width: 600px; */
            padding: 5px 10px;
        }

        table {
            border-collapse: collapse;
            margin: 0 auto;
        }
    </style>
</head>

<body>
    <div id="app">
        <table>
            <!-- 表头 -->
            <thead>
                <tr>
                    <!-- 遍历表头里的数据 -->
                    <th v-for="item in title">
                        {
   
   {item}}
                    </th>
                </tr>
                <!-- 数据 -->
            <tbody>
                <!-- 循环遍历数组里的对象 页面和数据双向绑定-->
                <tr v-for="item,index in arr" :key="item.id">
                    <!-- 遍历对象里的数据 -->
                    <td v-for="item2,key in item">
                        <!-- 如果key的值不是num 就不显示 -->
                        <button v-if="key == 'num'" @click="min(item.num,index)"> - </button>
                    <!-- 给数据做了过滤 给价格栏加¥和.00 只渲染价格栏 不是价格的就不渲染 -->              
                        {
   
   {item2 | nomover(key)}}
                    <!-- 给不是价格的数据进行渲染 -->
                        {
   
   {item2 | moneys(key)}}
                        <!-- 如果key的值不是num 就不显示 -->
                        <button v-if="key== 'num'" @click="max(item.num,index)"> + </button>
                    </td>
                    <td>
                        <!-- 在操作下面添加删除-->
                        <button @click="del(index)">删除</button>
                    </td>
                </tr>
            </tbody>
            </thead>
            <tr>
                <td colspan="6">总价:{
   
   {sum | money}}</td>
            </tr>
        </table>


    </div>
    <script>
        // 实例化vue对象
        const app = new Vue({
            el: "#app", //实例化vue对象的绑定内容
            data: {
                // 购物车数据
                arr: [{
                        id: 1,
                        name: "算发导论",
                        year: "2006 - 9",
                        price: 85,
                        num: 1
                    },
                    {
                        id: 2,
                        name: "UNIX编程艺术",
                        year: "2006 - 2",
                        price: 59,
                        num: 1
                    },
                    {
                        id: 3,
                        name: "Vue程序设计",
                        year: "2008 - 10",
                        price: 35,
                        num: 1
                    },
                    {
                        id: 4,
                        name: "颈椎康复",
                        year: "2006 - 3",
                        price: 129,
                        num: 1
                    },
                ],
                //   表头数据
                title: [
                    "编号", "书籍名称", "出版日期", "价格", "购买数量", "操作"
                ],

            },
            methods: {
                // 传入当前数据的值和索引 通过索引操作arr里面的num数据
                min(num, index) {
                    if (num - 1 >= 1) {
                        this.arr[index].num--
                    } else if (confirm("确认删除吗?")) {
                        this.arr.splice(index, 1)
                    }
                },
                max(num, index) {
                    // console.log(num, index);
                    this.arr[index].num++
                },
                del(index) {
                    // console.log(index);
                    if (confirm("确认删除吗?")) {
                        this.arr.splice(index, 1)
                    }
                }
            },
            filters: {
                // 只读属性 当变量使用
                money(val) {
                    return "¥" + val + ".00"
                },
                moneys(val, key) {
                    console.log(val);
                    if (key == "price") {
                        return "¥" + val + ".00"
                    }
                },
                nomover(val, key) {
                    if (key != "price") {
                        return val
                    }
                }
            },
            computed: {
                sum() {
                    let sum = 0
                    for (var i = 0; i < this.arr.length; i++) {
                        // console.log(this.arr[i].price);
                        sum += this.arr[i].price * this.arr[i].num
                    }
                    return sum
                }
            },
        });
    </script>
</body>

</html>

4. Function upgrade vue version

Calculate the price of the checked commodity and judge it by checked

<template lang="">
  <div class="shopcar">
    <div>
      <h1>购物车<span>编辑</span></h1>
    </div>
    <!-- 如果购物车为空就显示该图片 -->
    <div class="img" v-if="false">
      <img src="../../public/img/0.png" alt="" width="100%" />
    </div>
    <!-- 购物车内容 -->
    <div v-else>
      <ul class="list">
        <li v-for="(item, index) in list" :key="item.id">
          <input
            class="checked"
            type="checkbox"
            ref="checked"
            @click="checked"
          />
          <img src="../../public/img/c1.png" alt="" />
          <p class="p1">{
   
   { item.title }}</p>
          <p class="p2">{
   
   { item.text }}</p>
          <p class="p3">
            {
   
   { item.money * item.num }}¥.00
            <i class="iconfont icon-shanchu" @click="del(item.id)">删除</i>
          </p>
          <p class="p4">
            <button @click="add(-1, item.id)">-</button>
            <input type="text" v-model="item.num" />
            <button @click="add(1, item.id)">+</button>
          </p>
        </li>
      </ul>
    </div>
    <!-- 底部 -->
    <div class="bottom">
      <input
        name="checkbox"
        value="Item 1"
        type="checkbox"
        class="tui-checkbox"
        @click="checkeds"
        ref="checkeds"
      />
      <span class="s1" ref="text">全选</span>
      <span class="s3">结算</span>
      <span class="s2"> 合计:{
   
   { money }}¥</span>
    </div>
  </div>
</template>

<script>
export default {
  // 组件注册
  components: {},
  mixins: [],
  props: [],
  data() {
    return {
      money: 0,
      sum: 1,
      list: [
        {
          id: 1,
          title: "喜羊羊薯片",
          text: "薯片好吃的一批,吃了每天都喜羊羊",
          money: 15,
          img: "../../public/img/c1.png",
          num: 1,
        },
        {
          id: 2,
          title: "懒羊羊薯片",
          text: "薯片好吃的一批,吃了每天都懒羊羊",
          money: 15,
          img: "../../public/img/c1.png",
          num: 2,
        },
        {
          id: 3,
          title: "灰太狼薯片",
          text: "薯片好吃的一批,吃了每天都动力十足",
          money: 15,
          img: "../../public/img/c1.png",
          num: 3,
        },
      ],
    };
  },
  watch: {
    // money: function (val) {
    //   console.log(val);
    // var checkeda = this.$refs.checked;
    // console.log(checkeda);
    // for (var i = 0; i < this.list.length; i++) {
    //   if (checkeda[i].checked) {
    //     val += this.list[i].money * this.list[i].num;
    //   }
    // }
    // },
  },
  computed: {
    // 总价
    // money() {
    //   var num = 0;
    //   // for (var i = 0; i < this.list.length; i++) {
    //   //     num += this.list[i].money * this.list[i].num;
    //   // }
    //   return num;
    // },
  },
  // 加减
  methods: {
    add(val, id) {
      // console.log(val);
      // console.log(id);
      this.list.forEach((item, index) => {
        if (item.id == id) {
          // console.log(item.num);
          if (item.num >= 1) {
            item.num += val;
          }
          if (item.num - 1 < 1) {
            item.num = 1;
          }
        }
      });
      this.num();
    },
    // 删除
    del(id) {
      // console.log(id);
      this.list.forEach((item, index) => {
        if (item.id == id) {
          // console.log(index);
          // console.log(this.list[index]);
          this.list.splice(index, 1);
        }
      });
      this.num();
    },
    // 全选
    checkeds() {
      // console.log(this.$refs.checked.length);
      var checkeda = this.$refs.checked;
      var checkeds = this.$refs.checkeds;
      for (var i = 0; i < checkeda.length; i++) {
        checkeda[i].checked = checkeds.checked;
      }
      var text = this.$refs.text;
      text.innerText = checkeds.checked ? "全不选" : "全选";
      this.num();
    },
    // 单个
    checked(e) {
      // console.log(e.target);
      var checkeda = this.$refs.checked;
      var checkeds = this.$refs.checkeds;
      // console.log(checkeda.length);
      checkeds.checked = true;
      for (var i = 0; i < checkeda.length; i++) {
        if (!checkeda[i].checked) {
          checkeds.checked = false;
        }
      }
      var text = this.$refs.text;
      text.innerText = checkeds.checked ? "全不选" : "全选";
      this.num();
    },
    // 总价 计算勾选的商品价格
    num() {
      var num = 0;
      var checkeda = this.$refs.checked;
      // console.log(checkeda);
      for (var i = 0; i < this.list.length; i++) {
        if (checkeda[i].checked) {
          num += this.list[i].money * this.list[i].num;
        }
      }
      this.money = num;
    },
  },
  // 生命周期 - 创建完成(访问当前this实例)
  created() {},
  // 生命周期 - 挂载完成(访问DOM元素)
  mounted() {},
  destroyed() {},
};
</script>

<style lang="less" scoped>
//设置选中背景
.tui-checkbox:checked {
  background: #1673ff;
}
//设置复选框样式
.tui-checkbox {
  margin-top: 10px;
  width: 25px;
  height: 25px;
  background-color: #ffffff;
  border: solid 1px #dddddd;
  -webkit-border-radius: 50%;
  border-radius: 50%;
  font-size: 0.8rem;
  margin-top: 20px;
  padding: 0;
  position: relative;
  display: inline-block;
  vertical-align: top;
  cursor: default;
  -webkit-appearance: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-transition: background-color ease 0.1s;
  transition: background-color ease 0.1s;
}
//设置伪类,即显现的对勾样式
.tui-checkbox:checked::after {
  content: "";
  top: 5px;
  left: 5px;
  position: absolute;
  background: transparent;
  border: #fff solid 2px;
  border-top: none;
  border-right: none;
  height: 6px;
  width: 10px;
  -moz-transform: rotate(-45deg);
  -ms-transform: rotate(-45deg);
  -webkit-transform: rotate(-45deg);
  transform: rotate(-45deg);
}
.shopcar {
  background-color: #f7f6fb;
  .img {
    margin: auto;
  }
  div {
    text-align: center;
    width: 100%;
    background-color: #fff;
    h1 {
      font-size: 35px;
      text-align: center;
      padding: 20px;
      padding-left: 50px;
      span {
        font-size: 25px;
        margin-top: 10px;
        float: right;
      }
    }
  }
  .bottom {
    position: absolute;
    bottom: 60px;
    // background-color: red;
    font-size: 20px;
    height: 60px;
    line-height: 60px;
    span {
      display: inline-block;
    }
    .s1 {
      margin-left: 5px;
      font-size: 16px;
    }
    .s2 {
      margin-right: 20px;
      float: right;
      font-size: 16px;
    }
    .s3 {
      margin-right: 20px;
      float: right;
      color: #f7f6fb;
      margin-top: 5px;
      line-height: 40px;
      overflow: hidden;
      padding: 5px;
      display: inline-block;
      background-color: #fc0050;
      width: 100px;
      border-radius: 30px;
    }
  }
}
.list {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  li {
    background-color: #eee;
    padding: 5px;
    padding-top: 15px;
    margin: 5px;
    .checked {
      float: left;
      margin-top: 40px;
      margin-right: 10px;
    }
    img {
      width: 50px;
      float: left;
    }
    p {
      text-align: left;
      text-indent: 1em;
      margin-bottom: 10px;
    }
    .p1 {
      font-size: 20px;
      color: #ff7716;
    }
    .p2 {
      font-size: 14px;
    }
    .p3 {
      font-size: 18px;
      color: rgb(247, 91, 0);
      i {
        float: right;
        color: #000;
        font-weight: 700;
        margin-right: 20px;
      }
    }
    .p4 {
      float: right;
      margin-right: 50px;
      input {
        text-align: center;
        width: 30px;
        margin: 2px;
      }
    }
  }
}
</style>

Guess you like

Origin blog.csdn.net/weixin_70563937/article/details/126356363