前言
目前公司主站以及老的KMS页面采用的是JQ + ES6, 而新版KMS则是由Vue开发的。
使用Vue开发更加高效,优雅。但是从JQuery转到Vue其实有个过程,我在开发前自认为对Vue还是挺了解的,但是真正动手起来发现还是有一些不适应。因此在此写下一些心得,记录下来。
思维方式差异
JQuery
对于JQ大家肯定都非常熟悉,使用JQ开发,就像把大象装进冰箱:
-
拿到DOM元素
-
封装功能函数
-
操作DOM
这种思维很直观,拿到元素,然后就可以"为所欲为"。但是在页面复杂程度越来越高的情况,许多代码无法复用,代码维护成本高,缺少规范。
JQ组件化
在业务功能,业务场景越变越多的情况下,为了提高开发效率,前端组件化势在必行。于是
前端组件化规范就出现了。基本思想是通过继承来将代码有效组织起来,减少一些重复的劳动,规范了组件的生命周期。
优点:
-
将原来分散的组件有机结合起来,有利于以后业务的扩展
-
提供了完善的继承模式,很容易产出新业务的组件
-
提供了事件机制以及全局标识符
缺点:
-
过多的继承使得组件的依赖越来越多,但是不引入依赖组件又无法使用
-
缺少css样式支持
-
本质上还是函数的封装,并没有从视图层面上进行组件的划分,更接近于js模块化开发
vue有v-model连接数据和视图,而react则通过管理state来重新渲染视图。
JQuery没有中间的过渡层,我们需要花费很大的精力来解决它们之间相互的联系。直接操作DOM时很难写出高效而又优雅的代码,从而使得前端代码满满变得越来越难以维护
Vue
Vue 最显著的特性之一便是不太引人注意的响应式系统(reactivity system)
在开发Vue的时候,并不需要取DOM元素,这个让我别扭了一会,因为我还没有将思维改变过来。总的来说,写vue的过程分为三步:
-
V-视图层(包括HTML,vue指令,其他vue组件等等)
-
M-数据层 (包括从后端拿到的数据以及自己定义的数据)
-
v-model (vue实例)
视图层和数据层其实是没有联系的,所以Vue的核心就在v-model上面,该实例会代理其data属性,并且将视图层和model层联系起来。至此,我们无需再关心视图层面,只需要关心数据的变化即可,因为数据的变化会反应到视图上。 模板语法
Vue组件化
在vue中,一个组件其实就是一个vue实例,而其中的单文件组件,更是一个强大的功能,配合webpack和vue-loader,可以解析后缀名为vue的文件。格式大概如下
<template> html, vue指令, pug... </template> <script> import ... from 'path/to/your-file' export default { data () { return { isLogin:false, } }, methods: { }, watch: { }, computed: { }, created: { } ... } </script> <style lang='scss' scoped> css,scss... </style>
优点:
-
组件既拥有自己的状态,样式,行为,也可以通过在组件外传的props来改变自身状态,复用性和扩展性强
-
完善的模板语法,事件绑定机制以及生命周期,开发效率提升一个层次
-
响应式设计,改变数据的同时,视图跟着改变,不需要再去手动操作DOM。
缺点:
- 使用webpack等打包工具才能发挥最大威力
组件通信
一个页面由许多个组件构成,组件之间可以嵌套,每个组件都有自身的状态,但是有时候需要一个组件的变化反映到另一个组件上,这个时候就需要组件之间的通信了。
-
每个组件都有自己内部的状态,不要从外部直接改变组件内部的状态,例如
-
子组件通过props接收父组件的数据,父组件通过控制props来改变子组件的状态。
-
子组件通过事件来与父组件通信,在子组件内部触发该vue实例(组件)的事件,然后在父组件上监听该事件即可。 vue自定义事件
开始使用Vue吧
设计数据结构
数据的变化会更新DOM,这是Vue迷人的一点,因此好的数据结构非常重要,在写Vue组件之前,不妨按照一下思路来思考一下:
-
组件内部,必要的数据有哪些,能否表示组件的内部状态
-
组件接收外部的数据有哪些,能否从外部使组件发生预期的变化
-
数据精简化,检查是否有冗余的数据
俗话说:磨刀不误砍柴工,设计好数据结构对之后的开发很有益。
计算属性
数据大部分都声明在Vue实例的data的属性中(在组件中data必须是函数,返回一个对象),当时当数据有着逻辑计算时,直接从data中拿数据然后用表达式并不是个好方法。
<div id="example"> {{ message.split('').reverse().join('') }} </div>
上面的代码,在模板内放入了过多的逻辑,对于复杂的逻辑运算应当使用计算属性
data: { return { message: 'Hello,World' } }, computed: { reversedMessage() { return this.message.split('').reverse().join('') } }
计算属性可以当作数据结构的一种,任何复杂的数据运算都声明在计算属性中。
至于为什么不用methods,这里有回答 计算属性 VS methods
构建视图层
设计好数据结构之后,书写视图层显得得心应手,但是前提是了解Vue的模板语法 模板语法 。
我在开发过程中遇到一些坑,都是小问题,但是也不能忽视:
-
在html上绑定属性,一律使用v-bind语法,否则会解析为字符串。
-
不要在子组件中改变props,特别是引用类型,如果有需要请使用计算属性来处理数据。
构建高性能组件
利用slot混合组件
在组件嵌套的时候,为了能更灵活的使用组件,使用slot来混合组件的内容是一种非常好的方式
现在构建一个有头部和尾部的组件,但是中间的内容由使用组件的人来决定(父组件作用域中)。
子组件child
<div> <div id="header"></div> <slot slot="body"></slot> <div id="footer"></div> </div>
父组件
<div> <child> <p slot="body">这是一个段落</p> </child> </div>
父组件中的内容会插入到对应的slot中。最后渲染为
<div> <div id="header"></div> <p>这是一个段落</p> <div id="footer"></div> </div>
当混合组件时,会碰到从子组件取值的情况。当时组件之间作用域是孤立的,之前的组件通信的方式也不适用于混合组件的情况,因此作用域插槽出现了 作用域插槽 。
通过作用域插槽可以将子组件中的数据通过插槽传到父组件中,然后父组件通过scope取到数据,根据数据插入需要的模板。
编写可复用的组件
Vue组件的API主要三部分
-
Props 允许外部环境传递数据给组件
-
Events 允许从外部环境在组件内触发副作用
-
Slots 允许外部环境将额外的内容组合在组件中。
基础架构优化
-
html模板要简介明了,不适合放入过多逻辑操作,需要运算的时候使用computed
-
构建中大型项目,组件尽量拆分细化,一个组件做好一件事情
-
Vue是单向数据流,使用vuex等工具来管理组件状态,是一个好的选择
以上是我的一些小总结,文章以后随着知识的增长也会反复更新,有误之处欢迎指正。
注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。