什么是 Vue.js
Vue(发音为 /vjuː/,类似于 view)是一个用于构建用户界面的渐进式框架。
如果您已经是一位经验丰富的后端开发人员,并且想了解 Vue 与其他库/框架有何不同,请查看比较其他框架。 ,官网有详细的介绍,我就不过多赘述了。
从维护视图到维护数据,Vue.js 使我们能够快速开发应用程序。 但随着业务代码越来越大,组件越来越多,组件逻辑耦合严重,代码维护变得非常困难。
同时Vue.js的接口和句型都非常自由,有多种技术可以实现同样的功能。 每个人解决问题的思路不同,写出来的代码也不同,团队内部缺乏标准。
本文致力于从组件开发的不同方面列出合理的解决方案,作为构建组件规范的参考。
导航
成分
组件是具有一定功能的模块,不同组件的功能相对独立。 组件可以是按钮、输入框、视频播放器等。
组件可复用,高内聚,低耦合。
那么,什么构成了组件。 以浏览器原生组件视频为例,我们来分析一下组件的组成部分。
从示例中可以看出,组件由状态、事件和嵌套片段组成。 State是组件当前的单个数据或属性,例如视频中的src、宽度和高度。 Storm是组件在特定时间触发某些操作的行为。 例如,当视频资源加载或失败时,会触发相应的风暴进行处理。 Fragment是指嵌套在组件标签中的内容,在一定条件下会被解释,比如当浏览器不支持video标签时显示提示信息。
在 Vue 组件中,状态称为 props,事件称为 events,片段称为 slot。 组件的组件也可以理解为组件的外部插座。 一个好的可重用组件应该定义一个清晰的暴露套接字。
使用vue扩展视频组件,构造一个支持播放列表的组件myVideo:
myVideo组件有一个clear socket,接收播放列表的状态、播放器宽高等,触发加载成功或失败,播放上一个或下一个暴风雨,并且可以自定义结尾的结束页面播放,可用于插入广告或显示下一个视频信息。
组件之间的通信
在Vue.js中,父子组件之间的关系可以概括为propsdown、eventsup。 父组件通过 props 向上传递数据给子组件,子组件通过事件向父组件发送消息。 看看他们是如何工作的。
生意无关
姓名
组件的命名应该与业务无关。 组件应根据其功能命名。
例如,一个列表显示公司部门,每个项目作为一个组件,并命名为DepartmentItem。 这时有一个需求,以和刚才部门列表相同的风格显示团队成员列表。 事实上,DepartmentItem 这个名称并不合适。
为此,可复用组件的命名应避免与业务相关,以组件的角色和功能来命名。 项目、列表项目、单元格。 可以参考Bootstrap、ElementUI等一些UI框架的命名。
业务数据不相关
可复用组件只负责UI上的显示以及一些交互和动画。 如何获取数据与之无关,因此不要在组件内部获取数据,以及任何与服务器打交道的操作。 可重用组件仅实现UI相关的功能。
组件职责
约束组件的职责可以让组件更好地前馈,知道哪些功能是组件实现的,哪些功能不需要实现。
组件可以分为通用组件(可复用组件)和业务组件(一次性组件)。
可复用的组件实现常用功能(不会因组件使用的地点和场景而改变):
业务组件实现面向业务的功能:
可复用的组件应该尽量减少对外部条件的依赖,所有与vuex相关的操作都不应该出现在可复用的组件中。
组件应该避免对其父组件的依赖,并且不要使用 this.$parent 来操作父组件。 父组件不应该通过this.$children引用子组件的实例,而是通过子组件的socket与其交互。
命名空间
可重用的组件不仅需要定义一个明确的公共套接字,还需要一个命名空间。 命名空间可防止与浏览器保留的标记和其他组件发生冲突。 特别是当项目引用外部UI组件或者组件迁移到其他项目时,命名空间可以防止很多命名冲突。
...
业务组件还可以有命令空间,这一点与一般组件不同。 这里st(section)用来表示业务组件。
上下文无关
还是那句话,可复用的组件应该尽量减少对外部条件的依赖。 在没有特殊要求且单个组件不太重的前提下,不要将一个具有独立功能的组件拆分成几个小组件。
TableHeader组件和TableBody组件依赖于当前上下文,即TableWrapper组件的嵌套环境。 您可以有更好的解决方案:
上下文无关原则会提高组件使用门槛。
数据扁平化
定义组件套接字时,尽量不要将整个对象作为 prop 传入。
每个 prop 应该是简单的数据类型。 这样做有以下好处:
Flat props 可以让我们更直观地理解组件套接字。
使用自定义storm实现数据的单向绑定
有时,对于一个状态,需要从组件内部和外部来改变它。
例如,要显示和隐藏模态框,父组件可以初始化模态框的显示,模态框组件内部的关闭按钮可以将其隐藏。 一个好的方法是使用自定义storm来更改父组件中的值:
export default { props: { show: String }, methods: { close () { this.$emit('input', false) } } }
当用户单击关闭按钮时,Modal 组件会向父组件发送输入自定义风暴。 当父组件监听输入的storm时,设置show为storm反弹的第一个参数。
特别是,当状态名称为value且输入storm名称时,可以使用v-model指令语法糖:
相当于
为了使组件的 v 模型发挥作用,它必须:
注意:由于每个组件的输入storm只能用于一个数据的单向绑定,当有多个数据需要向下同步时,请不要使用v-model,请使用多个自定义storm,并同步父组件中的新值。
使用自定义观察者优化 DOM 操作
在开发中elementui组件重写,有些逻辑很难使用数据绑定,很难避免需要对DOM进行操作。 例如视频播放需要同步Video对象的播放操作和组件中的播放状态。 您可以使用自定义观察器来优化 DOM 操作。
export default { props: { src: String // 播放地址 }, data () { return { playing: false // 是否正在播放 } }, watch: { // 播放状态变化时,执行对应操作 playing (val) { let video = this.$refs.video if (val) { video.play(); } else { video.pause(); } } }, method: { // 切换播放状态 togglePlay () { this.playing = !this.playing } } }
在示例中,当自定义观察者检测到播放状态的变化时,它将执行播放或暂停操作。 遇到视频播放状态的处理时,只需要关注播放状态即可。
项目骨架
单个组件并不太重。 组件在功能独立的前提下应尽可能简单。 组件越简单,复用性越强。 当你实现组件的代码时elementui组件重写,不包括CSS,有数百行(大小取决于业务),所以你应该考虑将其拆分为更小的组件。
当组件足够简单的时候,我们就可以自由地将这些组件组合成一个更大的业务组件来实现我们的业务功能。 因此,理想情况下,元件的参考电平只有两级。 业务组件是指通用组件。
我们可以得到一个扁平化的结构。
在一个庞大的项目中,组件之间的引用关系会更加复杂。 当单页面应用有多个路由,且每个路由组件过重时,就需要对模块进行拆分。 组件结构将如右图所示。
按照这个思路构建我们的项目,最终的源码目录结构(不含创建过程文件):
│ App.vue # 顶级组件 │ client-entry.js # 前端入口文件 │ config.js # 配置文件 │ main.js # 主入口文件 │ ├─api # 接口 API ├─assets # 静态资源 ├─components # 通用组件 ├─directives # 自定义指令 ├─mock # Mock 数据 ├─plugins # 自定义插件 ├─router # 路由配置 ├─sections # 业务组件 ├─store # Vuex Store ├─utils # 工具模块 └─views # 路由页面组件
常见组件中还可以区分容器组件、布局组件和其他功能组件。
学习从来都不是一个人的事情,一定要有一个互相监督的伙伴,想要学习或者交流后端问题的男伙伴可以私信“学习”小明获取网页后端的介绍资料,学习一起,一起成长!
发表评论