
想着作为一个 Vuer,平时却没有怎么好好的看过官方文档,这次找了个时间看了一番,不得不说 Vue 的文档写的还是很详细的。从里面整理出来一些小技巧,希望能帮助大家提高平时的开发效率。毕竟:
传输一个对象的所有属性平时我们在开发的时候,经常会通过父组件给子组件传递很多 prop,一般我们可能会这样写:
这样写当然也是没问题的, 但是这样的写法并不是很优雅,并且每需要多传一个属性给子组件,我就需要多写一个类似:prop="prop"的属性传递,写多了也很繁琐。
其实我们可以使用 v-bind="object"来代替一个个的 :prop-name="propValue", v-bind会传递这个对象中的所有 property给子组件。
假设我们要传递给子组件这么一些属性
post: {
id: 1,
title: 'My Journey with Vue'
}
通过 v-bind,我们可以写成这样:
这种写法其实是等同于下面这种写法的,但是会方便很多。
$attrs 实现透传
包含了父作用域中不作为组件
props或自定义事件的attribute绑定和事件。当一个组件没有声明任何prop时,这里会包含所有父作用域的绑定,并且可以通过v-bind="$attrs"传入内部组件——这在创建高阶的组件时会非常有用。
简单来说,就是在父作用域传给子组件的一些属性或者事件,但是在子作用域又没有进行定义的,都会被包含在 $attrs 里面,比如 class,style,id,在创建高阶的组件的时候非常有用。
我们在用基础组件的时候,往往需要根据业务场景对这些基础组件进行一些封装,这时候 $attrs就能发挥很大的作用。通过 v-bind="$attrs",轻松实现属性透传。
但是当组件是单个根节点时,非 prop 的 attribute 会自动添加到根结点的 attribute 上,这时候我们可以通过设置inheritAttrs: false将其禁用,以保证非 prop 的 attribute只在我们添加的元素上生效。
// 子组件
$attrs:
// 父组件
显示的效果如下:
需要注意的点是,在 Vue2 中,是可以通过 v-on="$listeners" 来获取传递的事件,但是在 Vue3 中 $listeners被移除了,通过 $attrs 就能获取到事件监听器。
具体示例放在了 codesandox 中,可以戳这里。
平时在使用 props 传递的时候,是不是只会这样写
props: ['propsA']
// 或者这样
props: {
propB: {
type: Number,
default: 100
},
}
但其实,prop 也能自定义验证函数,实现更精细的控制,这在开发一个公共类型的组件时尤其有帮助。
props: {
// 自定义验证函数
propC: {
validator(value) {
// 这个值必须与下列字符串中的其中一个相匹配
return ["success", "warning", "danger"].includes(value);
},
},
},
当 prop 验证失败的时候,开发环境下 Vue 将会产生一个控制的告警用于提示。
codesandox - 代码示例
定义 v-model 修饰符v-model有许多内置的修饰符,比如 .trim,.number,可以更好的提高我们的开发效率,但是在某些情况下,我们还需要有自定义的修饰符。
我们来演示一个自定义修饰符 capitalize,它可以将 v-model 绑定的字符串第一个字母大写,添加到组件 v-model 的修饰符将通过 modelModifiers prop 提供给组件。
// 父组件
// 子组件
在这个示例中,每当输入框触发 input 事件时,都会将首字母变大写。示例在这。
Provide/Inject有时候我们会碰到一些深度嵌套的组件,当孙孙孙子组件想用顶层父组件的内容,如果仍然将 prop 沿着组件一层一层往下传,会非常的麻烦,这时候就可以使用 provide 和 inject。
父组件用一个 provide 来提供数据,子组件用 inject来接受数据,我们可以将这种方式看作是长距离的 prop,只是父组件并不知道哪些自组件用了这些数据,而子组件也并不知道接收的属性来自哪里。
// 父组件
export default {
name: "ParentComponent",
// provide: {
// provideData: "provideData",
// },
// 一般使用上面的方式即可,但是要使用到组件的实例属性,则需要下面这种方式
provide() {
return {
provideData: this.str.length,
};
},
};
// 孙子组件
export default {
name: "ChildComponent",
inject: ["provideData"],
};
但是这样传递的数据是没有响应式的,即父组件 provide 的数据更改了,孙子组件 inject 到的数据也不能做出相应的更改,但是可以通过 provide 传递一个具有响应式的数据来改变这种情况。
示例戳这里。
指令的动态参数在 Vue 中,指令的参数是可以使用表达式的,只需要用方括号括起来:
...
// 或者
...
在示例中,attributeName 和 eventName都会作为表达式被求值,将求得的值作为最终的参数使用。
如果 attributeName 为 href ,那就等价于 v-bind:href。
同理,如果当 eventName 的值为 "focus" 时,v-on:[eventName]将等价于 v-on:focus
假设我有一个父组件 和 一个子组件 , 我想在子组件更新的时候,父组件进行一些逻辑处理。一般可能会在子组件中的生命周期函数里 emit('something'),但其实有更简洁的方式
这样就可以轻松在父组件内部轻松监听到子组件的生命周期,从而避免父子组件产生更强的耦合。
在 Vue2 中,这些事件名和相应的生命周期钩子一致,并带有 hook: 前缀,但是在 Vue3 中,事件名附带的是 vnode- 前缀:
组件样式特性
scoped
当 标签带有 scoped attribute 的时候,它的 CSS 只会应用到当前组件的元素上。通过PostCSS转换可以看到,在样式后面添加了[data-v-f3f3eg9],来标识这个样式只在该组件内生效。
hi
hi
插槽选择器
我们在创建一个组件的时候,为了灵活性,有时候会在组件内部设置插槽,但是在默认情况下,该组件的作用域样式是影响不到 里的内容的,因为这些内容被认为是父组件的,但是我们可以通过 :slotted 伪类以确切地将插槽内容作为选择器的目标。
深度选择器
在需求的开发中,难免会用到第三方的组件库,但是在 scoped 下,又不能对第三方组件样式进行修改,放在全局又容易对其他地方产生影响,这时候可以使用 :deep() 这个伪类, 或者使用 ::v-deep 和 >>> 深度选择器。
全局选择器
有时候需要在同一个组件中同时包含作用域样式和非作用域样式,会这样写:
需要两个 标签,如果组件中需要的全局样式不是很多的时候,可以使用 :global 伪类来实现,就可以少写一个标签了。
$event
有时候在绑定了事件时,我们需要传一些参数的情况下,还想获取原始的 DOM 事件,可以用特殊变量 $event 把它传入方法:
// 在方法中传入 $event
// ...
methods: {
warn(message, event) {
// 现在可以访问到原生事件
if (event) {
event.preventDefault()
}
alert(message)
}
}
–
有时候在绑定了事件时,我们需要传一些参数的情况下,还想获取原始的 DOM 事件,可以用特殊变量 $event 把它传入方法:
// 在方法中传入 $event
// ...
methods: {
warn(message, event) {
// 现在可以访问到原生事件
if (event) {
event.preventDefault()
}
alert(message)
}
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)