Vuejs结合html5 localstorage本地缓存开发webapp项目源码,项目可以记录每次存储的数据,并统计历史记录、本月记录、最高记录等等。
点击在线预览
github仓库地址:
https://github.com/zhongyoucong/app/tree/master/app2.0
js代码
//日期格式化函数
Date.prototype.format = function(fmt) {
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
}
for (var k in o) {
if (new RegExp("(" + k + ")").test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
}
}
return fmt;
};
var dataobj, data, index;
//判断用户是否是第一次使用(专指没有清空过缓存那些)
if (localStorage.getItem("data")) {
dataobj = JSON.parse(localStorage.getItem("data"));
} else {
dataobj = [];
data = localStorage.setItem("data", JSON.stringify(dataobj));
}
var vue = new Vue({
el: "#wordText",
data: {
//原始用户评论信息
textcontent: dataobj,
textcontents: [],
//全部总计
totalCount:[
{totalWeight:'',totalIncome:''},
{hightWeight:'',hightIncome:'',hightPrice:''}
],
//本月总计
crrMonthCount:[
{totalWeight:'',totalIncome:''},
{hightWeight:'',hightIncome:'',hightPrice:''}
],
rcShowflag: false,
allShowflag:false,
crrShowflag:false
},
/*
computed: {
textcontents: function() {
return this.textcontent.reverse();
}
},*/
methods: {
//点击遮罩层消失
wraphide:function(){
this.rcShowflag = false;
},
//阻止冒泡
stopPro:function(e){
e = e || event;
e.stopPropagation();
},
showWrap: function() {
//切换显示
this.rcShowflag = true;
},
//全部总计显示隐藏
allwraphide:function(){
this.allShowflag = false;
},
allshowWrap:function(){
this.allShowflag = true;
var totalWeight=0,
totalIncome=0,
hightWeight=0,
hightPrice=0,
hightIncome=0;
//获取本地缓存数据
var localData = JSON.parse(localStorage.getItem("data"));
for(var i = 0, len = localData.length; i < len; i++){
totalWeight += localData[i].weight;
totalIncome = totalIncome + ((localData[i].price*localData[i].weight)*100)/100;
//最高重量
if(hightWeight < localData[i].weight){
hightWeight = localData[i].weight;
}
//最高花价
if(hightPrice < localData[i].price){
hightPrice = localData[i].price;
}
//最高收入
var temp = ((localData[i].price*localData[i].weight)*100)/100;
if(hightIncome < temp ) {
hightIncome = temp;
}
}
//总计赋值
this.totalCount[0].totalWeight = Math.round(totalWeight*100)/100;
this.totalCount[0].totalIncome = Math.round(totalIncome*100)/100;
//历史之最赋值
this.totalCount[1].hightWeight = Math.round(hightWeight*100)/100;
this.totalCount[1].hightIncome = Math.round(hightIncome*100)/100;
this.totalCount[1].hightPrice = Math.round(hightPrice*100)/100;
},
//本月总计显示隐藏
crrwraphide:function(){
this.crrShowflag = false;
},
crrShowWrap:function(){
this.crrShowflag = true;
var localData = JSON.parse(localStorage.getItem("data"));
var crrMonthData = []; //本月数据容器
var data,crrMonth,crrYear;
var nowYear = new Date().getFullYear();
var nowMonth = new Date().getMonth()+1;
//过滤本月数据
for(var i = 0, len = localData.length; i < len; i++){
data = (localData[i].data.split(" "))[0];
crrMonth = parseInt((data.split("-"))[1]); //数据里面的月
crrYear = parseInt((data.split("-"))[0]); //数据里面的年
//判断数据里面日期是否等于当前月,等于则存储起来
if(nowYear == crrYear && nowMonth == crrMonth){
crrMonthData[crrMonthData.length] = localData[i];
}
}
//赋值输出到页面
var totalWeight=0,
totalIncome=0,
hightWeight=0,
hightPrice=0,
hightIncome=0;
//获取本地缓存数据
for(var i = 0, len = crrMonthData.length; i < len; i++){
totalWeight += crrMonthData[i].weight;
totalIncome = totalIncome + ((crrMonthData[i].price*crrMonthData[i].weight)*100)/100;
//最高重量
if(hightWeight < crrMonthData[i].weight){
hightWeight = crrMonthData[i].weight;
}
//最高花价
if(hightPrice < crrMonthData[i].price){
hightPrice = crrMonthData[i].price;
}
//最高收入
var temp = ((crrMonthData[i].price*crrMonthData[i].weight)*100)/100;
if(hightIncome < temp ) {
hightIncome = temp;
}
}
//总计赋值
this.crrMonthCount[0].totalWeight = Math.round(totalWeight*100)/100;
this.crrMonthCount[0].totalIncome = Math.round(totalIncome*100)/100;
//历史之最赋值
this.crrMonthCount[1].hightWeight = Math.round(hightWeight*100)/100;
this.crrMonthCount[1].hightIncome = Math.round(hightIncome*100)/100;
this.crrMonthCount[1].hightPrice = Math.round(hightPrice*100)/100;
},
//添加工作记录
addItem: function(e) {
var e = e || event;
var index = null;
var tempobj = {}; //存储插入数据的容器
var localData = JSON.parse(localStorage.getItem("data"));
//判断开始的时候是否是否为空
if (localData.length == 0) {
index = 1;
} else {
index = parseInt(localData[0].id) + 1;
}
var numReg = /^\d+(\.\d+)?$/; //小数字正则
var text = document.getElementsByClassName("words")[0].value;
var price = document.getElementById("price").value;
var weight = document.getElementById("weight").value;
var floatprice = parseFloat(price);
var floatweight = parseFloat(weight);
var data = new Date().format("yyyy-MM-dd hh:mm:ss");
var flag = (text !== "" && price !== "" && weight !== "" && numReg.test(price) && numReg.test(weight));
if (flag){
tempobj.id = index; //设置id
tempobj.price = floatprice; //设置花价
tempobj.weight = floatweight; //设置重量
tempobj.content = text; //设置内容
tempobj.data = data; //设置时间
localData.unshift(tempobj);
this.textcontent = localData; //当前对象添加新增内容
localStorage.setItem("data", JSON.stringify(localData));
//重置表单
document.getElementsByClassName("words")[0].value = "";
document.getElementById("price").value = "";
document.getElementById("weight").value = "";
//切换隐藏
this.rcShowflag = false;
} else {
alert("请按要求输入的内容!");
e.stopPropagation();
}
},
delItem: function(index) {
this.textcontent.splice(index, 1); //删除vue数据中对应选项
//删除本地localStorage中的对应的数据项
var localData = JSON.parse(localStorage.getItem("data")); //先获取缓存数据
localData.splice(index, 1); //删除缓存数据
localStorage.setItem("data", JSON.stringify(localData)); //保存缓存数据
}
}
});
html代码
<html lang="en">
<head>
<meta charset="utf-8">
<title>卖花记录本title>
<link rel="apple-touch-icon" sizes="57x57" href="img/app.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta content="telephone=yes" name="format-detection" />
<meta name="apple-mobile-web-app-status-bar-style" content="white">
<meta name="x5-fullscreen" content="true">
<meta name="apple-touch-fullscreen" content="yes">
<link rel="stylesheet" href="css/font-awesome.min.css" />
<link rel="stylesheet" href="css/index.css" />
<script type="text/javascript" src="js/vue.min.js">script>
head>
<body>
<div id="wordText">
<div class="wrapbox" v-bind:class="{'active':rcShowflag}" @click="wraphide()">
<div class="box" @click="stopPro()">
<form>
<input type="number" placeholder="多少钱一斤花(块)" class="num fl" id="price">
<input type="number" placeholder="多少斤花(斤)" class="num fr" id="weight">
<textarea placeholder="请输入你要记录的内容,限定200个字 " maxlength="200" class="words">textarea>
<div class="bluebtn" @click="addItem()">立即保存div>
form>
div>
div>
<div class="wrapbox" v-bind:class="{'active':crrShowflag}" @click="crrwraphide()">
<div class="box" @click="stopPro()">
<div class="countbox">
<h1><i class="icon-signal">i> 本月总计h1>
<h3><i class="icon-trophy">i> 总重量:<strong>{{crrMonthCount[0].totalWeight}}strong> 斤h3>
<h3><i class="icon-strikethrough">i> 总收入:<strong>{{crrMonthCount[0].totalIncome}}strong> 元h3>
div>
<div class="countbox">
<h1><i class="icon-bar-chart">i> 本月之最h1>
<h3><i class="icon-trophy">i> 最高重量:<strong>{{crrMonthCount[1].hightWeight}}strong> 斤h3>
<h3><i class="icon-strikethrough">i> 最高收入:<strong>{{crrMonthCount[1].hightIncome}}strong> 元h3>
<h3><i class="icon-list-alt">i> 最高花价:<strong>{{crrMonthCount[1].hightPrice}}strong> 元/斤h3>
div>
div>
div>
<div class="wrapbox" v-bind:class="{'active':allShowflag}" @click="allwraphide()">
<div class="box" @click="stopPro()">
<div class="countbox">
<h1><i class="icon-signal">i> 全部总计h1>
<h3><i class="icon-trophy">i> 总重量:<strong>{{totalCount[0].totalWeight}} strong>斤h3>
<h3><i class="icon-strikethrough">i> 总收入:<strong>{{totalCount[0].totalIncome}} strong>元h3>
div>
<div class="countbox">
<h1><i class="icon-bar-chart">i> 历史之最h1>
<h3><i class="icon-trophy">i> 最高重量:<strong>{{totalCount[1].hightWeight}}strong> 斤h3>
<h3><i class="icon-strikethrough">i> 最高收入:<strong>{{totalCount[1].hightIncome}}strong> 元h3>
<h3><i class="icon-list-alt">i> 最高花价:<strong>{{totalCount[1].hightPrice}}strong> 斤/元h3>
div>
div>
div>
<div class="contentlist">
<div class="item" v-for="(value, index) in textcontent">
<p class="textcontent"><i class="icon-tags">i> {{value.content}}p>
<p>
<span class="price number"><i class="icon-strikethrough">i> 单价:(<strong>{{value.price}}strong>)元/斤span>
<span class="weight number"><i class="icon-trophy">i> 重量:(<strong>{{value.weight}}strong>)斤span>
<span class="total number"><i class="icon-strikethrough">i> 收入:(<strong>{{Math.round(value.weight*value.price*100)/100}}strong>)元span>
p>
<p>
<span class="delbtn" @click="delItem(index)"><i class="icon-remove-circle">i> 删除span>
<span class="data"><i class="icon-calendar">i> {{value.data}}span>
p>
div>
div>
<div class="bottombtn">
<div class="savebtn" @click="showWrap()"><i class="icon-pencil">i> 我要记录div>
<div class="currmonthbtn" @click="crrShowWrap()"><i class="icon-signal">i> 本月总计div>
<div class="totalbtn" @click="allshowWrap()"><i class="icon-bar-chart">i> 全部总计div>
div>
div>
body>
<script src="js/index.js">script>
html>
css代码
@charset "UTF-8";
body,
div,
span,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
code,
del,
dfn,
em,
img,
q,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
dialog,
figure,
footer,
header,
hgroup,
nav,
section {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
vertical-align: baseline;
}
a {
text-decoration: none;
}
ul li {
list-style-type: none;
}
a img {
border: none;
}
a {
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none;
-webkit-user-select: none;
}
html {
font-size: 62.5%;
font-family: arial, "Hiragino Sans GB", "Microsoft Yahei", "微软雅黑", "宋体", Tahoma, Arial, Helvetica, STHeiti;
}
.bluebtn {
width: 100%;
height: 50px;
line-height: 50px;
text-align: center;
color: #fff;
background: #39F;
border: 1px solid #39F;
border-radius: 0;
-webkit-appearance: none;
font-size: 2rem;
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none;
-webkit-user-select: none;
}
body {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background: #E4E4E4;
padding: 0 0 6rem 0;
}
#wordText .wrapbox {
display: none;
position: fixed;
z-index: 99999;
width: 94%;
height: 100%;
padding: 0 3%;
font-size: 2rem;
background: url(../img/maskbg.png);
}
#wordText .active {
display: block;
}
#wordText .wrapbox .box {
position: relative;
top: 50%;
padding: 2rem;
margin: -16.7rem auto 0;
background: #fff;
border-radius: 2.4rem;
border: 4px solid #3399FF;
}
#wordText .wrapbox .box textarea {
width: 99.5%;
height: 17.1rem;
margin: 0;
padding: 0;
box-shadow: 0 0 0.1rem #ccc;
border: 1px solid #ccc;
resize: none;
-webkit-appearance: none;
font-size: 1.6rem;
-webkit-tap-highlight-color: transparent;
}
#wordText .wrapbox .box textarea::-webkit-input-placeholder {
font-size: 1.6rem;
}
#wordText .wrapbox .box .num {
height: 4rem;
width: 41%;
margin-bottom: 1rem;
font-size: 1.6rem;
box-shadow: 0 0 0.1rem #ccc;
border: 1px solid #ccc;
-webkit-appearance: none;
-webkit-tap-highlight-color: transparent;
}
#wordText .contentlist .number {
display: block;
margin: 0.5rem 0;
color: green;
font-size: 1.5rem;
}
#wordText .contentlist .number strong {
font-size: 1.6rem;
color: red;
margin: 0 0.2rem;
}
#wordText .wrapbox .box .fl {
float: left;
}
#wordText .wrapbox .box .fr {
float: right;
}
#wordText .wrapbox .box .countbox {
margin: 1rem 0;
}
#wordText .wrapbox .box .countbox h1 {
color: #666;
font-weight: normal;
margin-bottom: 1rem;
}
#wordText .wrapbox .box .countbox h3 {
font-size: 1.8rem;
font-weight: normal;
margin: 0.8rem 0;
color: green;
}
#wordText .wrapbox .box .countbox h3 strong {
color: red;
}
#wordText .wrapbox .box .bluebtn {
margin-top: 0.8rem;
border-radius: 0.5rem;
}
#wordText .contentlist {
padding: 3%;
}
#wordText .contentlist .item {
padding: 3%;
margin-bottom: 1.6rem;
background: #fff;
border-radius: 1.2rem;
box-shadow: 0 0.4rem 0 #BCBCBC;
}
#wordText .contentlist .textcontent {
margin-bottom: 1rem;
color: orange;
line-height: 24px;
font-size: 1.8rem;
}
#wordText .bottombtn {
position: fixed;
display: flex;
bottom: 0;
width: 100%;
height: 6rem;
background: #fff;
}
#wordText .bottombtn div {
flex: 1;
height: 6rem;
line-height: 6rem;
text-align: center;
font-size: 1.6rem;
color: #3399FF;
-webkit-tap-highlight-color: transparent;
}
#wordText .contentlist .delbtn {
margin-left: 0.5rem;
color: #3399FF;
font-size: 1.4rem;
-webkit-tap-highlight-color: transparent;
}
#wordText .contentlist .data {
float: right;
color: #999;
font-size: 1.4rem;
}