# 数据劫持

Vue2使用的是Object.defineProperty来进行数据拦截依赖收集,无法做到深层次的监听

​ Vue3使用的是proxy的代理拦截,可以进行深层次的拦截

# 检测变化的注意事项 (opens new window)

对数组进行以下操作不是响应式的:

  • vm.items[indexOfItem] = newValue
  • vm.items.length = newLength

解决办法:

# $set

// 直接给数组赋值 arr[index] = newValue vue无法监听到
// vm.$set( target, key, value ). This is the alias of the global Vue.set. (Vue 2 Snippets)
this.$set(target, key, value)
1
2
3
<script>
export default {
  data() {
    this.obj = { name: 'zs', age: 18 }
    return {
      arr: {
        a1: 'a1',
        a2: 'a2',
      },
    }
  },
  // obj 不是响应式的,arr是响应式的
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13

# 对象

只有在初始化时在data对象上的的对象才具有响应式,如果是后续阶段去添加的对象,其属性是不具有响应式的。

# v-model的原理

v-model实际上是 :value 和 @input 的语法糖

<BaseInput :value="message" @input="message = $event" />
<base-input v-model="message"></base-input>

<!-- 以上两段代码是等效的 -->

<!-- 子组件内部 -->
<template>
  <div class="hello">
    <input
      type="text"
      :value="value"
      @input="$emit('input', $event.target.value)"
    />
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: {
    value: String,
  },
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

demo (opens new window)

# sync修饰符

<my-input :value="searchText" @update:value="(val) => (searchText = val)">
</my-input>
<!-- 等效于 -->
<my-input :value.sync="searchText"></my-input>

<!-- 子组件 -->
<template>
  <div class="hello">
    MyInput:<input type="text" :value="value" @input="handleInput" />
  </div>
</template>

<script>
export default {
  name: "MyInput",
  props: {
    value: String,
  },
  methods: {
    handleInput(e) {
      this.$emit("update:value", e.target.value);
    },
  },
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

注意带有 .sync 修饰符的 v-bind 不能和表达式一起使用 (例如 v-bind:title.sync=”doc.title + ‘!’” 是无效的)。取而代之的是,你只能提供你想要绑定的 property 名,类似 v-model。

watch深度监听

https://github.com/fncheng/fe/issues/14