记账本简单应用-原生&vue的实现对比

1.vue框架简介

引用网上的说法:vue.js 一个核心思想是数据驱动。所谓数据驱动,是指视图是由数据驱动生成的,我们对视图的修改,不会直接操作 DOM,而是通过修改数据。这个等会通过记账本这个案例进行演示体现。

2.原生与vue框架对比

参考1
参考2

1.数据的自动绑定
2.页面参数传递和页面状态管理。
3.模块化开发、无刷新保留场景参数更新
4.代码的可阅读性(模块化开发带来的)
5.基于强大的nodejs,拥有npm包管理器,可以很好滴管理包的版本
6.各子组件样式不冲突
7.视图,数据,结构分离
8.虚拟dom
9.各种指令;过滤器

3.原生操作dom到jQuery的演变

基于原生,你想更新页面或者添加数据显示,避免不了要获取节点、创建节点、添加节点、赋值取值(Element.value Element.innerText等)… 直到后续出来一个jQuery框架,可以简化部分代码,并且兼容性很不错

//原生部分代码展示
var inputElements = document.querySelectorAll('input')
var remakeElement = inputElements[0] //输入文本
var moneyElement = inputElements[1] //输入金额
var addHistory = document.getElementById('add-history')
var historyListElement = document.getElementById('history-list')
var deleteHistoryElement = document.querySelectorAll('delete-btn')

var countMoneyElement = document.getElementById('countMoney')
var srElement = document.getElementById('srMoney')
var fyElement = document.getElementById('fyMoney')


function deleteHistory2(event) {
	var deleteMoney = event.target.parentNode.children[1].innerText
	console.log(event.target.parentNode.children[1].innerText)
	computedMoney(deleteMoney,true)
	historyListElement.removeChild(event.target.parentNode)
}

function appenHistory() {
	var remake = remakeElement.value
	var money = moneyElement.value
	if(!remake.trim().length || !money.trim().length){
		alert('请输入内容!')
		return
	}

	var str =
		`<span>${remake}</span><span>${money}</span><div class="delete-btn" onclick="deleteHistory2(event)">x</div>`

	var liElement = document.createElement('li')
	liElement.innerHTML = str
	liElement.classList.add(parseFloat(money) < 0 ? 'minus-wrap' : 'add-wrap')
	historyListElement.appendChild(liElement)

	// 清空输入
	remakeElement.value = ''
	moneyElement.value = ''
	computedMoney(money)

}

//jQuery 代码展示

//选择器
$(this)	//当前 HTML 元素
$("p")	//所有 <p> 元素
$("p.intro")	//所有 class="intro" 的 <p> 元素
$(".intro")	//所有 class="intro" 的元素
$("#intro")	//id="intro" 的元素
$("ul li:first")	//每个 <ul> 的第一个 <li> 元素
$("[href$='.jpg']")	//所有带有以 ".jpg" 结尾的属性值的 href 属性
$("div#intro .head")	//id="intro" 的 <div> 元素中的所有 class="head" 的元素


//常见取值赋值
$("#test").text()
$("#test").html()
$("#val_test").val()
$("a").attr("href")

//事件
$("p").click(function(){
  $(this).hide();
});


4.jQuery到Vue框架

喜大普奔,我们在也不需要关注dom,不需要由我们直接操作dom,所有的dom操作交由Vue框架,我们只需要维护需要显示的数据即可。如下是基于vue框架开发的记账本简单应用的全部代码,可以直接复制打开。看不懂没关系,我们可以看到,整个script部分并没有发现操作dom的代码,但是他可以实现添加删除,并自动计算值。

操作:我们可以复制如下代码,本地新建一个文件,粘贴代码,改文件后缀为.html,然后双击打开!

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>我的账本</title>
		<!-- <link rel="stylesheet" href="./style.css"> -->
		<style>
			* {
				margin: 0;
				padding: 0;
			}
			
			#app,body {
				display: flex;
				flex-direction: column;
				align-items: center;
				background: #f7f7f7;
				min-height: 100vh;
			}
			
			.title {
				margin: 20px 0;
			}
			
			.container {
				width: 350px;
				margin: 30px 0;
			}
			
			.top-money-wrap {
				display: flex;
				flex-direction: row;
				align-items: center;
				justify-content: space-between;
				margin: 20px 0;
				padding: 20px;
				background: #fff;
				box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
			}
			
			.top-money-wrap>div {
				flex: 1;
				display: flex;
				flex-direction: column;
				align-items: center;
				justify-content: center;
			}
			
			.top-money-wrap>div:first-of-type {
				border-right: 1px solid #dedede;
			}
			
			.top-money-wrap>div .money-add {
				font-size: 20px;
				margin: 5px 0;
				color: #2ecc71;
			}
			
			.top-money-wrap>div .money-minus {
				font-size: 20px;
				margin: 5px 0;
				color: #c0392b;
			}
			
			.history-wrap {}
			
			.history-title {
				margin: 40px 0 10px 0;
				padding-bottom: 10px;
				border-bottom: 1px solid #dedede;
			}
			
			.add-wrap,
			.minus-wrap {
				padding: 10px;
				margin: 10px 0;
				display: flex;
				flex-direction: row;
				align-items: center;
				justify-content: space-between;
				list-style-type: none;
				border-right: 5px solid #2ecc71;
				position: relative;
			
				box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
			}
			
			.minus-wrap {
				border-right: 5px solid #c0392b;
			}
			
			#add-form .input-wrap label {
				margin: 10px 0;
				display: inline-block;
			}
			
			#add-form .input-wrap input {
				display: block;
				padding: 10px;
				width: 100%;
				box-sizing: border-box;
				/* box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24); */
				border: 1px solid #dedede;
				border-radius: 2px;
			}
			
			#add-form .add-btn {
				cursor: pointer;
				background-color: #9c88ff;
				box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
				color: #fff;
				border: 0;
				display: block;
				font-size: 16px;
				margin: 10px 0 30px;
				padding: 10px;
				width: 100%;
			}
			
			.delete-btn{
				padding: 2px 5px;
				background: #c0392b;
				color: #fff;
				position: absolute;
				left: -20px;
				bottom: 0;
				opacity: 0;
			}
			
			.add-wrap:hover .delete-btn{
				opacity: 1;
			}
			.minus-wrap:hover .delete-btn{
				opacity: 1;
			}
			
		</style>
		<!-- 引入vue框架 -->
		<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>

	</head>
	<body>
		<!-- 模仿:https://vanillawebprojects.com/projects/expense-tracker/ -->
		<div id="app">
			<h2 class="title">账本记录</h2>
			<div class="container">
				<h4>你的余额</h4>
				<h1 id="countMoney">{
   
   {countMoney}}元</h1>
				<div class="top-money-wrap">
					<div>
						<h4>收入</h4>
						<p class="money-add" id="srMoney">${
   
   {srMoney}}</p>
					</div>

					<div>
						<h4>费用</h4>
						<p class="money-minus" id="fyMoney">${
   
   {fyMoney}}</p>
					</div>
				</div>

				<div class="history-wrap">
					<h3 class="history-title">
						历史记录
					</h3>
				</div>
				<ul id="history-list">
					<li v-for="(history,index) in historyList" :key="history.id"
						:class="history.money>0?'add-wrap':'minus-wrap'">
						<span>{
   
   {history.text}}</span>
						<span>{
   
   {history.money}}</span>
						<div class="delete-btn" id="delete-history" @click="deleteHistory(index)">x</div>
					</li>
				</ul>


				<div class="history-wrap">
					<h3 class="history-title">
						添加新记录
					</h3>
				</div>


				<form id="add-form">
					<div class="input-wrap">
						<label>文本</label>
						<input type="text" placeholder="请输入文本" v-model="inputRemake">
					</div>

					<div class="input-wrap">
						<label>金额(负数为费用,正数为收入)</label>
						<input type="number" placeholder="请输入金额" v-model="inputMoney">
					</div>

					<button class="add-btn" id="add-history" @click="addHistory">添加记录</button>
				</form>

			</div>
		</div>
		<!-- 使用vue框架实现 -->
		<script>
			const vue = new Vue({
				el: "#app",
				data: {
					inputMoney: '',
					inputRemake: '',
					historyList: [
						// {
						// 	text: '奖金',
						// 	money: 111,
						// 	id: 0,
						// },
						// {
						// 	text: '吃饭',
						// 	money: -11,
						// 	id: 1,
						// }
					],
				},
				mounted(){
					var localData =  JSON.parse(localStorage.getItem('app'))
					
					if(localData){
						this.historyList = localData
					}
				},
				methods: {
					saveLocalData(){
						localStorage.setItem('app',JSON.stringify(this.historyList))
					},
					addHistory(e) {
						e.preventDefault();
						if (!this.inputMoney.trim().length || !this.inputRemake.trim().length) {
							return
						}
						var addData = {
							text: this.inputRemake,
							money: this.inputMoney,
							id: Date.now(),
						}
						this.historyList.push(addData)
						this.inputRemake = ''
						this.inputMoney = ''
						
						this.saveLocalData()
					},
					deleteHistory(deleteIndex) {
						this.historyList.splice(deleteIndex, 1)
						this.saveLocalData()
					}
				},
				computed: {
					srMoney() { //收入金额统计
						var result = 0
						this.historyList.forEach(item => {
							if (item.money >= 0) {
								result += parseFloat(item.money)
							}
						})
						return result
					},
					fyMoney() { //费用金额统计
						var result = 0
						this.historyList.forEach(item => {
							if (item.money < 0) {
								result += -parseFloat(item.money)
							}
						})
						return result
					},
					countMoney() { //余额统计
						return this.srMoney - this.fyMoney
					}
				}
			})
			console.log('vue=', vue)
			// 为了演示数据变化,页面自动更新,请挨个复制如下代码到控制台(Console)然后回车输出,然后注意页面变化,认真看页面变化别眨眼~
			// vue.inputMoney = 967
			// vue.historyList.push({id:91,text:'hahah',money:-54})
			// vue.historyList.push({id:99,text:'hahah',money:9888})
			// vue.historyList[0].money = 967
		</script>
	</body>
</html>



为了演示数据变化,页面自动更新,请挨个复制如下代码到控制台(Console)然后回车输出,然后注意页面变化,认真看页面变化别眨眼~

  • vue.inputMoney = 967
  • vue.historyList.push({id:91,text:‘hahah’,money:-54})
  • vue.historyList.push({id:99,text:‘hahah’,money:9888})
  • vue.historyList[0].money = 967
  • vue.historyList[0].text = ‘改变了’
  • vue.historyList.pop()

5.代码下载&演示图

代码链接

控制台输出,页面更新
控制台输出,页面更新

猜你喜欢

转载自blog.csdn.net/u014632228/article/details/126862316
今日推荐