编写Vue.js组件前需要知道的10件事

2019 年 7 月 09 日

编写Vue.js组件前需要知道的10件事

本文介绍了编写 Vue.js 组件前需要知道的 10 件事,其中包括:组件可以全局或局部加载;延迟加载 / 异步组件;必需的 Props;使用 $emit 触发自定义事件;多 Props 绑定和覆盖等等。


1. 组件可以全局或局部加载


Vue.js 提供了两种加载组件的方法:一种是 Vue 实例中的全局加载,另一种是组件级的加载。两种方法都有各自的优点。


全局加载的组件可以从应用程序中的任何模板(包括子组件)访问。它限制了将全局组件导入子组件的次数。此外,如果你全局加载组件,就不会得到 Vue 注册组件错误“你注册的组件正确吗?”注意,加载全局组件要谨慎。它会使你的应用程序膨胀,即使不使用,它仍然会包含在你的 Webpack 构建中。


import Vue from 'vue';import Editor from './componetns/Editor.vue'
//Where 'editor' is the name of the component <editor></editor>Vue.component('editor', Editor);

复制代码


局部加载组件使你能够隔离组件,并且只在必要时加载它们。当与 Webpack 结合使用时,你可以只在使用组件时延迟加载它们。这使你的应用程序初始文件较小,并减少了初始加载时间。


<template>  <section>    <editor></editor>  </section></template>
<script>import Editor from './Editor'export default { name: 'dashboard', components: { Editor }}</script>
复制代码


2. 延迟加载 / 异步组件


使用 Webpack 的动态导入来延迟加载组件。Vue 支持在渲染时延迟加载组件和代码分割。这些优化让你可以只在需要时加载组件代码,从而减少 HTTP 请求、文件大小,并自动提高性能。这个特性的重要之处在于,它既可以处理全局加载的组件,也可以处理局部加载的组件。


全局加载异步组件:



import Vue from 'vue';
//Where 'editor' is the name of the component <editor></editor>//Returns a promise that only gets called when the compoent is rendered and then cached.Vue.component('editor', () => import('./componetns/Editor.vue'));
复制代码


本地加载异步组件:


<template>  <section>    <editor></editor>  </section></template>
<script>export default { name: 'dashboard', components: { 'Editor': () => import('./Editor') }}</script>
复制代码


“当他们将平均页面加载时间减少 850 毫秒时,COOK 将转化率提高了 7%,跳出率降低了 7%,每次会话增加了 10%。”


3. 必需的 Props


有很多方法可以为组件创建 props;你可以传递一个表示 prop 名称的字符串数组,也可以传递一个以键作为 prop 名称的对象和一个配置对象。


使用基于对象的方法,你可以为单个 prop 创建一些键配置更改,其中之一就是必需的键。必需的键需要一个 true 或 false 值。当组件被使用时,如果 prop 没有设置,true 就会抛出一个错误,false(默认值)就不必需或者抛出一个错误。在和其他开发人员共享组件以及提醒你自己某个 prop 对该组件至关重要时,这是很好的做法。


<template>  <section>    <editor v-if="isAdmin"></editor>  </section></template>
<script>export default { name: 'Editor', props: { enabled: {}, isAdmin: { required: true } }}</script>
复制代码


4. 使用 $emit 触发自定义事件


子组件和父组件之间的通信可以通过使用组件内置的函数emit 函数接受一个事件名称字符串和要发出的可选值。要侦听事件,只需将“@eventName”添加到发出事件的组件并传入事件处理程序。这是一种很好的方法,可以保持真相的单一来源,并使数据从子组件流向父组件。


<template>  <section>    <button @click="onClick">Save</button>  </section></template>
<script>export const SAVE_EVENT = 'save';export default { name: 'triggerEvent', methods: { onClick() { this.$emit(SAVE_EVENT); } }}</script>

复制代码


<template>  <section>  <p v-show="showSaveMsg">Thanks for Listening for the saved event</p>  <trigger-event @save="onSave"></trigger-event>  </section></template>
<script>export default { name: 'TriggerEvent', data(){ return { showSaveMsg: false } }, components:{ //You can find Trigger Custom Events in VueJs https://gist.github.com/eabelard/36ebdc8367bfeff75387cc863c810f65 TriggerEvent: () => import('./TriggerEvent') }, methods: { onSave() { this.showSaveMsg = true; } }}
复制代码


5. 将组件分解为逻辑块


说起来容易做起来难,但是你如何定义要将组件分解成什么样的逻辑块?分解组件的第一种方法是基于数据变化率。如果数据在组件的某个部分始终在变化,而在其他部分没有变化,那么它可能应该自成组件。


这样做的原因是,如果你的数据/HTML 在模板的一个部分中不断变化,那么整个模板都需要检查和更新。但是,如果将相同的 HTML 放入它自己的组件中,并使用 props 传递数据,那么当它的 props 发生更改时,只有那个组件才会更新。


另一种从逻辑上分解组件的方法是重用。如果你的 HTML、图形或功能在整个应用程序中始终如一地使用,比如按钮、复选框、徽标动画、操作调用或文本简单变化的图形,那么它们就是可以隔离到一个可重用的新组件中的很好的候选项。可重用组件具有易于维护的潜在好处,因为你可以更改一个组件,而不必在代码库中查找替换和更改多个地方。


6. 验证 Props


使用对象表示法来配置每个 prop,而不是使用字符串数组来定义 prop。两种非常有用的配置样式是“type”和 validator。


使用类型参数,Vue 将对你的 prop 值进行自动类型检查。例如,如果我们期望一个 Number prop,但收到了一个 String,你会在控制台收到类似这样的警告:


[Vue warn]: Invalid prop: type check failed for prop “count”. Expected Number


对于更复杂的验证,我们可以将函数传递给 validator 属性,该属性以该值作为参数并返回 true 或 false。这非常强大,因为它允许我们针对传递给该特定属性的值编写自定义验证。


<template>  <section class="custom-validation" :class="[{enabled}, status]">    <p>You {{status}} the test</p>  </section></template>
<script>export default { name: "CustomValidation", props: { enabled: Boolean, status: { default: "fail", validator: function(value) { return ["pass", "fail"].includes(value); } } }};</script><style scoped></style>
复制代码


7. 多 Props 绑定和覆盖


如果组件有许多 props(比如 5、6、7 或更多),那么不断地为每个 prop 设置绑定可能会变得单调乏味。幸运的是,有一种快速的方法可以设置组件上所有属性的绑定,那就是使用 v-bind 绑定对象,而不是单个属性。


使用对象绑定的另一个好处是可以覆盖来自对象的任何绑定。在我们的例子中,如果我们在 person 对象中将 isActive 设置为 false,那么我们就可以对实际的 person 组件执行另一个绑定,并将 isActive 设置为 true,而不覆盖原始组件。


<template>  <div id="app">    <person v-bind="person" :isActive="true"/>  </div></template>
<script>import Person from "./components/Person.vue";export default { name: "App", components: { Person }, data() { return { person: { firstName: "Jaxson", lastName: "Pierre", dob: "05/22/1996", isActive: false } }; }};</script>
复制代码


8. 在组件中修改 Props


在某些情况下,你可能希望修改从某个 prop 传入的值。然而,这样做你会收到一个警告“避免直接改变一个 prop”,因为你的确不该。相反,使用 prop 值作为局部数据属性的默认值。这样做将使你能够看到原始值,而修改局部数据不会改变 prop 值。


这是有代价的。使用此方法,你的局部数据属性不会对 prop 值作出反应,因此来自父组件的任何对 prop 值的更改都不会更新你的局部值。但如果确实需要这些更新,则可以使用 computed 属性来组合值。


<template>  <main>    <section>      <h2>Non Reactive</h2>      <p>{{ localFirstName }}</p>      <button @click.prevent="changeLocalFirstName">Update First Name</button>    </section>    <section>      <h2>Reactive List</h2>      <ol>        <li v-for="item in itemsList" :key="item">{{ item }}</li>      </ol>    </section>  </main></template>
<script>export default { name: "FullName", props: { firstName: { type: String, default: "Mike" }, title: { type: String, default: "Senior" }, items: { type: Array, default() { return ["lemons", "oranges"]; } } }, computed: { itemsList() { return [...this.items, ...this.localItems]; } }, data() { return { localItems: ["mangos", "apples"], localFirstName: this.firstName }; }, methods: { changeLocalFirstName() { this.localFirstName = "Jackson"; } }};</script>
<style scoped></style>
复制代码


9. Test Utils Mount 与 Shallow Mount


有两种方法可以在 Vue tests utils 中创建和引导组件。一个是 mount,另一个是 shallow mount;两者各有优缺点。


当你希望在组件及其子组件之间进行共生测试时,mount 技术非常有效。它让你可以测试父组件是否正确地与子组件进行预期的交互。相反,正如名称所示,shallow mount 只实例化父组件并在完全隔离的情况下渲染它,而不考虑它的任何子组件。


那么哪种方法更好呢?这取决于你。你选择的策略应该取决于你自己的可衡量目标。试着在完全隔离的情况下单独测试组件,shallow 方法工作得很好。需要处理包含子组件的组件,而且要确保通信,那么就要使用 mount 选项。一个很好的选择是两者都使用。你并不必局限于一个,以混合搭配满足测试需求为准。


10. 强大的 Vue-cli


Vue CLI 是一个功能强大的命令行界面,它使得开发人员可以快速地利用大量可以加速工作流的特性。


我经常使用的一个特性是运行 vue serve 并将路径传递给 vue 组件。这样做的好处在于,你可以完全独立地开发组件,同时还可以热重载和遍历组件,直到它的核心功能都完成了为止。不需要临时将新组件导入要开发的页面。


vue serve ./components/views/GoldenRule


在团队中工作时,你可能希望提取一个特定的组件并与其他组件共享。这就需要 Vue CLI 的下一个特性:将 Vue 组件导出为库的能力。当被调用时,Vue 将自动构建一个单文件组件,将 CSS 移到一个外部 CSS 文件中(可选的,你也可以内联它),并创建 UMD 和 Common .js 文件,以导入其他 JS 项目。


vue build —-target lib --name goldenRule ./components/views/GoldenRule


英文原文:https://levelup.gitconnected.com/10-things-you-should-know-before-writing-your-next-vuejs-component-4f97964611f4


2019 年 7 月 09 日 19:094409
用户头像

发布了 323 篇内容, 共 140.6 次阅读, 收获喜欢 661 次。

关注

评论 1 条评论

发布
用户头像
第7条什么意思啊,没看懂。
2019 年 07 月 15 日 10:28
回复
没有更多评论了
发现更多内容

Java中的Stream用还是不用

孙苏勇

Java 流计算 程序设计 性能

当我们在说5G网络安全的时候,究竟在说什么?

石君

5G 5G网络安全 5G安全 网络安全

如果明天没有恐惧——两小时看完余欢水后想到的……

伯薇

个人成长 心理学 小说 恐惧

Windows环境MySql8.0忘记root密码重置

玏佾

MySQL

一个值得推荐的人才测量标准

Selina

dubbo-go 中如何实现路由策略功能

joe

golang Apache 开源 微服务架构 dubbo

如何画一个闹钟

池建强

视觉笔记

媒体的经营 01 | 媒体/内容行业投资分析的维度

邓瑞恒Ryan

创业 内容 重新理解创业 媒体 投资

程序员陪娃看绘本之启示

孙苏勇

生活 程序员人生 读书 成长 陪伴

用python爬虫保存美国农业部网站上的水果图片

遇见

Python GitHub 爬虫

【SpringBoot】为什么我的 CommandLineRunner 不 run ?

遇见

Java Spring Boot

Nginx代理Oracle数据库连接

遇见

MySQL nginx oracle 反向代理

关于HSTS - 强制浏览器使用HTTPS与服务器创建连接

遇见

https 安全 浏览器 TLS 证书

【SpringBoot】给你的 CommandLineRunner 排个序

遇见

Java Spring Boot

【SpringBoot】为什么我的定时任务不执行?

遇见

Java Spring Boot 定时任务 debug

国内10大前端团队网站

有思且行

技术 前端 大前端

给业务线的总经理多交代了几句

泰稳@极客邦科技

创业 效率 团队管理

回"疫"录(1):口罩危机也许是一种进步

小天同学

疫情 回忆录 现实纪录

像经营咖啡店一样扩容 Web 系统

Rayjun

Web 扩容

我敢说 80% 的程序员都掉进了「老鼠赛跑」的陷阱

非著名程序员

读书笔记 程序员 程序人生 提升认知

Fire Fast 再深一层的是什么?

树上

管理 考核 Fire Hire 用人

个人知识管理精进指南

非著名程序员

学习 读书笔记 知识管理 认知提升

像黑客一样思考

Fooying

黑客思维 黑客 安全攻防

复用到何种程度

孙苏勇

Java 程序设计 复用 面向对象 抽象

常用手机软件清单

彭宏豪95

效率工具 App 手机 移动应用

公司大了,人多事杂,如何落地项目制?

树上

项目制 落地 公司管理 业务线 考核

机房运维需要了解东西

Spider man

Idea工程启动时报错:Command line is too long

玏佾

intellij-idea

过滤数组中重复元素,你知道最优方案吗?

麦叔

数据结构 数组 数组去重

太慢是不行的

池建强

创业 产品

死磕Java并发编程(3):volatile关键字不了解的赶紧看看

七哥爱编程

Java Java并发 volatile

编写Vue.js组件前需要知道的10件事-InfoQ