Vue基础-key,计算属性,过滤器,侦听器

一、更新检测和key的作用

1.1 v-for更新检测

目标结构变化, 触发v-for的更新

  • 数组变更方法, 就会导致v-for更新, 页面更新
    • push
    • shift
    • unshift
    • pop
    • sort
    • splice
    • reverse
  • 数组非变更方法, 返回新数组, 就不会导致v-for更新, 可采用覆盖数组或this.$set()
    • filter
    • slice
    • concat

this.$set()方法更新某个值

 	changeBtn() {
      // this.arr[0] = 1000
      //使用this.$set()
      //参数一 更新的目标结构
      //参数二 更新的位置
      //参数三 更新的值
      this.$set(this.arr, 0, 1000)
    }

1.2 v-for就地更新

循环出新的虚拟DOM结构, 和旧的虚拟DOM结构对比, 尝试复用标签就地更新内容

在这里插入图片描述

1.3 真实DOM

在document对象上, 渲染到浏览器上显示的标签

在这里插入图片描述

1.4 虚拟DOM

本质是保存节点信息, 属性和内容的一个JS对象

在这里插入图片描述

在内存中比较变化部分,然后给真实DOM打补丁(更新)

在这里插入图片描述

虚拟DOM的好处,提高DOM更新的性能,不频繁操作真实的DOM

1.5 diff算法

同级比较-根元素变化,整个dom树删除重建

在这里插入图片描述

同级比较-根元素不变,属性改变更新属性

在这里插入图片描述

1.6 diff算法-key

根元素没变, 子元素没变, 元素内容改变

1.6.1 无key(就地更新)

v-for不会移动DOM, 而是尝试复用, 就地更新

在这里插入图片描述
在这里插入图片描述

最大限度尝试就地修改/复用相同类型元素

在这里插入图片描述

1.6.2 有key, 值为索引

有key属性, 基于key的来比较新旧虚拟DOM, 移除key不存在元素

在这里插入图片描述

先产生新旧虚拟DOM,根据key比较,还是就地更新

在这里插入图片描述

1.6.3 有key, 值唯一不重复的字符串或数字

有key属性, 基于key的来比较新旧虚拟DOM, 移除key不存在元素

在这里插入图片描述

先产生新旧虚拟DOM, 根据key比较

在这里插入图片描述

  • 有id用id, 无id用索引
  • key的好处可以配合虚拟dom提高更新的性能

1.7 动态class

用v-bind给标签class设置动态的值

  • 语法 :class="{ 类名 : 布尔值 }"
    在这里插入图片描述

1.8 动态style

给标签动态设置style的值

  • 语法 :style=" { css属性名 : 值 }"
    在这里插入图片描述

二、过滤器

2.1 定义使用

转换格式,过滤器就是一个函数 传入值返回处理后的结果

  • 过滤器只能用在 插值表达式 和 v-bind动态属性里
  • 定义过滤器的位置
    • 全局过滤器(main.js)
    • 局部过滤器(当前页面,与data同级)
      在这里插入图片描述
//全局过滤器
//任意的.vue文件内 直接使用
//语法Vue.filter('过滤器名称',值==>处理结果)
 Vue.filter('reverse', val => val.split('').reverse().join(''))
 --------------------------------------------
 //方法二 定义局部过滤器`
  //当前vue文件内使用  加s(可定义多个过滤器)
  filters: {
    toUps: function (val) {
      console.log('val');
      return val.toUpperCase()
    }
  }

  • 过滤器的使用
    • 语法 vue变量 | 过滤器名称
 <!-- 过滤器使用 {{ 变量|过滤器名称  }} -->
    <p>使用反转过滤器{{ msg | reverse }}</p>
    <p :title="msg | toUps">鼠标长时间停留111</p>

2.2 传参和使用多个过滤器

  • 语法
    • 传参 变量 | 过滤器(实参)
    • 多个过滤器 变量 | 过滤器1 | 过滤器2
      在这里插入图片描述

三、计算属性

3.1 computed

一个变量的值依赖另外一些数据计算得来的值

计算属性也是vue数据变量, 所以不要和data里重名, 用法和data相同

在这里插入图片描述

export default {
  data() {
    return {
      a: 10,
      b: 20
    }
  },
  //计算属性 场景(当一个变量的值,来源于另外变量计算而得来的)
  //语法 computed:{计算属性名(){return 值}}
  //注意 计算属性和data属性都是变量 不能重名
  computed: {
    num() {
      return this.a + this.b
    }
  }
}

3.2 缓存

计算属性, 基于依赖项的值进行缓存,依赖的变量不变, 都直接从缓存取结果

当依赖性改变时,会自动执行并重新缓存新值

在这里插入图片描述

3.3 完整写法

计算属性也是变量, 如果想要直接赋值, 需要使用完整写法

在这里插入图片描述

computed: {
    full: {
      // return '无名氏'
      //给full赋值触发set方法
      set(val) {
        console.log('val', val);
      },
      //使用full的值触发get方法
      get() {
        return '无名氏'
      }
    }
  }

3.4 全选 小选 反选案例

小选影响全选

在这里插入图片描述

全选影响小选

在这里插入图片描述

反选

在这里插入图片描述

<template>
  <div>
    <span>全选:</span>
    <!-- 2.v-model关联选中的状态 -->
    <input type="checkbox" v-model="isAll" />
    <button @click="btn">反选</button>
    <ul>
      <li v-for="item in arr">
        <!-- 1.关联选中状态 -->
        <input type="checkbox" v-model="item.c" />
        <span>{{ item.name }}</span>
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  //3.计算属性
  computed: {
    isAll: {
      set(val) {
        //5.全选框选中状态 改变小选框状态
        console.log('打印去到的值', val);
        this.arr.forEach(item => item.c = val)
      },
      get() {
        //4.统计小选框的状态
        //every 查找数组里不符合条件的 直接原地返回false
        return this.arr.every((item) => item.c === true)
      }
    }
  },
  methods: {
    btn() {
      this.arr.forEach((item) => item.c = !item.c)
    }
  },
  data() {
    return {
      arr: [
        {
          name: "猪八戒",
          c: false,
        },
        {
          name: "孙悟空",
          c: false,
        },
        {
          name: "唐僧",
          c: false,
        },
        {
          name: "白龙马",
          c: false,
        },
      ],
    };
  }
};
</script>

四、侦听器

4.1 watch

可以侦听data computed(计算属性) 值的改变

在这里插入图片描述

4.2 深度侦听和立即执行

侦听复杂类型, 或者立即执行侦听函数

在这里插入图片描述

watch: {
    user: {
      immediate: true,//立即执行
      deep: true,//深度侦听复杂类型
      handler(newval, oldval) {
        console.log(newval, oldval);
      }
    }
  }

五、品牌管理案例

1.品牌管理数据铺设

在这里插入图片描述

2.品牌管理数据增加

在这里插入图片描述

3.品牌管理数据删除

在这里插入图片描述

4.品牌管理时间格式化

在这里插入图片描述

5.品牌管理总价和均价

在这里插入图片描述

6.品牌管理数据缓存

在这里插入图片描述

完整代码

<template>
  <div id="app">
    <div class="container">
      <!-- 顶部框模块 -->
      <div class="form-group">
        <div class="input-group">
          <h4>品牌管理</h4>
        </div>
      </div>

      <!-- 数据表格 -->
      <table class="table table-bordered table-hover mt-2">
        <thead>
          <tr>
            <th>编号</th>
            <th>资产名称</th>
            <th>价格</th>
            <th>创建时间</th>
            <th>操作</th>
          </tr>
        </thead>
        <tbody>
          
          <tr v-for="item in list" :key="item.id">
            <td>{{ item.id }}</td>
            <td>{{ item.name }}</td>

            <!-- 如果价格超过100,就有red这个类 -->
            <td :class="{ red: item.price > 100 }">{{ item.price }}</td>
            <td>{{ item.time | formaDate }}</td>
            <td @click="del(item.id)"><a href="#">删除</a></td>
          </tr>
          <tr v-if="list.length !== 0" style="background-color: #EEE">
            <td>统计:</td>
            <td colspan="2">总价钱为: {{ allPrice }}</td>
            <td colspan="2">平均价: {{ svgPrice }}</td>
          </tr>
        </tbody>

        <tfoot v-if="list.length <= 0">
          <tr>
            <td colspan="5" style="text-align: center">暂无数据</td>
          </tr>
        </tfoot>

      </table>

      <!-- 添加资产 -->
      <form class="form-inline">
        <div class="form-group">
          <div class="input-group">
            <input type="text" v-model="name" class="form-control" placeholder="资产名称" />
          </div>
        </div>
        &nbsp;&nbsp;&nbsp;&nbsp;
        <div class="form-group">
          <div class="input-group">
            <input v-model.number="price" type="text" class="form-control" placeholder="价格" />
          </div>
        </div>
        &nbsp;&nbsp;&nbsp;&nbsp;
        <!-- 阻止表单提交 -->
        <button @click.prevent="addBtn" class="btn btn-primary">添加资产</button>
      </form>
    </div>
  </div>
</template>

<script>
//目标 侦听list改变 同步到本地localStorage里边
import moment from 'moment'
export default {
  data() {
    return {
      name: "", // 名称
      price: 0, // 价格
      //3.本地取出缓存的list        
      list: JSON.parse(localStorage.getItem('Plist')) || []
    };
  },
  //侦听器 1.list
  watch: {
    list: {
      deep: true,
      handler(newval, oldval) {
        //2.存入本地 
        localStorage.setItem('Plist', JSON.stringify(newval))
      }
    }
  },
  //过滤器
  filters: {
    formaDate(val) {
      return moment(val).format('YYYY-MM-DD')
    }
  },
  //计算属性
  computed: {
    allPrice() {
      return this.list.reduce((sum, obj) =>
        sum += obj.price
        , 0)
    },
    svgPrice() {
      // toFixed 保留两位小数
      return (this.allPrice / this.list.length).toFixed(2)
    }
  },
  methods: {
    //增加按钮
    addBtn() {
      console.log('名称 价格', this.name, this.price);
      if (this.name.trim().length === 0 || this.price === 0) {
        return alert('不能为空')
      }
      let id = this.list.length > 0 ? this.list[this.list.length - 1].id + 1 : 100
      console.log('打印id', id);
      this.list.push({
        id: id,
        name: this.name,
        price: this.price,
        time: new Date()
      })
      this.name = ''
      this.price = 0
    },
    //删除
    del(id) {
      console.log('id', id);
      let i = ''
      // this.list.forEach((item, index) => {
      //   if (item.id === id) {
      //     console.log('打印索引', index);
      //     i = index
      //   }
      // })
      i = this.list.findIndex((item, index) => {
        return item.id === id
      })
      this.list.splice(i, 1)
    }
  }
};
</script>

<style >
.red {
  color: red;
}
</style>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gik99

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值