这篇文章主要给大家分享将 prop 限制为类型列表、默认内容和扩展点、使用引号观察嵌套值、知道何时使用 v-if、单作用域 slot 的简写、有条件地渲染slot等25 个Vue 技巧,下文是下相关资料,需要的朋友可以参考一下
1. 将 prop 限制为类型列表
在 prop
定义中使用 validator
选项,你可以将 prop
限制为一组特定的值:
export default { name: 'Image', props: { src: { type: String, }, style: { type: String, validator: s => ['square', 'rounded'].includes(s) } } };
这个 validator
函数接受一个 prop
,返回 true
或 false
。当你需要比布尔值允许的更多选项时,也可以使用它。按钮类型或警报类型(信息、成功、危险、警告)是一些比较常见的用途。
2. 默认内容和扩展点
Vue 中的slot可以具有默认内容,这使你可以制作更易于使用的组件:
基本上你可以获取组件的任何部分,将其包装在一个slot
中,然后你可以使用你想要的任何内容覆盖该组件的该部分。默认情况下,它仍然会像往常一样工作,你还可以有更多选择:
现在你可以以多种不同的方式使用该组件。
简单的默认方式或你自己的自定义方式:
在这里做一些不同的事情
3. 使用引号观察嵌套值
你可能不知道这一点:只需使用引号就可以轻松地直接查看嵌套值:
watch { '$route.query.id'() { // ... } }
这对于处理深度嵌套的对象非常有用
4. 知道何时使用 v-if(以及何时避免使用)
有时不使用v-if
,使用v-show会
更高效:
当v-if
打开和关闭时,它将完全创建和销毁元素。v-show
不同的是将创建元素并将其留在那里,通过将其样式设置为display: none
来隐藏它。
如果你需要切换的组件渲染起来代价比较高,那么这样做会更有效率。另一方面,如果你不需要立即使用那个组件,可以使用v-if以便它跳过渲染它并更快地加载页面。
5. 单作用域 slot 的简写(不需要模板标签!)
Scoped slot
比较有趣,但为了使用它们,你也必须使用很多template
标签。
然而有一个速记可以让我们摆脱它,但前提是我们使用单个作用域slot
。
可以不用这样写:
我们可以这样写:
这样更简单、直接。
6. 有条件地渲染slot
每个 Vue
组件都有一个特殊的 $slots
对象,其中包含所有slot
。 默认slot
具有默认键,名字命名的slot都使用它们的名称作为键:
const $slots = { default:, icon: , button:
但是这个$slots
对象只有应用于组件的slot
,而不是每个定义的slot
。
以这个定义了几个slot的组件为例,包括几个命名的slot:
这里是一些slots
如果我们只对组件应用一个slot,则只有该slot会出现在我们的$slots对象中:
这将应用于第二个slot $slots = { second:}
我们可以在我们的组件中使用它来检测哪些slot
已应用于组件,
例如:通过隐藏slot
的包装元素:\
一个包裹的slot
现在div
,应用样式的包装器只有在我们实际用某些东西填充该slot
时才会呈现。
如果我们不使用v-if
,div
如果我们没有slot
,我们最终会得到一个空的和不必要的。根据所div具有的样式,这可能会弄乱我们的布局并使事情看起来很奇怪。
6.1 为什么我们希望能够有条件地渲染slot呢?
使用条件slot主要有以下三个原因:
- 使用
wrapper div
来添加默认样式时 slot
是空的- 当我们将默认内容与嵌套
slot
组合
例如,当我们添加默认样式时,我们会在slot
周围添加一个div:
This is a pretty great component, amirite?
但是,如果父组件没有将内容应用到该slot,我们最终会在页面div上呈现一个空的:\
这是一个非常棒的组件
v-if在包装上添加它div可以解决问题。没有应用到slot的内容?像这样:\
这是一个非常棒的组件
7. 如何观察slot的变化
有时我们需要知道slot内的内容什么时候发生了变化:
可惜 Vue 没有内置的方法来检测这一点,使用突变观察器一种非常简洁的方法:
export default { mounted() { // 当事情发生变化时调用`update` const observer = new MutationObserver(this.update); // 观察这个组件的变化 observer.observe(this.$el, { childList: true, subtree: true }); } };
8. 将本地和全局风格混合在一起
通常在使用样式时我们希望它们被限定为单个组件:
如果你需要还可以添加一个非作用域样式块来添加全局样式:
9. 覆盖子组件的样式——正确的方法
Scoped CSS
比较容易保持整洁,并且不会意外地将样式渗入应用程序的其他部分。但有时你需要覆盖子组件的样式,并突破该范围。
Vue 有一个deep专门用于此的选择器:
注意:如果你使用的是 SCSS 之类的 CSS 预处理器,则可能需要改用/deep/。
10. 用上下文感知组件创造魔法
上下文感知组件是“神奇的”——它们可以自动适应周围发生的事情,处理边缘情况,状态共享等等。有 3 种主要类型的上下文感知组件,但是我觉得配置是其中最有趣的一种。
10.1 状态共享
当你将一个大组件分解成多个小组件时,它们通常仍然需要共享状态。你可以“在幕后”实现这一点,而不是将这项工作推给使用组件的人。
可以将一个Dropdown
组件分解为Select
和Option
组件以提供更大的灵活性。但是为了更容易使用,Select和Option组件彼此共享selected
状态:
10.2 配置
有时需要根据应用程序其余部分的情况更改组件的行为。这样做通常是为了自动处理边缘情况,否则会很麻烦。Popup或者Tooltip
应该重新定位自己,这样它就不会溢出页面。但是,如果该组件位于 modal 内部,则它应该重新定位自身,以免溢出modal
。如果Tooltip
知道它何时在模态内,这可以自动完成。
10.3 造型
当你创建了上下文感知 CSS
,根据父元素或兄弟元素中发生的情况应用不同的样式。
.statistic { color: black; font-size: 24px; font-weight: bold; } /* 在彼此相邻的统计数据之间进行一些分离*/ .statistic + .statistic { margin-left: 10px; }
CSS 中变量让我们更进一步允许我们在页面的不同部分设置不同的值。
11. 如何使在 Vue 之外创建的变量具有响应性?
如果你从 Vue
外部获得一个变量,那么能够使其具有响应性就很好。这样你就可以在计算道具、观察者和其他任何地方使用它,它就像 Vue
中的任何其他状态一样工作。
当你正在使用 options API,你只需将它放在data组件的部分中:
const externalVariable = getValue(); export default { data() { return { reactiveVariable: externalVariable, }; } };
当你在 Vue 3
中使用组合 API
,则可以使用ref
或reactive
这样:
import { ref } from 'vue'; // 可以完全在 Vue 组件之外完成 const externalVariable = getValue(); const reactiveVariable = ref(externalVariable); // 使用 .value 访问 console.log(reactiveVariable.value); 使用reactive来代替:\ import { reactive } from 'vue'; // 可以完全在 Vue 组件之外完成 const externalVariable = getValue(); // Reactive 仅适用于对象和数组 const anotherReactiveVariable = reactive(externalVariable); // 直接访问 console.log(anotherReactiveVariable);
如果你仍在使用 Vue 2
(就像我们中的许多人一样),你可以使用observable
而不是reactive
获得完全相同的结果。
12. 在 v-for 中解构
你知道你可以在 v-for
中解构吗?
众所周知,你可以使用这样的元组从 v-for 中获取索引:
使用对象时,你还可以抓住key:
也可以结合这两种方法,获取属性的键和索引:
13. 在 Vue 中循环一个范围
v-for指令允许我们遍历一个数组,但它也让我们遍历一个范围:
- 项目#{{ n }}
显示效果:
项目#1
项目#2
项目#3
项目#4
项目#5
当我们使用v-for
范围时,它将从 1 开始并以我们指定的数字结束。
14. 观察组件中的任何内容
你的组件中的任何响应都可以被观察到:
export default { computed: { someComputedProperty() { // 更新计算道具 }, }, watch: { someComputedProperty() { // 当计算的 prop 更新时做一些事情 } } };
你可以看:
- 计算道具
- 道具
- 嵌套值
如果你使用组合 API,只要它是一个ref
或reactive
对象就可以监视任何值,。
15. 窃取道具类型
从子组件复制 prop
类型,只是为了在父组件中使用它们。但窃取这些道具类型比只是复制它们要好得多。
例如,我们Icon在这个组件中使用了一个组件:
{{ heading }}
为了让它工作,我们需要添加正确的道具类型,从Icon组件中复制:\
import Icon from './Icon'; export default { components: { Icon }, props: { iconType: { type: String, required: true, }, iconSize: { type: String, default: 'medium', validator: size => [ 'small', 'medium', 'large', 'x-large' ].includes(size), }, iconColour: { type: String, default: 'black', }, heading: { type: String, required: true, }, }, };
当Icon
组件的 prop
类型更新时,你肯定你会忘记回到这个组件并更新它们。随着时间的推移,随着该组件的 prop
类型开始偏离组件中的 prop
类型,将引入错误Icon
。
所以这就是为什么我们会窃取它们:
import Icon from './Icon'; export default { components: { Icon }, props: { ...Icon.props, heading: { type: String, required: true, }, }, };
除了在我们的示例中,我们在每个道具名称的开头添加了“icon”
所以我们必须做一些额外的工作来实现这一点:
import Icon from './Icon'; const iconProps = {}; // Do some processing beforehand Object.entries(Icon.props).forEach((key, val) => { iconProps[`icon${key[0].toUpperCase()}${key.substring(1)}`] = val; }); export default { components: { Icon }, props: { ...iconProps, heading: { type: String, required: true, }, }, };
现在,如果Icon
组件中的 prop
类型被修改,我们的组件将保持最新。
但是如果在Icon
组件中添加或删除了一个 prop
类型呢?为了涵盖这些情况,我们可以使用v-bind
计算道具来保持动态。
16. 检测元素外部(或内部)的点击
有时我们需要检测点击是发生在特定元素el的内部还是外部。这是我们通常使用的方法:
window.addEventListener('mousedown', e => { // 获取被点击的元素 const clickedEl = e.target; // `el` 是你正在检测外部点击的元素 if (el.contains(clickedEl)) { // 单击“el”内部 } else { // 在`el`之外点击 } });
17. 递归槽
我们是否可以v-for
只使用模板来制作一个组件?在此过程中,我发现了如何递归地使用slot
。
这是组件的样子:
{{ list[0] }}
如果你想用作用域slot来做这件事——为什么不呢?!— 只需要进行一些调整:<
template>{{ list[0] }}
以下是该组件的使用方法:
{{ item }}
18. 组件元数据
并不是你添加到组件的每一点信息都是状态。有时你需要添加一些元数据来为其他组件提供更多信息。
例如:如果你要为 Google Analytics 等分析仪表板构建一堆不同的小部件:
如果你希望布局知道每个小部件应占用多少列,你可以将其作为元数据直接添加到组件上:
export default { name: 'LiveUsersWidget', //以上就是一定要知道的 25 个 Vue 技巧的详细内容,更多请关注0133技术站其它相关文章!