elementui布局嵌套-前端工程实践

设置回调函数

使用OPEN方法与服务器建立连接

发送数据到服务器

在回调函数中处理不同的响应状态

这5个步骤。 那么Ajax最关键的作用就是让页面有局部刷新的功能,避免每次后台请求都刷新页面的糟糕体验,同时也让后端页面可以通过组合复杂的页面数据逻辑js.

随着Ajax技术的日益普及,很多基于该技术为核心功能的后端js框架也诞生了。 基本上,这些框架实际上分为两大类:

当然,看起来jquery的统治力远低于其他框架,并且已经统治了后端领域很多年。 当然,在这个过程中,有过adobe flex的麻烦,也有微软microsoft silverLight的试水,但在软件开发的最终领域,我个人的理解是,免费小于收费,开源小于产品。 直到移动浪潮来临,jquery对移动终端的支持以及移动终端体验的保障才逐渐显现出来。 虽然jquerymobile也推出了,但是对于响应式布局的支持确实还不够。 随后出现了Bootstrap等支持两端的新框架,但真正的新变化来自于移动端的发展。

3 三大前端框架及node的出现

2015年之后,移动开发逐渐成为整个互联网开发的核心。 随着整体开发工作领域的细分,前端工作变得越来越重要。

您听说过三大新一代后端框架吗? 什么,不?那你就out了

目前,三大主流后端框架是React、Vue、Angular。

那么既然我们已经有了jquery,为什么还需要一个新的框架呢?

根本的诱因可以说是以上两个数字。 我们的后端开发思路已经从上图的MVC模型转变为右图的MVVM模型。

什么是 MVVM 模式? MVVM最先由Google提出。 它借鉴了桌面应用程序的MVC思想。 在后端页面中,Model由纯JavaScript对象表示,View负责显示。 两者最大程度地分开。 也就是我们常说的,这里真正实现了前后分离。 因此,分离前后,首先要做的就是后端的自我分离。

有什么区别吗?

它采用单向绑定(数据绑定):View中的更改会自动反映到ViewModel中,反之亦然,模型数据的更改也手动显示在页面上。 将 Model 和 View 关联起来的就是 ViewModel。 ViewModel 负责将 Model 数据同步到 View 进行显示,同时还负责将 View 的更改同步回 Model。

上面我们提到的三大后端框架都是MVVM的实现。刚接触后端行业的朋友应该很好掌握这个框架。

最后说一下我觉得走得最远的,那就必须是node.js了。 Node是第一个将js的手伸到服务器端的框架。

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。

Node.js 使用波浪驱动、非阻塞 I/O 模型,使其轻量且高效。

Node.js 可以将后端工程师变成全栈工程师

我们将在后续章节中介绍节点的其他细节。

规格

说完了后端开发的介绍,下面开始我们的重点内容,前端工程化实践。

工欲善其事,必先利其器。 在编码之前,规范是第一位的。

1.风格恢复

页面的还原,尤其是移动端,不同屏幕规格下如何适配,我们的原则是基准模型下100%还原,其他模型做相对栏目适配(pc端,根据px值设计稿的相应恢复)。

有的朋友,当被问到如何适配移动端时,大多数人都能用rem来回答。 如果再仔细问,也说不出来一二。 我在这里解释一下。 rem是html根目录的字体大小,比如html标签的字体大小如果是100px,那么1rem==100px,当前页面下所有与rem相关的宽度都与这个关系有关。 说到适配,通过获取屏幕的长度,然后按比例动态设置html的font-size,此时rem就适配了,对应的样式也适配了。 代码如下:

/** * rem 动态设置函数 * @param {*} pxToRem 设置px转换rem 比例,默认100 * @param {*} baseWidth 设置基准设计稿宽, 默认750px 基准机型iPhone6/7/8 * @returns */function htmlSizeCalculation(pxToRem, baseWidth) {  pxToRem = pxToRem || 100;  baseWidth = baseWidth || 750;  // 获取根节点元素  var docEl = document.documentElement;  // 屏幕变化监听event  var resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';  // 核心方法,计算关系,并赋值根节点font size  var recalc = function () {      // 获取当前设备屏幕宽      var clientWidth = docEl.clientWidth;      if (!clientWidth) return;      // 根据当前设备屏幕宽,计算相应的根节点字体大小      docEl.style.fontSize = pxToRem * (clientWidth / baseWidth) + 'px';    };  recalc();  if (!document.addEventListener) return;  // 屏幕变化,重新计算  window.addEventListener(resizeEvt, recalc, false);  // 文档加载后,执行计算  document.addEventListener('DOMContentLoaded', recalc, false);}

2.内容逻辑还原

严格按照需求文档进行逻辑恢复。 按需求行事elementui布局嵌套,原本没什么可指出的,但在工作中,我发现有的伙伴喜欢自己添加,自己在页面上加文字,甚至交付的产品与最终的完全不一样需要。 这些问题已经到了测试阶段,将被视为bug。 当然,也可能是需求文档本身的疏忽造成的。 如有发现,需及时与需求人员沟通调整。

以上,无论是风格层面还是逻辑层面,我们坚持的原则可以用一句话来概括,尊重上游环节和专业人士的工作。

3. 命名约定

注意见名知意,通常认同英文语义命名。 多短语可以采用中横线、小驼峰、大驼峰等格式,这个可以根据团队的习惯约定。 语义命名保证了代码的可读性。 笔者在工作中发现,有的伙伴命名变量,并不满意。 有的甚至颠倒命名,逻辑混乱,造成不可维护、项目移交困难等一系列问题。

例子:

水平线风格中的某个名称

变量/方法驼峰式命名法 someName

图片名称下划线some_name.png

常量全部小写逗号 SOME_NAME

组件名称 驼峰式命名法 SomeName

4. 代码检查

代码检查,通过一定的工具检查项目代码是否编写规范、冗余等,提示开发人员相应代码行位置存在的错误和警告,以便纠正; 友好的可读性和可维护性。 其次,可以加强代码质量,规避潜在风险。 工具有很多,eslint是比较常用的。 我们通常选择其标准规格并稍加改动。 团队也可以根据内部习惯来使用。 选择正确的工具。 各种IDE也都有一些相关的底层工具,方便开发者进行标准的底层代码编写。 如果一些团队成员没有意识到这一点,可以在提交分支时使用git hook检查代码,如果有错误就阻止提交。

eslint 可以在 package.json、.eslintrc 和 webpack 中配置。 详情请参考官网#cliengine。 以下是webpack.config.js中eslint的配置示例。

{        test: /.js$/,        exclude: /node_modules/,        loader: 'eslint-loader',        options: {          // community formatter          formatter: require('eslint-friendly-formatter'),          // This option will enable ESLint autofix feature.          fix: true,          // This option will enable caching of the linting results into a file.          cache: true,        },      },

5. 分支机构规格

约定分支的意义在于保证关键节点的快速响应、生产的稳定性、开发的灵活性; 我们选择git进行版本控制。 从分支规格来看,master是稳定生产版本,develop是主开发分支,feature/xxxx功能模块分支,hotfix紧急补丁分支。

master分支是从其他分支合并而来,并存储用于生产部署的稳定代码。 每次合并都是一个版本更改并且可以被标记。

开发分支存储开发的阶段性结果,并从 feta 分支合并。 它是一个代码源,可以提供测试部署、手动测试部署或自动化测试的代码。

功能分支是开发特定功能块的分支。 敏捷开发常用于项目开发。 敏捷开发中的用户故事被拆分为多个1-2天的功能模块并分配给开发人员。 开发者可以在本地基于develop构建模块分支feature/xxxx以供使用。 本地development完成后,会合并到develop中。 合并后,可以删除feature分支。

hotfix分支针对生产版本遇到异常或者严重问题需要及时修复的场景。 这时就应该在master分支的基础上建立hotfix/xxxx分支来修正生产bug,同时又不影响develop分支的其他迭代开发工作。 修复后如果hotfix分支被验证正确,会及时合并到master并打上标签,及时发布版本。 同时会合并到develop中,保证后续迭代的正常开发。 合并后,可以删除hotfix分支。

模块化的

模块化是将大的功能块分割成小的可维护的单元块,以便分区和重用。 它是快速开发和维护小型复杂应用程序的必要基础。

CSS预处理的变量机制、嵌套关系等句型促进了CSS样式编写的清晰性和便捷性,为样式模块化提供了基础。 另外,webpack配置CSS-loader来统一添加哈希属性,利用属性选择器的特性。 ,避免全局样式污染,实现模块化。 共享样式和属性值被提取到全局模块,并引入其他相应模块并使用。 全局模块在主题切换方面非常高效。

// webpack.config.js{  test: /.css$/,  use: [    {      loader: 'css-loader',      options: {        modules: true,        localIdentName: '[path][name]__[local]--[hash:base64:5]'      }    }  ]}

市面上优秀的css预处理有less、sass、stylus等,各有各的优缺点,选择适合自己团队的就可以了。

js模块化,目前常用的有commonjs规范和es6模块,nodejs模块API基于commonjs范式制定,用于node包管理,例如modules.export = somePackage / require('somePackage'); es6是ECMA2015版本规定的模块机制,可以通过export/import导出和导入模块。

节点模块

// log.jsmodule.exports = function (mes) {  console.log(mes)}
// print.jsconst log = require('./log.js')log('hello world')

节点模块按照来源分为两类,一类是外部模块,一类是自定义模块。

内置模块是node API涉及到的模块,由官方提供,如文件系统fs、协议http/https、path路径等。自定义模块,非官方出品,来自社区或私人开发自用。 通常开源模块也会发布到 npm。 开发者可以通过npm install(npm install xxxx)下载并安装它们。

节点模块按照功能分为两类,一类是开发依赖模块,一类是线上生产依赖模块。

开发过程中使用开发依赖模块,以提高开发效率和友好性(例如实时更新页面代码变化的热加载模块、dev运行时美化shell输出文本的chalk模块等),以及安装时添加参数。 --save-dev,记录在package.json的devdependency下; 生产依赖是在线运行时依赖的模块(例如日期低格式模块、px2rem转换模块等)。 安装时还要加上参数--save。 ,记录在package.json中的dependency下。

通过require引入模块有一定的机制。 如果是直接名字,如require('path'),首先检查是否已经cash缓存,即缓存优先级最高(require参数不同,但索引的资源是如果是相同则视为相同进入缓存)。 如果不是,则判断是否为外部模块。 如果没有,则会在项目的node_modules文件夹中查找; 如果是路径索引,则为绝对路径“/”或相对路径“./”“../”,例如require('./a'); 然后根据路径位置搜索对应的模块,如果文件没有指定格式,nodejs会尝试加载a.js、a.json、a.node,如果以上都不存在的话,则索引按照a文件夹的顺序,其下的package.json(主数组配置的文件)、index.js、index.json、index.node。

ES6模块

// 2. es6 module// log.jsexport default function (mes) {  console.log(mes)}
// print.jsimport print from './log.js'print('hello world')

导出句型规定是向外界导出,必须与内部变量建立一一对应关系。 如果只有一个模块导出,可以使用export default导入一个没有名称的变量,同时export也可以暴露多个导出,但它们不能出现在块级作用域中,否则会出错。

// export.js// 报错export 9
// 报错var num = 9export num
// 正例一export var num = 9
//正例二var age = 15export { age }
//正例三 通过as关键词 重命名对外出口var color = 'red'export {color as pigment }
// 正例四 default export default function sayHello () {  console.log('hello')}

import 导入一个包,语法与export 一致,可以导入整个包,也可以导入部分包。 对于导入可自定义名称的默认表单,导入后的 from 指定文件位置。 用法与require类似。 示例代码如下:

// import.js// 引入的对象可以结构, 对应变量为import 里定义的变量名// from的文件格式后缀可省了import { num } from './export.js' 
// 重命名引入import { age as year } from './export.js'
// 整体引入import * as obj from './export.js'
// default 引入import anyName from './export.js'

JS模块化,无论是公共模式还是业务逻辑,都是分而治之。 为了方便开发和后期维护,也解决了全局变量污染、开发混乱的情况。 这对于小型工程项目的开发尤为重要。

组件化

对于一个应用来说,单一的样式和js模块化是不够的。 需要根据UI用户交互级别来定义和分离细粒度的组件。 据说一个页面中的不同块被划分为不同的组件,其中应该包含该组件样式和逻辑数据层块。 组件相对独立,组件可以自由组合。 页面是组件的容器,可以快速响应不同业务需求下的组合。 理论上,划分的组成部分之间不存在时间顺序依赖,可以保证同步发展,分工无障碍地扩大和扩大,提高生产率。

组件统一放置在组件下面,如下图所示。 每个组件的风格、标签内容、逻辑分类都在一起,内聚性高,功能清晰,目录清晰,让可靠的组件自然可复用。

header.html

header
 

header.css

.header{    background: black,    color: red}

header.js

const title = document.querySelector('.title')title.innerHTML = 'newTitle'

在开发中elementui布局嵌套,组件通常不会直接按照上述原生形式编写。 在目前基于框架的开发方式下,每个框架都有很好的工程组件实现。 比如一个vue组件,创建组件的文件,template标签中的dom节点,脚本中的js数据和逻辑,style中的样式,通过props定义组件被父级调用时的属性,并通过emit将数据从组件传输到父组件。

标题组件vue示例:

  
{{title}} {{color}}

export default { data() { title: 'title' }, props: { color: { default: 'red', type: String } }}
.header{ background: #f0f }

市面上各大厂商开源了很多基于主流框架的优秀UI组件库,比如基于vue的element-ui、muse-ui,基于react的ant-design、material-ui等。详细文档,请到相应的官方网站查看。

编译构建

前端工程关注的是如何提高开发效率,最终的发布取决于宿主环境浏览器。 目前主流浏览器都可以支持html5、css3、es5以及少数es6句型。 css预处理器、原生es6+、js框架、模块机制等需要一步编译创建,将开发者友好的语言翻译成浏览器可以识别的资源。 目前市场上使用最多的是webpack。

本质上,webpack 是现代 JavaScript 应用程序的静态模块捆绑器。 当 webpack 处理应用程序时,它会递归地构建一个依赖图,其中包含应用程序所需的每个模块,然后将所有这些模块打包到一个或多个包中

从webpackv4.0.0开始,无需配置即可编译打包。 默认入口文件为src/index.js,打包后的文件为dist/main.js。 当然,webpack 仍然是高度可配置的。

Webpack有四个核心配置项,entry、output、loader、plugin。 Webpack就像上图中的盒子一样。 通过entry入口文件输入资源,盒子经过loader和plugin,然后输出资源。 入口和出口比较好理解,我们来说说loader和plugin。

loader用于将各种类型的资源转换成webpack可以理解的模块。 加载器的配置主要有两个点,测试和使用。 测试正则匹配文件类型,use配置要使用的对应loader。 当链接多个加载器时,请记住它们将以相反的顺序执行。 根据字段书写格式,从右到左或从下到下执行。

// webpack.config.jsconst path = require('path');
const config = {  entry: 'index.js', output: { filename: 'bundle.js' }, module: { rules: [      { test: /.less$/, use: ['style-loader', 'css-loader', 'less-loader'] }       ] }};
module.exports = config;

这是告诉webpack遇到.less文件类型的资源对应的require()/import时,使用less-loader将less文件转换为css文件,并使用css-loader解析css文件。 url()”会导入相应的样式资源,最后style-loader会生成一个包含最终解析的css代码的样式标签,并将其附加到head标签中。

加载器处理具体文件的转换,而插件可以处理更广泛的任务,比如打包优化、代码压缩、打包后的js自动插入到模板html中、环境变量定义等。插件的使用方式是通过require、实例化并加载到插件链表中。

const HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装const config = {  plugins: [    new HtmlWebpackPlugin({template: './src/index.html'})  ]};
module.exports = config;

在webpack配置中使用插件简单明了,大部分都可以直接通过文档进行配置和使用。

自动化

我们来谈谈提高效率。 编译完成后,我们就得到了浏览器可以识别的代码。 后续工作能否拉近与用户的距离? 答案是肯定的,比如切换测试生产环境,测试、部署等方面,以自动化为方向。 ,在越来越多的项目中解放人力。

通过npm run build命令,先设置env,然后build。 代码中使用env来导引逻辑,以处理不同环境下的代码走向。

// 命令行cross-env NODE_ENV=production webpack --config build/webpack.config.js
// 逻辑代码块const  env = process.env.envif (env === 'production') {  // doSomething in production} else {  // doSomething in test}

环境变量设置不同,因为操作系统不传递它们。 这里建议使用cross-env,以避免在不同操作系统中来回切换命令的麻烦。

常用的有单元测试和初步测试。

单元测试是直接测试一个代码单元,可以是模块或函数。 常用的工具是mocha。

验收测试是通过脚本控制浏览器触发Web程序的功能来测试界面和功能是否完好。 目前,公司内部测试团队已经开始这方面的工作。

如果有多个生产服务器,手动上传代码会效率低下且容易出错。 要将重复的任务交给机器并自动化部署,可以使用 Jenkins,它是开源 CI&CD 软件的领导者,提供超过 1000 个插件来支持创建、部署和自动化,以满足任何项目的需求。

总结:产品稳定高效的交付才是后端工程的意义。 前端发展了这么多年,从最初的原始荒野一步一步发展到现在的高度工具化的生产线链条。 它不断创新,以满足日益下降的流动性。 应用场景和多维度客户更高​​的体验需求。

关于导师

讲师直通车

袁森是泰康集团数据信息中心、中国联通互联网部的高级后端工程师。 从事后端领域多年。 基础扎实,无论是在H5、CSS、JS三大框架,还是陌陌小程序weex,还是node等领域都有深入的研究。更重要的是,人长得帅

科技鱼系列