Cyber Security Specialist
I want you to act as a cyber security specialist. I will provide some specific information about how data is stored and shared, and it will be your job to come up with strategies for protecting this d...
<script >
Sign in to like and favorite skills
#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 })
}]
})
```
I want you to act as a cyber security specialist. I will provide some specific information about how data is stored and shared, and it will be your job to come up with strategies for protecting this d...
I want to act as a Statistician. I will provide you with details related with statistics. You should be knowledge of statistics terminology, statistical distributions, confidence interval, probabillit...
I want you to act as a scientific data visualizer. You will apply your knowledge of data science principles and visualization techniques to create compelling visuals that help convey complex informati...
#1 @hook那些事儿
<script > export default { mounted () { const timer = setInterval(() => {}, 1000); this.$once('hook:beforeDestroy', () => clearInterval(timer)); } } </script>
组件生命周期hook,通常,您可以向中央监听子组件的生命周期(例如
)mounted
<!-- 子组件 --> <script> export default { mounted () { this.$emit('on-mounted') } } </script> <!-- 父组件 --> <template> <child @on-mounted="handleMounted"/> </template> <!-- 或者 --> <template> <child @hook:mounted="handleMounted"/> </template>
#2 .sync语法糖
sync 就是为了实现prop进行“双向绑定”仅此而已(父对子,子对父,来回传)
<template> <!--父组件--> <div> <child :num.sync="num"/> <!--等同于--> <child :num="num" @update:num="e => num = e"/> </div> </template> <script> import Child from './Child' export default { components: { Child }, data () { return { num: 1 } } } </script>
<template> <!--子组件--> <div> <div>{{num}}</div> <button class="submit-btn" @click="onAdd">添加</button> </div> </template> <script> export default { name: 'Child', props: ['num'], methods: { onAdd() { this.$emit('update:num', 10) } } } </script>
#3 路由按需加载
随着项目功能模块的增加,引入的文件数量剧增。如果不做任何处理,那么首屏加载会相当缓慢,这个时候,路由按需加载就闪亮登场了。
const routes = [ // webpack < 2.4 { path: '/', name: 'home', components: resolve => require(['@/views/home'], resolve) }, // webpack > 2.4 { path: '/', name: 'home', components: () => import('@/views/home') } ]
#4 卸载watch观察
通常定义数据观察,会使用选项的方式
中配置:watch
export default { data() { return { count: 1 } }, watch: { count(newVal) { console.log('count 新值:' + newVal) } } }
除此之外,数据观察还有另一种函数式定义的方式:
export default { data() { return { count: 1 } }, created() { this.$watch('count', function (newVal) { console.log('count 新值:' + newVal) }) } }
它和前者的作用一样,但这种方式使定义数据观察更灵活,而且
会返回一个取消观察函数,用来停止触发回调:$watch
let unwatchFn = this.$watch('count', function(){ console.log('count 新值:'+newVal) }) this.count = 2 // log: count 新值:2 unwatchFn() this.count = 3 // 什么都没有发生...
第三个参数接收一个配置选项$watch
this.$watch('count', function(newVal){ console.log('count 新值:'+ newVal) }, { immediate: true // 立即执行watch })
#5 巧用template
相信 v-if 在开发中是用得最多的指令,那么你一定遇到过这样的场景,多个元素需要切换,而且切换条件都一样,一般都会使用一个元素包裹起来,在这个元素上做切换。
<div v-if="status === 'ok'"> <h1>Title</h1> <p>Paragraph 1</p> <p>Paragraph 2</p> </div>
如果像上面的div只是为了切换条件而存在,还导致元素层级嵌套多一层,那么它没有存在的意义。我们都知道在声明页面模板时,所有元素需要放在
元素内,除此之外,它还能在模板内使用,<template>元素作为不可见的包裹元素,只是在运行时做处理,最终的渲染结果并不包含它。<template>
<template> <div> <template v-if="status==='ok'"> <h1>Title</h1> <p>Paragraph 1</p> <p>Paragraph 2</p> </template> </div> </template>
同样的,我们也可以在
上使用<template>指令,这种当时还能解决v-for和v-for同时使用报出的警告问题。v-if
<template v-for="item in 10"> <div v-if="item % 2 == 0" :key="item">{{item}}</div> </template>
#6 深层选择器
有时,你需要修改第三方组件的CSS,这些都是
样式,移除scoped或打开一个新的样式是不可能的。现在,深层选择器scoped>>>/deep/可以帮助你。::v-deep
<style scoped> >>> .scoped-third-party-class { color: gray; } </style> <style scoped> /deep/ .scoped-third-party-class { color: gray; } </style> <style scoped> ::v-deep .scoped-third-party-class { color: gray; } </style>
#7 高级watcher
立即执行。当被监控的prop发生突变时,watch handler就会触发。但有时,它是在组件被创建后才出现的。是的,有一个简单的解决办法:在
的钩子中调用处理程序,但这看起来并不优雅,同时也增加了复杂性。或者,你可以向观察者添加created属性:immediate
export default { watch: { value: { handler: 'printValue', immediate: true } }, methods: { printValue () { console.log(this.value) } } }
深度监听。有时,watch是属性是一个对象,但是其属性突变无法触发watcher处理程序。在这种情况下,为观察者添加
可以使用属性的突变可检测到。请注意,当对象具有多个层时,深层可能会导致一些严重的性能问题。最好考虑使用更扁平的数据解构。deep:true
export default { data () { return { value: { one: { two: { three: 3 } } } } }, watch: { value: { handler: 'printValue', deep: true } }, methods : { printValue () { console.log(this.value) } } }
多个handlers。实际上,watch可设置为数组,支持的类型为 String、Function、Object。触发后,注册的watch处理程序将被一一调用。
export default { watch: { value: [ 'printValue', function (val, oldVal) { console.log(val) }, { handler: 'printValue', deep: true } ] }, methods : { printValue () { console.log(this.value) } } }
订阅多个变量突变。
不能监听多个变量,但我们可以将目标组合在一起作为一个新的watcher,并监视这个新的“变量”。computed
export default { computed: { multipleValues () { return { value1: this.value1, value2: this.value2, } } }, watch: { multipleValues (val, oldVal) { console.log(val) } } }
#8 路由器参数解耦
我相信这是大多数人处理组件中路由器参数的方式:
export default { methods: { getRouteParamsId() { return this.$route.params.id } } }
在组件内部使用
会对某个URL产生耦合,这限制了组件的灵活性。正确的解决方案是路由器添加props。$route
const Component = import('@/views/hello.vue'); const router = new VueRouter({ routes: [{ path: '/:id', component: Component, props: true }] })
这样,组件可以直接从props获取
。params
export default { props: ['id'], methods: { getParamsId() { return this.id } } }
此外,你还可以传入函数以返回自定义
。props
const router = new VueRouter({ routes: [{ path: '/:id', component: Component, props: router => ({ id: route.params.id }) }] })