学习在Vue中使用无状态组件
时间:2023-03-30 16:08:42
CSS
作者:MilosProtic译者:前端小智来源:medium点赞再看,养成习惯本文已收录到GitHubhttps://github.com/qq44924588...更多分类往期好评文章,也整理了很多我的文档和教程资料。欢迎来到星和完美。面试时可参考考点复习。我希望我们能在一起。什么是应用程序状态,我们为什么需要它?在较小的项目中通常不需要状态管理,但是当涉及到较大的范围时,例如企业级应用程序,它们中的大多数都需要它。简单的说,state就是一个包含了应用程序使用的最新值的对象。然而,如果我们从结构化的、更抽象的角度来看它,就会发现状态是复杂应用程序中的重要组成部分,它可以实现干净的架构和强大的关注点分离。通常,缺乏经验的开发人员无法预测状态管理的必要性以及它将如何实施,从而难以理解状态管理的重要性。如果基于状态的组件堆积如山,它们之间的数据管理和共享将成为一场噩梦。您拥有的基于状态的组件越多,从长远来看,出现的问题就越多。如果您不使用外部包进行状态管理,最好使用尽可能少的基于状态的组件,并为您的组件提供围绕它们构建的状态。Vue与无状态(函数)组件Vue中的无状态组件其实就是函数组件。但什么是功能组件?要回答这个问题,首先要了解什么是函数式编程。与将程序分解为对象的面向对象方法不同,函数式编程鼓励将程序分解为用于形成更高级别程序的小函数。我们创建的函数不依赖于或可以改变任何外部状态,这导致了另一个观察结果,即对于给定的输入,它们总是返回相同的输出。因此,函数组件是没有状态的组件,是可以改变的。函数组件的输出总是基于给定的输入。在Vue方面,这些组件根据给定的props给出不同的输出。语法Vue提供了一种简单的方法来定义功能组件。我们只需要给出一个功能关键字。在2.5.0及以上版本,如果使用单文件组件,基于模板的函数式组件可以这样声明:function/statelesscomponent
或者exportdefault{functional:true,props:{//...},render(createElement,context){returncreateElement('div','function/statelesscomponent')}}注意:在2.3.0之前的版本中,如果一个功能组件想要领取道具,需要道具选项。在2.3.0及以上版本中,可以省略props选项,组件上的所有属性都会自动隐式解析为props。使用功能组件时,引用将是HTMLElement,因为它们是无状态且无实例的。请注意,传递给函数组件的唯一数据是props。这些组件是完全无状态的(没有响应数据),它们会忽略传递给它们的任何状态,并且不会触发任何生命周期方法(创建、挂载等)。此外,我们无法使用this关键字访问实例,因为这些组件也未实例化。相反,组件需要的一切都是通过上下文提供的。在渲染函数中,它作为createElement方法的第二个参数传递。组件需要的一切都通过上下文参数传递,它是一个具有以下字段的对象:props:一个提供所有props的对象children:一个VNode子节点数组slots:一个返回包含所有插槽的对象的函数scopedSlots:(2.6.0+)公开传入作用域插槽的对象。还将普通插槽公开为函数。data:传递给组件的整个数据对象,作为createElement的第二个参数传入组件parent:父组件的引用listeners:(2.3.0+)包含父注册的所有事件监听器的列表当前组件对象的组件。这是data.on的别名。injections:(2.3.0+)如果使用了inject选项,这个对象包含应该被注入的属性。为什么我们需要无状态组件到目前为止,我们已经了解到功能组件是无状态的,在它们的核心,它们只是接受一些输入并根据它提供输出的可执行函数。就它们的使用而言,由于功能组件只是功能,因此渲染开销要低得多,这也意味着它们非常高效并且不会花费太长时间来渲染。另外,考虑高阶组件,它们不需要任何状态,它们所要做的就是用额外的逻辑或样式包装给定的子组件。接下来,一般示例显示何时使用功能组件,这些组件非常适合此类任务。示例在此示例中,我们创建了一个面板组件,它充当包装器并提供所需的样式。子组件将在面板主体中呈现:constheader=createElement('header',{attrs:{class:'panel-header'}},context.props.title);constbody=createElement('main',{attrs:{class:'panel-body'}},slots.default);returncreateElement('section',{attrs:{class:'panel'}},[header,body]);}}如上所述,这个组件的唯一目的是提供一个类似面板(卡片)的样式,它有header和main元素,分别保存面板标题和HTML内容。整个过程是通过使用渲染函数中的createElement参数完成的。createElement是Vue核心中实现的VirtualDom系统的一部分。VirtualDOMVue创建一个虚拟DOM来跟踪它想要如何更改真实DOM。请仔细看这行代码:returncreateElement('h1',this.blogTitle)createElement到底会返回什么?实际上不是实际的DOM元素。它更准确的名字可能是createNodeDescription,因为它包含的信息会告诉Vue需要在页面上渲染什么样的节点,包括它的子节点的描述信息。我们将这样的节点描述为“虚拟节点(virtualnode)”,通常简称为“VNode”。“VirtualDOM”就是我们所说的从Vue组件树构建的整个VNode树。createElement参数接下来您需要熟悉的是如何在createElement函数中使用模板中的那些函数。以下是createElement接受的参数://@returns{VNode}createElement(//{String|Object|Function}//HTML标签名称、组件选项对象或//解析上述任何内容的异步函数。Required.'div',//{Object}//模板中属性对应的数据对象Optional.{//(详见下一节)},//{String|Array}//subLevelvirtualnodes(VNodes),由`createElement()`构造,//字符串也可以用来生成“文本虚拟节点”。可选。['先写一些文字',createElement('h1','aheadline'),createElement(MyComponent,{props:{someProp:'foobar'}})])面板的CSS样式如下:.panel{margin-bottom:.5rem}.panel,.panel-header{border:1pxsolid#d3d3d3;border-radius:4px;}.panel-header,.panel-body,.panel{padding:.5rem;}.panel-header{background-color:#efefef;color:#eeeee}这是一个简单明了的CSS,提供了一些填充和颜色。子组件现在,为了使示例更生动,让我们创建两个额外的组件,一个显示汽车列表,另一个只是一个简单的lorem-ipsum文本组件,要求它们具有相同的面板样式和外观。列表组件:exportdefault{name:'cars',props:{data:Array}}template:文本组件:exportdefault{name:'lorem-ipsum'}template:终身学习者,终身学习者,终身学习者,终身学习者,终身学习者
现在,有了可用的子组件,我们需要做的就是使用面板组件将它们包装到我们的应用程序中,如下所示:
请注意,使用这些组件是因为示例很简单。实际上,它可以是任何类型的组件。完整代码hmtl
<脚本类型="text/x-template"id="lorem-ipsum">
前端小智,终身学习者,终身学习者,终身学习者,终身学习者,终身学习者
cssbody{填充:.5rem}*{填充:0;保证金:0;box-sizing:border-box;}.??panel{margin-bottom:.5rem}.panel,.panel-header{border:1pxsolid#d3d3d3;border-radius:4px;}.panel-header,.panel-body,.panel{padding:.5rem;}.panel-header{background-color:#efefef;颜色:#eeeee}ul{列表样式:无;}ul>li{padding:.5rem.2rem}js//包装面板constpanel={functional:true,name:"panel",props:{title:String},render(createElement,context){constslots=context.slots();constheader=createElement('header',{attrs:{class:'panel-header'}},context.props.title);constbody=createElement('main',{attrs:{class:'panel-body'}},slots.default);returncreateElement('section',{attrs:{class:'panel'}},[header,body]);}}//示例组件constcars={name:'cars',template:'#cars',props:{data:Array}}constloremIpsum={name:'lorem-ipsum',template:'#lorem-ipsum'}newVue({el:'.vue-app',components:{panel,cars,'lorem-ipsum':loremIpsum}});运行效果:无法实时获知代码部署后可能出现的bug。之后为了解决这些bug,很多时间都花在了日志调试上。这里顺便推荐一个好用的BUG监控工具Fundebug原文:https://itnext.io/whats-the-d...每周更新交流文章。可以微信搜索“大千世界”立即阅读更新(比博文早一两篇),本文已收录到GitHubhttps://github.com/qq449245884/xiaozhi,本人整理我的很多文件。欢迎加星和改进。可以参考考点面试。也关注公众号,后台回复福利就能看到福利,你懂的。