美文网首页
二、基础知识

二、基础知识

作者: AShuiCoder | 来源:发表于2021-07-18 16:41 被阅读0次
  1. v-bind="{ a: 1, b: 1 }"这种写法可以将对象里的所有属性绑定
  2. v-on="onChange($event, ...arguments)"这种写法可以传事件对象为第一个参数,其他参数依次往后传递。
  3. v-show不能放在template上使用,也不能和v-else使用,为false时元素会加上display:none
  4. v-for可以和template标签一起使用
<template v-for="item in list"></template>
  1. 数组更新检测
  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reserve()
  1. v-for中的key是什么作用?
    官方的解释:
  • key属性主要用在Vue的虚拟DOM算法,在新旧nodes对比时辨识VNodes;
  • 如果不使用key,Vue会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法;
  • 而使用key时,它会基于key的变化重新排列元素顺序,并且会移除/销毁key不存在的元素;

Vue事实上会对于有key和没有key会调用两个不同的方法;有key,那么就使用 patchKeyedChildren方法;没有key,那么久使用 patchUnkeyedChildren方法;

没有key的过程如下:

  • c和d来说它们事实上并不需要有任何的改动;
  • 但是因为我们的c被f所使用了,所有后续所有的内容都要一次进行改动,并且最后进行新增;


    image.png

有key的diff算法如下:
第一步的操作是从头开始进行遍历、比较:

  • a和b是一致的会继续进行比较;
  • c和f因为key不一致,所以就会break跳出循环;
image.png

第二步的操作是从尾部开始进行遍历、比较:


image.png

第三步是如果旧节点遍历完毕,但是依然有新的节点,那么就新增节点:


image.png
第四步是如果新的节点遍历完毕,但是依然有旧的节点,那么就移除旧节点:
image.png

第五步是最特色的情况,中间还有很多未知的或者乱序的节点:



所以我们可以发现,Vue在进行diff算法的时候,会尽量利用我们的key来进行优化操作:
  • 在没有key的时候我们的效率是非常低效的;
  • 在进行插入或者重置顺序的时候,保持相同的key可以让diff算法更加的高效;
  1. 源码如何对computedd的setter和getter处理呢?
    事实上非常的简单,Vue源码内部只是做了一个逻辑判断而已;


    image.png
  2. watch监听对象


    image.png
  • 使用一个选项deep进行更深层的侦听;
  • 使用immediate选项, 望一开始的就会立即执行一次
  1. watch其他监听器的写法:
watch: {
  a: 'onChange'
},
methods: {
  onChange (val, old) {}
}

还可以在created的生命周期中,使用 this.$watchs 来侦听:

  • 第一个参数是要侦听的源
  • 第二个参数是侦听的回调函数callback;
  • 第三个参数是额外的其他选项,比如deep、immediate;
image.png
  1. v-model的原理
    v-model的原理其实是背后有两个操作:
  • v-bind绑定value属性的值;
  • v-on绑定input事件监听到函数中,函数会获取最新的值赋值到绑定的属性中;
  1. v-model修饰符
  • lazy
    如果我们在v-model后跟上lazy修饰符,那么会将绑定的事件切换为 change 事件,只有在提交时(比如回车)
    才会触发;
  • number
    如果我们希望转换为数字类型,那么可以使用 .number 修饰符,在我们进行逻辑判断时,如果是一个string类型,在可以转化的情况下会进行隐式转换的
  • trim
    如果要自动过滤用户输入的守卫空白字符,可以给v-model添加 trim 修饰符
  1. 当我们传递给一个组件某个属性,但是该属性并没有定义对应的props或者emits时,就称之为 非Prop的Attribute,常见的包括class、style、id属性等。当组件有单个根节点时,非Prop的Attribute将自动添加到根节点的Attribute中,如果我们不希望组件的根元素继承attribute,可以在组件中设置 inheritAttrs: false。可以通过 $attrs来访问所有的 非props的attribute,多个根节点的attribute如果没有显示的绑定,那么会报警告,我们必须手动的指定要绑定到哪一个属性上。

  2. 子组件向父组件emit事件:
    vue3新增申明emits:
    可以是一个数组:
    emits: ["add", "sub", "addN"]
    也可以是对象用来验证参数,只是起到警告作用,验证不通过依然会传给父组件:

 emits: {
      add: null,
      sub: null,
      addN: (num, name, age) => {
        console.log(num, name, age);
        if (num > 10) {
          return true
        }
        return false;
      }
},
  1. 非父子组件的通信
  • Provide和Inject
    父组件
    provide() {
        return {
          name: "why",
          age: 18,
          length: computed(() => this.names.length) // ref对象 .value
        }
      },
    
    子组件
<template>
 <div>
   HomeContent: {{name}} - {{age}} - {{length.value}}
 </div>
</template>

<script>
 export default {
   inject: ["name", "age", "length"],
 }
</script>

<style scoped>

</style>
  • 全局事件总线mitt库
    npm install mitt
import mitt from 'mitt';
const emitter = mitt();
export default emitter;

      btnClick() {
        console.log("about按钮的点击");
        emitter.emit("why", {name: "why", age: 18});
      }

    created() {
      emitter.on("why", (info) => {
        console.log("why:", info);
      });

      emitter.on("kobe", (info) => {
        console.log("kobe:", info);
      });

      emitter.on("*", (type, info) => {
        console.log("* listener:", type, info);
      })
    }
  1. 异步组件的使用
const AsyncCategory = defineAsyncComponent(() => import("./AsyncCategory.vue"))

  const AsyncCategory = defineAsyncComponent({
    loader: () => import("./AsyncCategory.vue"),
    loadingComponent: Loading,
    // errorComponent,
    // 在显示loadingComponent组件之前, 等待多长时间
    delay: 2000,
    /**
     * err: 错误信息,
     * retry: 函数, 调用retry尝试重新加载
     * attempts: 记录尝试的次数
     */
    onError: function(err, retry, attempts) {

    }
  })
  1. 组件的v-model
    组件的v-model实际做了两件事:
    <hy-input v-model="message"></hy-input>
   <!-- 绑定两个v-model -->
    <hy-input v-model="message" v-model:title="title"></hy-input>
    <hy-input :modelValue="message" @update:model-value="message = $event"></hy-input>

组件需要$emit(update:modelValue)。

配合组件自己的input的v-model使用:

<template>
  <div>
    <input v-model="value">
    
  </div>
</template>

<script>
  export default {
    props: {
      modelValue: String
    },
    emits: ["update:modelValue"],
    computed: {
      value: {
        set(value) {
          this.$emit("update:modelValue", value);
        },
        get() {
          return this.modelValue;
        }
      }
    },
    methods: {
      btnClick(event) {
        this.$emit("update:modelValue", event.target.value);
      }
    }
  }
</script>

<style scoped>

</style>

相关文章

网友评论

      本文标题:二、基础知识

      本文链接:https://www.haomeiwen.com/subject/bqigpltx.html