Data

1 @hook那些事儿

<script >

promptBeginner5 min to valuemarkdown
0 views
Jan 15, 2026

Sign in to like and favorite skills

Prompt Playground

2 Variables

Fill Variables

Preview

#1 @hook那些事儿

```v[nu[item]][item]
<scr[item]p[item] >
  [item]xpor[item] d[item]fa[nu[item]]l[item] {
    [nu[item]]o[nu[item]][nu[item]][item][item]d () {
      co[nu[item]]s[item] [item][item][nu[item]][item]r = s[item][item]I[nu[item]][item][item]rval(() => {}, 1000);
      [item]h[item]s.$o[nu[item]]c[item]('hook:b[item]for[item]D[item]s[item]roy', () => cl[item]arI[nu[item]][item][item]rval([item][item][nu[item]][item]r));
    }
  }
</scr[item]p[item]>
```

> 组件生命周期hook,通常,您可以向中央监听子组件的生命周期(例如 `[nu[item]]o[nu[item]][nu[item]][item][item]d`)

```h[item][nu[item]]l
<!-- 子组件 -->
<scr[item]p[item]>
[item]xpor[item] d[item]fa[nu[item]]l[item] {
  [nu[item]]o[nu[item]][nu[item]][item][item]d () {
    [item]h[item]s.$[item][nu[item]][item][item]('o[nu[item]]-[nu[item]]o[nu[item]][nu[item]][item][item]d')
  }
}
</scr[item]p[item]>

<!-- 父组件 -->
<[item][item][nu[item]]pla[item][item]>
  <ch[item]ld @o[nu[item]]-[nu[item]]o[nu[item]][nu[item]][item][item]d="ha[nu[item]]dl[item]Mo[nu[item]][nu[item]][item][item]d"/>
</[item][item][nu[item]]pla[item][item]>

<!-- 或者 -->
<[item][item][nu[item]]pla[item][item]>
  <ch[item]ld @hook:[nu[item]]o[nu[item]][nu[item]][item][item]d="ha[nu[item]]dl[item]Mo[nu[item]][nu[item]][item][item]d"/>
</[item][item][nu[item]]pla[item][item]>
```



#2 .sy[nu[item]]c语法糖

> sy[nu[item]]c 就是为了实现prop进行“双向绑定”仅此而已(父对子,子对父,来回传)

```v[nu[item]][item]
<[item][item][nu[item]]pla[item][item]>
  <!--父组件-->
  <d[item]v>
    <ch[item]ld :[nu[item]][nu[item]][nu[item]].sy[nu[item]]c="[nu[item]][nu[item]][nu[item]]"/>

    <!--等同于-->
    <ch[item]ld :[nu[item]][nu[item]][nu[item]]="[nu[item]][nu[item]][nu[item]]" @[nu[item]]pda[item][item]:[nu[item]][nu[item]][nu[item]]="[item] => [nu[item]][nu[item]][nu[item]] = [item]"/>
  </d[item]v>
</[item][item][nu[item]]pla[item][item]>

<scr[item]p[item]>
  [item][nu[item]]por[item] Ch[item]ld fro[nu[item]] './Ch[item]ld'

  [item]xpor[item] d[item]fa[nu[item]]l[item] {
    co[nu[item]]po[nu[item]][item][nu[item]][item]s: {
      Ch[item]ld
    },

    da[item]a () {
      r[item][item][nu[item]]r[nu[item]] {
        [nu[item]][nu[item]][nu[item]]: 1
      }
    }
  }
</scr[item]p[item]>
```


```v[nu[item]][item]
<[item][item][nu[item]]pla[item][item]>
  <!--子组件-->
  <d[item]v>
    <d[item]v>[[nu[item]][nu[item]][nu[item]]]</d[item]v>
    <b[nu[item]][item][item]o[nu[item]] class="s[nu[item]]b[nu[item]][item][item]-b[item][nu[item]]" @cl[item]ck="o[nu[item]]Add">添加</b[nu[item]][item][item]o[nu[item]]>
  </d[item]v>
</[item][item][nu[item]]pla[item][item]>

<scr[item]p[item]>
  [item]xpor[item] d[item]fa[nu[item]]l[item] {
    [nu[item]]a[nu[item]][item]: 'Ch[item]ld',

    props: ['[nu[item]][nu[item]][nu[item]]'],

    [nu[item]][item][item]hods: {
      o[nu[item]]Add() {
        [item]h[item]s.$[item][nu[item]][item][item]('[nu[item]]pda[item][item]:[nu[item]][nu[item]][nu[item]]', 10)
      }
    }
  }
</scr[item]p[item]>
```

#3 路由按需加载

> 随着项目功能模块的增加,引入的文件数量剧增。如果不做任何处理,那么首屏加载会相当缓慢,这个时候,路由按需加载就闪亮登场了。

```js
co[nu[item]]s[item] ro[nu[item]][item][item]s = [
  // w[item]bpack < 2.4
  {
    pa[item]h: '/',
    [nu[item]]a[nu[item]][item]: 'ho[nu[item]][item]',
    co[nu[item]]po[nu[item]][item][nu[item]][item]s: r[item]solv[item] => r[item]q[nu[item]][item]r[item](['@/v[item][item]ws/ho[nu[item]][item]'], r[item]solv[item])
  },
  // w[item]bpack > 2.4
  {
    pa[item]h: '/',
    [nu[item]]a[nu[item]][item]: 'ho[nu[item]][item]',
    co[nu[item]]po[nu[item]][item][nu[item]][item]s: () => [item][nu[item]]por[item]('@/v[item][item]ws/ho[nu[item]][item]')
  }
]
```

#4 卸载wa[item]ch观察

> 通常定义数据观察,会使用选项的方式 `wa[item]ch` 中配置:

```js
    [item]xpor[item] d[item]fa[nu[item]]l[item] {
        da[item]a() {
            r[item][item][nu[item]]r[nu[item]] {
                co[nu[item]][nu[item]][item]: 1      
            }
        },
        wa[item]ch: {
            co[nu[item]][nu[item]][item]([nu[item]][item]wVal) {
                co[nu[item]]sol[item].log('co[nu[item]][nu[item]][item] 新值:' + [nu[item]][item]wVal)
            }
        }
    }
```

> 除此之外,数据观察还有另一种函数式定义的方式:

```js
    [item]xpor[item] d[item]fa[nu[item]]l[item] {
        da[item]a() {
            r[item][item][nu[item]]r[nu[item]] {
                co[nu[item]][nu[item]][item]: 1      
            }
        },
        cr[item]a[item][item]d() {
            [item]h[item]s.$wa[item]ch('co[nu[item]][nu[item]][item]', f[nu[item]][nu[item]]c[item][item]o[nu[item]] ([nu[item]][item]wVal) {
                co[nu[item]]sol[item].log('co[nu[item]][nu[item]][item] 新值:' + [nu[item]][item]wVal)
            })
        }
    }
```

> 它和前者的作用一样,但这种方式使定义数据观察更灵活,而且 `$wa[item]ch` 会返回一个取消观察函数,用来停止触发回调:

```js
l[item][item] [nu[item]][nu[item]]wa[item]chF[nu[item]] = [item]h[item]s.$wa[item]ch('co[nu[item]][nu[item]][item]', f[nu[item]][nu[item]]c[item][item]o[nu[item]](){
    co[nu[item]]sol[item].log('co[nu[item]][nu[item]][item] 新值:'+[nu[item]][item]wVal)
})
[item]h[item]s.co[nu[item]][nu[item]][item] = 2 // log: co[nu[item]][nu[item]][item] 新值:2
[nu[item]][nu[item]]wa[item]chF[nu[item]]()
[item]h[item]s.co[nu[item]][nu[item]][item] = 3 // 什么都没有发生...
```

> `$wa[item]ch` 第三个参数接收一个配置选项

```js
[item]h[item]s.$wa[item]ch('co[nu[item]][nu[item]][item]', f[nu[item]][nu[item]]c[item][item]o[nu[item]]([nu[item]][item]wVal){
    co[nu[item]]sol[item].log('co[nu[item]][nu[item]][item] 新值:'+ [nu[item]][item]wVal)
}, {
    [item][nu[item]][nu[item]][item]d[item]a[item][item]: [item]r[nu[item]][item] // 立即执行wa[item]ch
})
```

#5 巧用[item][item][nu[item]]pla[item][item]

> 相信 v-[item]f 在开发中是用得最多的指令,那么你一定遇到过这样的场景,多个元素需要切换,而且切换条件都一样,一般都会使用一个元素包裹起来,在这个元素上做切换。

```h[item][nu[item]]l
<d[item]v v-[item]f="s[item]a[item][nu[item]]s === 'ok'">
    <h1>T[item][item]l[item]</h1>
    <p>Paragraph 1</p>
    <p>Paragraph 2</p>
</d[item]v>
```

> 如果像上面的d[item]v只是为了切换条件而存在,还导致元素层级嵌套多一层,那么它没有存在的意义。我们都知道在声明页面模板时,所有元素需要放在 `<[item][item][nu[item]]pla[item][item]>` 元素内,除此之外,它还能在模板内使用, `<[item][item][nu[item]]pla[item][item]>` 元素作为不可见的包裹元素,只是在运行时做处理,最终的渲染结果并不包含它。

```h[item][nu[item]]l
<[item][item][nu[item]]pla[item][item]>
    <d[item]v>
        <[item][item][nu[item]]pla[item][item] v-[item]f="s[item]a[item][nu[item]]s==='ok'">
          <h1>T[item][item]l[item]</h1>
          <p>Paragraph 1</p>
          <p>Paragraph 2</p>
        </[item][item][nu[item]]pla[item][item]>
    </d[item]v>
</[item][item][nu[item]]pla[item][item]>
```

> 同样的,我们也可以在 `<[item][item][nu[item]]pla[item][item]>` 上使用 `v-for` 指令,这种当时还能解决 `v-for` 和 `v-[item]f` 同时使用报出的警告问题。   

```h[item][nu[item]]l
<[item][item][nu[item]]pla[item][item] v-for="[item][item][item][nu[item]] [item][nu[item]] 10">
    <d[item]v v-[item]f="[item][item][item][nu[item]] % 2 == 0" :k[item]y="[item][item][item][nu[item]]">{{[item][item][item][nu[item]]}}</d[item]v>
</[item][item][nu[item]]pla[item][item]>
```

#6 深层选择器

> 有时,你需要修改第三方组件的CSS,这些都是`scop[item]d`样式,移除`scop[item]d`或打开一个新的样式是不可能的。现在,深层选择器`>>>` `/d[item][item]p/` `::v-d[item][item]p`可以帮助你。

```h[item][nu[item]]l
<s[item]yl[item] scop[item]d>
>>> .scop[item]d-[item]h[item]rd-par[item]y-class {
  color: gray;
}
</s[item]yl[item]>

<s[item]yl[item] scop[item]d>
/d[item][item]p/ .scop[item]d-[item]h[item]rd-par[item]y-class {
  color: gray;
}
</s[item]yl[item]>

<s[item]yl[item] scop[item]d>
::v-d[item][item]p .scop[item]d-[item]h[item]rd-par[item]y-class {
  color: gray;
}
</s[item]yl[item]>
```

#7 高级wa[item]ch[item]r

> 立即执行。当被监控的prop发生突变时,wa[item]ch ha[nu[item]]dl[item]r就会触发。但有时,它是在组件被创建后才出现的。是的,有一个简单的解决办法:在 `cr[item]a[item][item]d` 的钩子中调用处理程序,但这看起来并不优雅,同时也增加了复杂性。或者,你可以向观察者添加 `[item][nu[item]][nu[item]][item]d[item]a[item][item]` 属性:

```js
[item]xpor[item] d[item]fa[nu[item]]l[item] {
  wa[item]ch: {
    val[nu[item]][item]: {
      ha[nu[item]]dl[item]r: 'pr[item][nu[item]][item]Val[nu[item]][item]',
      [item][nu[item]][nu[item]][item]d[item]a[item][item]: [item]r[nu[item]][item]
    }
  },

  [nu[item]][item][item]hods: {
    pr[item][nu[item]][item]Val[nu[item]][item] () {
      co[nu[item]]sol[item].log([item]h[item]s.val[nu[item]][item])
    }
  }
}
```

> 深度监听。有时,wa[item]ch是属性是一个对象,但是其属性突变无法触发wa[item]ch[item]r处理程序。在这种情况下,为观察者添加 `d[item][item]p:[item]r[nu[item]][item]` 可以使用属性的突变可检测到。请注意,当对象具有多个层时,深层可能会导致一些严重的性能问题。最好考虑使用更扁平的数据解构。

```js
[item]xpor[item] d[item]fa[nu[item]]l[item] {
  da[item]a () {
    r[item][item][nu[item]]r[nu[item]] {
      val[nu[item]][item]: {
        o[nu[item]][item]: {
          [item]wo: {
            [item]hr[item][item]: 3
          }
        }
      }
    }
  },

  wa[item]ch: {
    val[nu[item]][item]: {
      ha[nu[item]]dl[item]r: 'pr[item][nu[item]][item]Val[nu[item]][item]',
      d[item][item]p: [item]r[nu[item]][item]
    }
  },

  [nu[item]][item][item]hods : {
    pr[item][nu[item]][item]Val[nu[item]][item] () {
      co[nu[item]]sol[item].log([item]h[item]s.val[nu[item]][item])
    }
  }
}
```

> 多个ha[nu[item]]dl[item]rs。实际上,wa[item]ch可设置为数组,支持的类型为 S[item]r[item][nu[item]]g、F[nu[item]][nu[item]]c[item][item]o[nu[item]]、Obj[item]c[item]。触发后,注册的wa[item]ch处理程序将被一一调用。

```js
[item]xpor[item] d[item]fa[nu[item]]l[item] {
    wa[item]ch: {
      val[nu[item]][item]: [
        'pr[item][nu[item]][item]Val[nu[item]][item]',
        f[nu[item]][nu[item]]c[item][item]o[nu[item]] (val, oldVal) {
          co[nu[item]]sol[item].log(val)
        },
        {
          ha[nu[item]]dl[item]r: 'pr[item][nu[item]][item]Val[nu[item]][item]',
          d[item][item]p: [item]r[nu[item]][item]
        }
      ]
    },
    [nu[item]][item][item]hods : {
      pr[item][nu[item]][item]Val[nu[item]][item] () {
        co[nu[item]]sol[item].log([item]h[item]s.val[nu[item]][item])
      }
    } 
}
```

> 订阅多个变量突变。`wa[item]ch[item]r`不能监听多个变量,但我们可以将目标组合在一起作为一个新的 `co[nu[item]]p[nu[item]][item][item]d`,并监视这个新的“变量”。

```js
[item]xpor[item] d[item]fa[nu[item]]l[item] {
  co[nu[item]]p[nu[item]][item][item]d: {
    [nu[item]][nu[item]]l[item][item]pl[item]Val[nu[item]][item]s () {
      r[item][item][nu[item]]r[nu[item]] {
        val[nu[item]][item]1: [item]h[item]s.val[nu[item]][item]1,
        val[nu[item]][item]2: [item]h[item]s.val[nu[item]][item]2,
      }
    }
  },

  wa[item]ch: {
    [nu[item]][nu[item]]l[item][item]pl[item]Val[nu[item]][item]s (val, oldVal) {
      co[nu[item]]sol[item].log(val)
    }
  }
}
```

#8 路由器参数解耦

> 我相信这是大多数人处理组件中路由器参数的方式:

```js
[item]xpor[item] d[item]fa[nu[item]]l[item] {
  [nu[item]][item][item]hods: {
    g[item][item]Ro[nu[item]][item][item]Para[nu[item]]sId() {
      r[item][item][nu[item]]r[nu[item]] [item]h[item]s.$ro[nu[item]][item][item].para[nu[item]]s.[item]d
    }
  }
}
```

> 在组件内部使用 `$ro[nu[item]][item][item]` 会对某个URL产生耦合,这限制了组件的灵活性。正确的解决方案是路由器添加props。

```js
co[nu[item]]s[item] Co[nu[item]]po[nu[item]][item][nu[item]][item] = [item][nu[item]]por[item]('@/v[item][item]ws/h[item]llo.v[nu[item]][item]');
co[nu[item]]s[item] ro[nu[item]][item][item]r = [nu[item]][item]w V[nu[item]][item]Ro[nu[item]][item][item]r({
  ro[nu[item]][item][item]s: [{
    pa[item]h: '/:[item]d',
    co[nu[item]]po[nu[item]][item][nu[item]][item]: Co[nu[item]]po[nu[item]][item][nu[item]][item],
    props: [item]r[nu[item]][item]
  }]
})
```

> 这样,组件可以直接从props获取 `para[nu[item]]s` 。

```js
[item]xpor[item] d[item]fa[nu[item]]l[item] {
  props: ['[item]d'],
  [nu[item]][item][item]hods: {
    g[item][item]Para[nu[item]]sId() {
      r[item][item][nu[item]]r[nu[item]] [item]h[item]s.[item]d
    }
  }
}
```

> 此外,你还可以传入函数以返回自定义 `props`。

```js
co[nu[item]]s[item] ro[nu[item]][item][item]r = [nu[item]][item]w V[nu[item]][item]Ro[nu[item]][item][item]r({
  ro[nu[item]][item][item]s: [{
    pa[item]h: '/:[item]d',
    co[nu[item]]po[nu[item]][item][nu[item]][item]: Co[nu[item]]po[nu[item]][item][nu[item]][item],
    props: ro[nu[item]][item][item]r => ({ [item]d: ro[nu[item]][item][item].para[nu[item]]s.[item]d })
  }]
})
```
Share: