本文汇总整理了自己用到的一些基础css,可用作基础的base.css引用到项目中
前端技术汇总
由于前端相对后端框架、插件库更加的多样化,以及不同项目ui设计稿的多样性,定制化开发的各种需求,前端项目很难做到都是用统一的框架,所以此文档更多的是对以后项目进行总结已供参考。
本文档主要作用:
- 整理目前技术中心前端项目中所用的技术
- 目前前端项目中所用到的第三方插件库汇总
- 通过此文档对现有前端项目进行一个初步了解
- 对以后前端项目选型的参考
[TOC]
##一、项目概览
此文档将项目分类成为 门户类 和 后管类 。
1. 门户类
门户类项目中门户网站的排版非常重要。信息的呈现方式以及门户页面的样式不同不仅会影响到信息的浏览量,也会影响到用户体验。
目前的门户类项目大致如下:
- 信用江苏 http://www.jscredit.gov.cn/
- 淄川可视化 待补充地址
- 长春新区统一门户 http://39.104.101.87:8080/cc_portal
- 广州公租房(诚壹宜居pc 公众号)https://www.c1yj.com/
2. 后管类
后台管理系统最大的作用就是对用户业务的支撑,大多数以表格、图标为主。界面样式大多不会复杂,要求统一、简洁。
目前的后管项目大致如下:
- pass后台管理系统
- 长春新区门户后台管理系统
- 待补充
##二、技术概览
1. 门户类
门户类前端的技术栈现基于es5、jQuery、template.js、axios、flex、rem、bootstrap、layui等,部分前后端未分离的项目使用了freemarker模板。你的本地环境需要视项目情况安装node或者tomcat,以及对应的版本控制工具。
1.1、可视化大屏门户:
该门户大多需要兼容大屏以及响应式。
1.2、政府类、企业类、个人门户:
技术栈基于html+css+js,数据渲染使用了jquery、template.js、freemarker,前端请求使用ajax或者axios库,布局使用bootstrap-ui以及layui弹窗提示。
1.3、公众号
公众号主要采取rem的方式进行适配,css布局中也会使用到flex布局,以及WEUI的插件使用。其中数据交互以及逻辑代码为js原生或者jquery。
rem适配:
function rem() {
var psd_width = 设计稿宽度,
win_width = document.documentElement.clientWidth,
viewport = document.querySelector('meta[name="viewport"]'),
dpr = window.devicePixelRatio || 1,
scale = 1 / dpr,
rem;
var style = document.createElement('style');
rem = win_width / psd_width * 100;
style.innerHTML = "html{font-size:" + rem + "px!important;}";
document.querySelector("head").appendChild(style);
}
2. 后管类
后管平台现在大多是基于vue-cli,去进行二次开发。你的本地环境需要安装 node 和 git。我们的技术栈基于 ES2015+、vue、vuex、vue-router 以及 element-ui,bootstrap,layui,echarts,所有的请求数据都使用Mock.js模拟,axios进行接口交互,提前了解和学习这些知识会对使用本项目有很大的帮助。
##三、插件总结
这里列出一些使用过的插件,当然如果你有更多更方便的插件请你继续使用。
1.1、布局:
1.1.1、flex布局
多用于大屏以及移动端布局,是一种自适应的弹性布局。Flex 是 Flexible Box 的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。
任何一个容器都可以指定为 Flex 布局。
.box{display: flex;}
行内元素也可以使用 Flex 布局。
.box{display: inline-flex;}
Webkit 内核的浏览器,必须加上-webkit前缀。
.box{
display: -webkit-flex; /* Safari */
display: flex;
}
注意,设为 Flex 布局以后,子元素的float、clear和vertical-align属性将失效。
flex容器的6个属性:
- flex-direction 属性决定主轴的方向(即项目的排列方向)
- flex-wrap flex-wrap属性定义,如果一条轴线排不下,如何换行
- flex-flow flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。
- justify-content 属性定义了项目在主轴上的对齐方式
- align-items 属性定义项目在交叉轴上如何对齐。
- align-content 属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
flex布局详细用法 Flex 布局教程:语法篇
1.1.2、栅格布局
项目中多使用bootstrap-ui,element-ui自带的栅格布局,也能满足响应式以及自适应的布局需求。
- bootstrap栅格布局 bootstrap栅格系统
- element栅格布局 element栅格系统
1.2、表格:
1.2.1、element表格
1.2.2、原生表格
1.3、时间选择器:
1.4、弹窗:
1.5、图表:
1.6、穿梭框:
1.7、上传:
1.7.1、element中的上传
后管项目中一般使用的都是基于elementui的上传组件。 upload上传
1.7.2、weui中的上传
此上传用于移动端实例 带lzr压缩的上传
注:不同版本可能插件的使用方法会有不同
附:带lzr压缩的移动端weui上传code
<!--uparea -->
//同时需要引入对应的weui.css
<div class="upload_op_area">
<div class="weui-gallery" id="gallery">
<span class="weui-gallery__img" id="galleryImg"></span>
<div class="weui-gallery__opr">
<a href="javascript:" class="weui-gallery__del">
<i class="weui-icon-delete weui-icon_gallery-delete"></i>
</a>
</div>
</div>
<div class="weui-cells weui-cells_form">
<div class="weui-cell">
<div class="weui-cell__bd">
<div class="weui-uploader">
<div class="weui-uploader__bd">
<ul class="weui-uploader__files" id="uploaderFiles">
</ul>
<div class="weui-uploader__input-box">
<input id="uploaderInput" class="weui-uploader__input zjxfjs_file" type="file" accept="image/*"><!--去除可以一次多张不然压缩可能会卡死-->
</div>
</div>
</div>
</div>
</div>
</div>
</div>
//引入js
<script src="/static/wechat/js/frame/compressImg/lrz.bundle.js"></script>
<script src="https://cdn.bootcss.com/jquery-weui/1.2.0/js/jquery-weui.min.js"></script>
//上传图片mock
$('.uplaod_tab div').on('click', function () {
$(this).addClass('selected')
$(this).siblings().removeClass('selected')
});
var tmpl = '<li class="weui-uploader__file pr" style="background-image:url(#url#)"><div class="type"><span></span></div></li>',
$gallery = $("#gallery"),
$galleryImg = $("#galleryImg"),
$uploaderInput = $("#uploaderInput"),
$uploaderFiles = $("#uploaderFiles"),
count = 0,
oldCode = '',
formData = new FormData();
var mainPc = 0;
$uploaderInput.on("change", function (e) {
var src, url = window.URL || window.webkitURL || window.mozURL,
files = e.target.files;
if (mainPc > 0 && $('.uplaod_tab .selected').attr('code') == 'mainpic') {
$.alert('只能上传1张封面图');
stopScroll($('.weui-mask'));
$uploaderInput.val('')
return false;
}
if (count >= 12 || files.length > 12) {
$.alert('最多上传12张图片');
stopScroll($('.weui-mask'))
return false;
}
var isOver = false;
$.showLoading('图片处理中请稍等~')
for (var i = 0, len = files.length; i < len; ++i) {
var file = files[i];
var fileName = file.name;
lrz(file)
.then(function (rst) {
$.hideLoading()
console.log('压缩后:' + rst.fileLen)
file = rst.file;
imgWrapList.forEach(function (item, index) {
if (file.size == item.size && file.name == item.name) {
isOver = true
$.alert('图片重复', function () {
isOver = false
$("#uploaderInput").val('')
});
stopScroll($('.weui-mask'))
return false;
}
})
if (isOver) {
return
}
if (file.size > 10 * 1024 * 1024) {
$.alert('请上传不超过10M的图片');
stopScroll($('.weui-mask'))
return false;
}
if(fileName){
file.name=fileName;
}
transformFileToFormData(file)
if (url) {
src = url.createObjectURL(file);
} else {
src = e.target.result;
}
count++;
var str = '';
var tmpl1 = (tmpl.split('<span>')[0] + '<span>' + str + tmpl.split('<span>')[1])
$uploaderFiles.append($(tmpl1.replace('#url#', src)));
//$(tmpl).find('.type').find('span').text(str)
$.ajax({
timeout: 30000,
type: "POST",
url:,
data: formData,
beforeSend: function () {
$.showLoading('图片上传中...')
},
contentType: false, // 注意这里应设为false
processData: false, // 告诉jquery不要处理发送的数据
success: function (res) {
if (res.code === 200) {
if (!oldCode) {
var code = $('.uplaod_tab .selected').attr('code');
oldCode = code
roomPictypes += code //图片所属的类型
roomPics += res.data.name
} else {
var code = $('.uplaod_tab .selected').attr('code');
if (oldCode != code) {
if (roomPictypes.indexOf(code) < 0) {
oldCode = code
roomPictypes += (',' + code)
roomPics += (';' + res.data.name)
} else {
var index = roomPictypes.replace(',', '').indexOf(code)
var tempArr = roomPics.split(';')
var str = tempArr[index]
str += (',' + res.data.name)
tempArr[index] = str
roomPics = tempArr.join(';')
}
} else {
roomPics += (',' + res.data.name)
}
}
}
},
complete: function () {
$("#uploaderInput").val('');
formData.delete('type');
// size
formData.delete('size');
// name
formData.delete('name');
// lastModifiedDate
formData.delete('lastModifiedDate');
// append 文件
formData.delete('file');
$.hideLoading();
},
error: function (error) {
delHandle($uploaderFiles.length - 1)
$.alert('图片上传失败,请重试');
}//请求出错
});
})
}
});
var index; //第几张图片
$uploaderFiles.on("click", "li", function () {
index = $(this).index();
$galleryImg.attr("style", this.getAttribute("style"));
$gallery.fadeIn(100);
});
1.7.3、tinyUpload
引入文件
<script src="../../js/jquery.js"></script>
<link rel="stylesheet" href="../../css/tinyImgUpload.css">
<script src="../../js/tinyImgUpload.js"></script>
`/**
* tinyImgUpload
* @param ele [string] [生成组件的元素的选择器]
* @param options [Object] [对组件设置的基本参数]
* options具体参数如下
* path 图片上传的地址路径 必需
* onSuccess(res) 文件上传成功后的回调 参数为返回的文本 必需
* onFailure(res) 文件上传失败后的回调 参数为返回的文本 必需
* @return [function] [执行图片上传的函数]
* 调用方法
* tinyImgUpload('div', options)
*/
function tinyImgUpload(ele, options) {
// 判断容器元素合理性并且添加基础元素
var eleList = document.querySelectorAll(ele);
if(eleList.length == 0){
console.log('绑定的元素不存在');
return;
}else if(eleList.length>1){
console.log('请绑定唯一元素');
return;
}else {
eleList[0].innerHTML ='<div id="img-container" >'+
'<div class="img-up-add img-item"><div class="up_title">上传电脑图片</div><span class="img-add-icon"><img src="../../img/add_img_icon.png" alt="" width="64px"></span> </div>'+
'<div class="prev_area">'+
'<input type="file" name="files" id="img-file-input" multiple ">'+
'</div>';
var ele = eleList[0].querySelector('#img-container');
ele.files = []; // 当前上传的文件数组
}
// 为添加按钮绑定点击事件,设置选择图片的功能
var addBtn = document.querySelector('.img-up-add');
addBtn.addEventListener('click',function () {
document.querySelector('#img-file-input').value = null;
document.querySelector('#img-file-input').click();
return false;
},false)
// 预览图片
//处理input选择的图片
function handleFileSelect(evt) {
var files = evt.target.files;
for(var i=0, f; f=files[i];i++){
// 过滤掉非图片类型文件
if(!f.type.match('image.*')){
continue;
}
// 过滤掉重复上传的图片
var tip = false;
for(var j=0; j<(ele.files).length; j++){
if((ele.files)[j].name == f.name){
layer.alert('图片已存在')
tip = true;
break;
}
}
if(!tip){
// 图片文件绑定到容器元素上
if(ele.files.length>=12){
layer.alert('最多12张');
return false
}
ele.files.push(f);
var reader = new FileReader();
reader.onload = (function (theFile) {
return function (e) {
var oDiv = document.createElement('div');
oDiv.className = 'img-thumb img-item border_all';
// 向图片容器里添加元素
oDiv.innerHTML = '<img class="thumb-icon" src="'+e.target.result+'" />'+
'<a href="javscript:;" class="img-remove">x</a>'
ele.insertBefore(oDiv, addBtn);
// $('.prev_area').append(oDiv)
uploadImg()
};
})(f);
reader.readAsDataURL(f);
}
}
}
document.querySelector('#img-file-input').addEventListener('change', handleFileSelect, false);
// 删除图片
function removeImg(evt) {
if(evt.target.className.match(/img-remove/)){
console.log('3',ele.files);
// 获取删除的节点的索引
function getIndex(ele){
if(ele && ele.nodeType && ele.nodeType == 1) {
var oParent = ele.parentNode;
var oChilds = oParent.children;
for(var i = 0; i < oChilds.length; i++){
if(oChilds[i] == ele)
return i;
}
}else {
return -1;
}
}
// 根据索引删除指定的文件对象
var index = getIndex(evt.target.parentNode);
ele.removeChild(evt.target.parentNode);
if(index < 0){
return;
}else {
ele.files.splice(index, 1);
//对应删除库里的图片?
}
console.log('4',ele.files);
}
}
ele.addEventListener('click', removeImg, false);
// 上传图片
function uploadImg() {
console.log(ele.files);
var xhr = new XMLHttpRequest();
var formData = new FormData();
for(var i=0, f; f=ele.files[i]; i++){
formData.append('files', f);
}
console.log('1',ele.files);
console.log('2',formData);
$.ajax(
{
type:"POST",//通常会用到两种:GET,POST。默认是:GET
url:options.path,//(默认: 当前页地址) 发送请求的地址
beforeSend:function () {
},
data:formData,
contentType: false, // 注意这里应设为false
processData:false, // 告诉jquery不要处理发送的数据
success:options.onSuccess, //请求成功
error:options.onFailure,//请求出错
complete:function () {
$('#img-file-input').val('')
}//请求完成
});
}
return uploadImg;
}`
1.8、分页:
1.8.1、移动端分页
mescroll连接
移动端分页目前采用第三方插件库mescroll.js (也可使用其他第三方插件比如iscroll)
1.8.2、pc端分页
pc端分页目前采用第三方插件库laypage、kkpager、element-ui分页等
1.9、轮播:
1.9.1、swiper轮播组件
第三方的轮播组件swiperswiper使用文档
1.9.2、bootstrap轮播
bootstrap carousel bootstrap轮播