总结
-
框架原理真的深入某一部分具体的代码和实现方式时,要多注意到细节,不要只能写出一个框架。
-
算法方面很薄弱的,最好多刷一刷,不然影响你的工资和成功率😯
-
在投递简历之前,最好通过各种渠道找到公司内部的人,先提前了解业务,也可以帮助后期优秀 offer 的决策。
-
要勇于说不,对于某些 offer 待遇不满意、业务不喜欢,应该相信自己,不要因为当下没有更好的 offer 而投降,一份工作短则一年长则 N 年,为了幸福生活要慎重选择!!!
喜欢这篇文章文章的小伙伴们点赞+转发支持,你们的支持是我最大的动力!
这个验证函数接受一个prop,如果prop有效或无效,则返回true
或false
。
当单单传入的 true 或 false 来控制某些条件不能满足需求时,我通常使用这个方法来做。
按钮类型或警告类型(信息、成功、危险、警告)是最常见的用法、、。颜色也是一个很好的用途。
2. 默认内容和扩展点
Vue中的槽可以有默认的内容,这使我们可以制作出更容易使用的组件。
<button class=“button” @click=“$emit(‘click’)”>
Click me
我最喜欢使用默认槽,就是用它们来创建扩展点。
我们可以取组件的任何部分,将其封装在一个插槽中,在外面我们可以用想要的任何内容覆盖组件的该部分。默认情况下,它仍然会按照原来的方式工作,但这样做会有了更多的选项
<button class=“button” @click=“$emit(‘click’)”>
{{ text }}
现在我们可以用许多不同的方式使用这个组件。简单的、默认的方式,或者自定义的方式。
Do something a little different here
3. 使用引号来监听嵌套属性
你可能不知道这一点,我们可以通过使用引号轻松地直接监听嵌套值:
watch {
‘$route.query.id’() {
// …
}
}
4. 知道何时使用v-if
(以及何时避免使用)
与其使用v-if
,有时使用v-show
来代替,会有更高的性能。
当v-if
被打开或关闭时,它将创建并完全销毁该元素。相反,v-show
将创建该元素并将其留在那里,通过设置其样式为display: none
来隐藏它。
如果你要切换的组件的渲染成本很高,那么这样做会更有效率。
反过来说,如果不需要立即执行昂贵的组件件,可以使用v-if
,这样它就会跳过渲染它,而使页面的加载速度更快一些。
5. 单个作用域插槽的简写(不需要 template 标签)
限定范围的插槽非常有趣,但为了使用它们,您还必须使用许多模板标记。
幸运的是,有一个简写可以让我们摆脱它,但只有在我们使用单个作用域槽的情况下。
普通写法:
<template #header=“tableAttributes”>
不使用 template
:
<DataTable #header=“tableAttributes”>
简单、直截了当,令人赞叹不已。
6. 有条件地渲染插槽
我们先来看如何做,然后在讨论为什么想隐藏插槽。
每个Vue组件都有一个特殊的$slots
对象,里面有你所有的插槽。默认槽的键是default
,任何被命名的槽都使用其名称作为键。
const $slots = {
default: ,
icon: ,
button: ,
};
但这个$slots
对象只有适用于该组件的插槽,而不是每一个定义的插槽。
拿这个定义了几个插槽的组件来说,包括几个命名的插槽。
Here are some slots
如果我们只对组件应用一个插槽,那么只有那个插槽会显示在我们的$slots
对象中。
<template #second>
This will be applied to the second slot.
$slots = { second: }
我们可以在我们的组件中使用这一点来检测哪些插槽已经被应用到组件中,例如,通过隐藏插槽的包装元素。
A wrapped slot
现在,应用样式的包装器div
只有在我们用某些东西填充这个插槽时才会被渲染。
如果不使用v-if
,那么如果没有插槽,就会得到一个空的不必要的div
。根据div
的样式,这可能会打乱我们的布局,让界面看起来很奇怪。
那么,为什么我们希望能够有条件地渲染插槽呢?
使用条件插槽的主要原因有三个:
-
当使用封装的
div
来添加默认样式时 -
插槽是空的
-
如果我们将默认内容与嵌套槽相结合
例如,当我们在添加默认样式时,我们在插槽周围添加一个div
:
This is a pretty great component, amirite?
<button @click=“$emit(‘click’)”>Click me!
然而,如果父组件没有将内容应用到该插槽中,我们最终会在页面上渲染出一个空的div
。
This is a pretty great component, amirite?
<button @click=“$emit(‘click’)”>Click me!
解决方法就是像上面讲的一样,多个条件判断,就行啦。
7. 如何监听一个插槽的变化
有时我们需要知道插槽内的内容何时发生了变化。
<slot @change=“update” />
不幸的是,Vue没有内置的方法让我们检测这一点。
然而,我的朋友Austin想出了一个非常干净的方法,使用MutationObserver来做这件事。
MutationObserver接口提供了监视对DOM树所做更改的能力。它被设计为旧的Mutation Events功能的替代品,该功能是DOM3 Events规范的一部分。
export default {
mounted() {
// 当有变化时调用update
const observer = new MutationObserver(this.update);
// 监听此组件的变化
observer.observe(this.$el, {
childList: true,
subtree: true
});
}
};
这个涉及的内容还是很多的,后面会单独出一篇文章来讲,记得关注刷碗智的公众号 <大迁世界> 哦!
8. 将局部和全局的 style
混合在一起
通常情况下,在处理样式时,我们希望它们能被划分到一个单独的组件中。
不过,如果需要的话,也可以添加一个非作用域样式块来添加全局样式
但要小心,全局样式是危险的,难以追踪。但有时,它们是一个完美的逃生舱口,正是你所需要的。
9. 重写子组件的样式–正确的方法
Scoped CSS在保持内容整洁方面非常棒,而且不会将样式引入应用的其他组件中。
但有时你需要覆盖一个子组件的样式,并跳出这个作用域。
Vue有一个 deep
选择器:
注意:如果你使用像SCSS这样的CSS预处理器,你可能需要使用/deep/
来代替。
10. 用上下文感知组件创造魔法
**上下文感知组件(context-aware)**是“魔法的”,它们自动适应周围发生的事情,处理边缘情况、状态共享等等。
有3种主要的 context-aware
,但 Configuration
是我最感兴趣的一种。
1.状态共享
当你把一个大的组件分解成多个小的组件时,它们往往仍然需要共享状态。
我们可以在 "幕后 "做这些工作,而不是把这些工作推给使用者。
我们一般会把 Dropdown
组件分解成 Select
和 Option
组件,这样会获得更多的灵活性。但是为了方便使用,Select
和Option
组件彼此共享 selected
状态。
2. Configuration
有时,一个组件的行为需要根据应用程序的其他部分的情况来改变。这通常是为了自动处理边缘情况,否则处理起来会很烦人。
一个 Popup
或 Tooltip
应该重新定位,以便它不会溢出页面。但是,如果该组件是在一个modal 内,它应该重新定位,以便它不会溢出 modal。
如果Tooltip
知道它是在一个模态里面,这可以自动完成。
3.样式
创建了 context-aware
的CSS,根据父级或同级元素的情况应用不同的样式。
.statistic {
color: black;
font-size: 24px;
font-weight: bold;
}
.statistic + .statistic {
margin-left: 10px;
}
CSS变量让我们更进一步,允许我们在一个页面的不同部分设置不同的值。
11. 如何在Vue之外创建一个具有响应性的变量(Vue2和3)
如果你从Vue之外得到一个变量,让它具有反应性是很好的。
这样,我们就可以在computed props
、watch
和其他任何地方使用它,它的工作方式就像Vue中的任何其他状态一样。
如果我们使用的选项API,需要的只是将其放在组件的数据部分中:
const externalVariable = getValue();
export default {
data() {
return {
reactiveVariable: externalVariable,
};
}
};
如果使用Vue3的组合API,可以直接使用ref
或reactive
。
import { ref } from ‘vue’;
// 可以完全在Vue组件之外完成
const externalVariable = getValue();
const reactiveVariable = ref(externalVariable);
console.log(reactiveVariable.value);
使用 reactive
代替:
import { reactive } from ‘vue’;
// 可以完全在Vue组件之外完成
const externalVariable = getValue();
// reactive 只对对象和数组起作用
const anotherReactiveVariable = reactive(externalVariable);
// Access directly
console.log(anotherReactiveVariable);
如果你还在使用 Vue2,你可以使用observable
而不是reactive
来实现完全相同的结果。
12. v-for 中的解构
你知道可以在-vfor
中使用解构吗?
v-for=“{ name, id } in users”
:key=“id”
{{ name }}
更广为人知的是,可以通过使用这样的元组从v-for
中取出索引。
‘Lion King’,
‘Frozen’,
‘The Princess Bride’
]">
{{ index + 1 }} - {{ movie }}
当使用一个对象时,可以这样使用 key
:
name: ‘Lion King’,
released: 2019,
director: ‘Jon Favreau’,
}">
{{ key }}: {{ value }}
也可以将这两种方法结合起来,获取key
以及属性的 index
。
name: ‘Lion King’,
released: 2019,
director: ‘Jon Favreau’,
}">
#{{ index + 1 }}. {{ key }}: {{ value }}
13. 在指定范围内循环
v-for
指令允许我们遍历数组,但它也允许我们遍历一个范围
- Item #{{ n }}
渲染结果:
Item #1
Item #2
Item #3
Item #4
Item #5
当我们使用带范围的
v-for
时,它将从1
开始,以我们指定的数字结束。14. 监听你的组件中的任何东西
export default {
computed: {
someComputedProperty() {
// Update the computed prop
},
},
watch: {
someComputedProperty() {
// Do something when the computed prop is updated
}
}
};
我们可以监听:
-
计算属性
-
props
-
嵌套值
如果你使用组合API,任何值都可以被监视,只要它是一个
ref
或reactive
对象。15.窃取 prop 类型
我从一个子组件中复制 prop 类型,只是为了在一个父组件中使用它们。但我发现,偷取这些 prop 类型要比仅仅复制它们好得多。
例如,我们在这个组件中使用了一个
Icon
组件。{{ heading }}
<Icon
:type=“iconType”
:size=“iconSize”
:colour=“iconColour”
/>
为了让它工作,我们需要添加正确的 prop 类型,从``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
类型开始偏离Icon
组件中的 prop 类型时,就会引入错误。因此,这就是为什么我们要窃取组件的
prop
类型:import Icon from ‘./Icon’;
export default {
components: { Icon },
props: {
…Icon.props,
heading: {
type: String,
required: true,
},
},
};
不需要再复杂了。
除了在我们的例子中,我们把
icon
加在每个prop
名称的开头。所以我们必须做一些额外的工作来实现这一点。import Icon from ‘./Icon’;
const iconProps = {};
Object.entries(Icon.props).forEach((key, val) => {
iconProps[
icon${key.toUpperCase()}
] = val;});
export default {
components: { Icon },
props: {
…iconProps,
heading: {
type: String,
required: true,
},
},
};
现在,如果
Icon
组件中的prop
类型被修改,我们的组件将保持最新状态。但是,如果一个
prop
类型从Icon
组件中被添加或删除了呢?为了应对这些情况,我们可以使用v-bind
和一个计算的prop
来保持动态。16. 检测元素外部(或内部)的单击
有时我需要检测一个点击是发生在一个特定元素
el
的内部还是外部。这就是我通常使用的方法。window.addEventListener(‘mousedown’, e => {
// 获取被点击的元素
const clickedEl = e.target;
if (el.contains(clickedEl)) {
//在 "el "里面点击了
} else {
//在 "el "外点击了
}
});
17. 递归插槽
有一次,我决定看看我是否可以只用模板来做一个
v-for
组件。在这个过程中,我也发现了如何递归地使用槽。{{ list[0] }}
<v-for
v-if=“list.length > 1”
:list=“list.slice(1)”
/>
如果你想用作用域插槽来做这件事,只是需要一些调整
最后
四轮技术面+一轮hr面结束,学习到了不少,面试也是一个学习检测自己的过程,面试前大概复习了 一周的时间,把以前的代码看了一下,字节跳动比较注重算法,面试前刷了下leetcode和剑指offer, 也刷了些在牛客网上的面经。大概就说这些了,写代码去了~
祝大家都能收获大厂offer~
篇幅有限,仅展示部分内容
-