Vue的基础属性知识

1. Vue基础_更新检测,key作用

在上一章我们提到过v-for数组,那么我们的需求是如何v-for数组变化,需要同步更新到页面。但是并不是所有的数组方法都会造成v-for的更新。

<template>
  <div>
    <ul>
      <li v-for="(val, index) in arr" :key="index">
        {{ val }}
      </li>
    </ul>
    <button @click="revBtn">数组翻转</button>
    <button @click="sliceBtn">截取前3</button>
    <button @click="updateBtn">更新第一个元素值</button>
  </div>
</template>

<script>
export default {
  data(){
    return {
      arr: [5, 3, 9, 2, 1]
    }
  },
  methods: {
    revBtn(){
      // 1. 数组翻转可以让v-for更新
      this.arr.reverse()
    },
    sliceBtn(){
      // 2. 数组slice方法不会造成v-for更新
      // slice不会改变原始数组
      // this.arr.slice(0, 3)

      // 解决v-for更新 - 覆盖原始数组
      let newArr = this.arr.slice(0, 3)
      this.arr = newArr
    },
    updateBtn(){
      // 3. 更新某个值的时候, v-for是监测不到的
      // this.arr[0] = 1000;

      // 解决-this.$set()
      // 参数1: 更新目标结构
      // 参数2: 更新位置
      // 参数3: 更新值
      this.$set(this.arr, 0, 1000)
    }
  }
}
</script>

<style>

</style>

上面列举了数组翻转,数组截取和数组更新值的情形。其中push,pop,shift,unshift,splice,sort,reverse等数组方法会导致v-for更新。
但是比如filter,concat,slice等方法不会造成更新,因此我们在使用的时候可以采用覆盖数组的方式。
但是对于赋值的操作我们可采用this.$set()

那么v-for是如何更新DOM的呢?
在这里插入图片描述
循环出新的虚拟DOM结构,和旧的虚拟DOM结构对比,尝试复用标签就地更新内容。在内存中比较变化部分,然后给真实DOM打补丁
那我们来回顾一下以前学过的真实DOM树。在document对象上,渲染到浏览器上显示的标签在这里插入图片描述
而虚拟DOM的本质是保存节点信息,属性和内容的一个JS对象。在这里插入图片描述
为什么用虚拟DOM呢?因为真实DOM属性过多,遍历耗时,下面来介绍一种diff算法,同根比较如果根元素变化,整个DOM树删除重建;同级比较如果根元素不变,属性改变更新属性

在这里插入图片描述
在这里插入图片描述
那么如果标签内子标签或者内容改变,那么diff算法是如何改变的,现在就来引入关键字key,具体来了解key是怎么用的

<template>
  <div>
    <ul>
      <li v-for="(val, ind) in arr" :key="ind">
        {{ val }}
      </li>
    </ul>
    <button @click="btn">下标1位置插入新来的</button>
  </div>
</template>

<script>
export default {
  data(){
    return {
      arr: ['老大', "老二", '老三']
    }
  },
  methods: {
    btn(){
      this.arr.splice(1, 0, '新来的')
    }
  }
}
</script>

<style>

</style>

在上述代码中,我用了:key=ind表示Key是索引值从0开始,一般对于数组的话,可以这样进行设置。这样想,当我们没有设置key的时候,这个更新机制如下图
在这里插入图片描述
会最大限度尝试修改/复用相同类型元素,也就是说我们新增了一个li 后面三个li的值都会发生变化。
在我们设置了key值为索引后,根据key比较然后就地更新,也就是说这种方法和上面的无key方法是一样的效果。
在我们设置了key值唯一不重复的字符串或数字,最典型就是id如下所示

<template>
  <div>
    <ul>
      <li v-for="obj in arr" :key="obj.id">
        {{ obj.name }}
        <input type="text">
      </li>
    </ul>
    <button @click="btn">下标1位置插入新来的</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      arr: [
        {
          name: '老大',
          id: 50
        },
        {
          name: '老二',
          id: 31
        },
        {
          name: '老三',
          id: 10
        }
      ],
    };
  },
  methods: {
    btn(){
      this.arr.splice(1, 0, {
        id: 19, 
        name: '新来的'
      })
    }
  }
};
</script>

<style>
</style>

最后的效果如下图所示
在这里插入图片描述
原则上是有id用id 无id用索引,并且key可以配合虚拟DOM提高更新的性能。
现对上述内容进行一个总结
在这里插入图片描述
下一个问题来讲讲动态class和动态style属性

<template>
  <div>
    <!-- 语法:
      :class="{类名: 布尔值}"
      使用场景: vue变量控制标签是否应该有类名
     -->
    <p :class="{red_str: bool}">动态class</p>
  </div>
</template>

<script>
export default {
  data(){
    return {
      bool: true
    }
  }
}
</script>

<style scoped>
  .red_str{
    color: red;
  }
</style>
<template>
  <div>
    <!-- 动态style语法
      :style="{css属性名: 值}"
     -->
    <p :style="{backgroundColor: colorStr}">动态style</p>
  </div>
</template>

<script>
export default {
  data(){
    return {
      colorStr: 'red'
    }
  }
}
</script>

<style>

</style>

2. Vue基础_过滤器

过滤器是转换格式,就是一个函数,传入值返回处理后的值。过滤器只能用来插值表达式和v-bind动态属性中。下面列举了v-bind的属性

v-bind:title  鼠标移上的显示

v-bind:src  绑定图片路径

v-bind:html 绑定HTML文本和标签

v-bind:text 绑定文本

v-bind:class 绑定类样式

v-bind:style  动态绑定样式
<template>
  <div>
    <p>原来的样子: {{ msg }}</p>
    <!-- 2. 过滤器使用
      语法: {{| 过滤器名字 }}
     -->
    <p>使用翻转过滤器: {{ msg | reverse }}</p>
    <p :title="msg | toUp">鼠标长停</p>
  </div>
</template>

<script>
export default {
  data(){
    return {
      msg: 'Hello, Vue'
    }
  },
  // 方式2: 局部 - 过滤器
  // 只能在当前vue文件内使用
  /*
     语法: 
     filters: {
       过滤器名字 (val) {
         return 处理后的值
       }
     }
  */
  filters: {
    toUp (val) {
      return val.toUpperCase()
    }
  }
}
</script>

<style>

</style>

上面的过滤器场景是用在字符串翻转和字符串转大写。在这里插入图片描述
如果是在主App.vue文件中,那么属于全局的过滤器,需要用到vue.filter来定义和声明,在单个vue文件中,直接使用filters即可。在使用过滤器时,一定是前者Vue变量后者过滤器名字。那么过滤器既然是个函数,就应该可以给过滤器进行传参,并且一个插值表达式或者动态属性可以使用多个过滤器。如下所示
在这里插入图片描述

<template>
  <div>
    <p>原来的样子: {{ msg }}</p>
    <!-- 1.
      给过滤器传值
      语法: vue变量 | 过滤器名()
     -->
    <p>使用翻转过滤器: {{ msg | reverse('|') }}</p>
    <!-- 2.
      多个过滤利使用
      语法: vue变量 | 过滤器1 | 过滤器2
     -->
    <p :title="msg | toUp | reverse('|')">鼠标长停</p>
  </div>
</template>

<script>
export default {
  data(){
    return {
      msg: 'Hello, Vue'
    }
  },
  filters: {
    toUp (val) {
      return val.toUpperCase()
    }
  }
}
</script>

<style>

</style>

3. Vue基础_计算属性

当我们需要a和b变量改变,那么如何同步更新num的值呢?因此我们又引入另一个语法-计算属性。

<template>
  <div>
    <p>{{ num }}</p>
  </div>
</template>

<script>
export default {
  data(){
    return {
      a: 10,
      b: 20
    }
  },
  // 计算属性:
  // 场景: 一个变量的值, 需要用另外变量计算而得来
  /*
    语法:
    computed: {
      计算属性名 () {
        return 值
      }
    }
  */
 // 注意: 计算属性和data属性都是变量-不能重名
 // 注意2: 函数内变量变化, 会自动重新计算结果返回
  computed: {
    num(){
      return this.a + this.b
    }
  }
}
</script>

<style>

</style>

计算属性也是vue数据变量,所以不要和data里重名,用法和data相同。同样我们可以用函数调用实现这个功能,那么计算属性的优势在哪呢?
计算属性,基于依赖项的值进行缓存,依赖的变量不变的情况,都直接从缓存取结果。

<template>
  <div>
    <p>{{ reverseMessage }}</p>
    <p>{{ reverseMessage }}</p>
    <p>{{ reverseMessage }}</p>
    <p>{{ getMessage() }}</p>
    <p>{{ getMessage() }}</p>
    <p>{{ getMessage() }}</p>
  </div>
</template>

<script>
export default {
  data(){
    return {
      msg: "Hello, Vue"
    }
  },
  // 计算属性优势:
  // 带缓存
  // 计算属性对应函数执行后, 会把return值缓存起来
  // 依赖项不变, 多次调用都是从缓存取值
  // 依赖项值-变化, 函数会"自动"重新执行-并缓存新的值
  computed: {
    reverseMessage(){
      console.log("计算属性执行了");
      return this.msg.split("").reverse().join("")
    }
  },
  methods: {
    getMessage(){
      console.log("函数执行了");
      return this.msg.split("").reverse().join("")
    }
  }
}
</script>

<style>

</style>

在这里插入图片描述
计算属性好处是带缓存,依赖项不变,直接从缓存取,依赖项改变,函数自动执行并重新缓存。计算属性也可以用在输入框上,双向绑定。set函数接收要赋予的值,get里要返回给这个计算属性具体值

<template>
  <div>
      <div>
          <span>姓名:</span>
          <input type="text" v-model="full">
      </div>
  </div>
</template>

<script>
// 问题: 给计算属性赋值 - 需要setter
// 解决:
/*
    完整语法:
    computed: {
        "计算属性名" (){},
        "计算属性名": {
            set(值){

            },
            get(){
                return 值
            }
        }
    }
*/
export default {
    computed: {
        full: {
            // 给full赋值触发set方法
            set(val){
                console.log(val)
            },
            // 使用full的值触发get方法
            get(){
                return "无名氏"
            }
        }
    }
}
</script>

<style>

</style>

4. Vue基础_侦听器

可以倾听data/computed属性值的改变

<template>
  <div>
    <input type="text" v-model="name">
  </div>
</template>

<script>
export default {
  data(){
    return {
      name: ""
    }
  },
  // 目标: 侦听到name值的改变
  /*
  语法:
    watch: {
      变量名 (newVal, oldVal){
        // 变量名对应值改变这里自动触发
      }
    }
  */
  watch: {
    // newVal: 当前最新值
    // oldVal: 上一刻值
    name(newVal, oldVal){
      console.log(newVal, oldVal);
    }
  }
}
</script>

<style>

</style>

使用watch配置项,key是要倾听的data,也可以倾听对象。如果需要深度监听的话 需要设置
在这里插入图片描述
以上便是整个vue的部分基础知识。在下一章中我会在一个小项目中使用这些语法。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

清辞-

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

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

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

打赏作者

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

抵扣说明:

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

余额充值