带数据储存的计算器
HTML
<!DOCTYPE html>
<html lang =“ zh_CN”>
<head>
<meta charset =“ UTF-8”>
<meta name =“ viewport”
content =“ width = device-width,initial-scale = 1,minimum-scale = 1,maximum-scale = 1,user-scaleable = no,viewport-fit = cover”>
<meta http-equiv =“ X-UA-Compatible” content =“ ie = edge”>
<title> MVC演示</ title>
</ head>
<body>
<div class =“ page”>
<section id =“ app1”> //section标签
<div class =“ output”> //输出值
<span id =“ number”> 100 </ span>
</ div>
<div class =“ actions”>
<button id =“ add1”> + 1 </ button>
<button id =“ minus1”>-1 </ button>
<button id =“ mul2”> * 2 </ button>
<button id =“ divide2”>÷2 </ button>
</ div>
</ section>
</ div>
<script src =“ main.js”> </ script> //引入main.js
</ body>
</ html>
CSS
#app1 {
width: 50vw;
height: 50vh;
}
#app1 .output {
}
#app1 .actions {
}
reset.css(重置CSS)
* {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
*::before,
*::after {
box-sizing: border-box;
}
ol,
ul {
list-style: none;
}
JS
import "./app1.css"; //JS自己调用CSS
import $ from "jquery"; //JS自己调用jquery
const $button1 = $("#add1");
const $button2 = $("#minus1");
const $button3 = $("#mul2");
const $button4 = $("#divide2");
const $number = $("#number");
const n = localStorage.getItem("n");//获取本地存储的值
$number.text(n || 100); //把n写入
$button1.on("click", () => {
let n = parseInt($number.text());//获取n(把字符串解析为整数)
n += 1;
localStorage.setItem("n", n); //修改本地储存的值
$number.text(n); //修改html中的值
});
$button2.on("click", () => {
let n = parseInt($number.text());
n -= 1;
localStorage.setItem("n", n);
$number.text(n);
});
$button3.on("click", () => {
let n = parseInt($number.text());
n *= 2;
localStorage.setItem("n", n);
$number.text(n);
});
$button4.on("click", () => {
let n = parseInt($number.text());
n /= 2;
localStorage.setItem("n", n);
$number.text(n);
});
gloal.css
body{
overflow: hidden;
}
body > .page{
display: flex;
flex-wrap: wrap;
}
body > .page > section{
width: 50vw;
height: 50vh;
border: 1px solid grey;
}
main.js(外部引入)
import "./reset.css";
import "./global.css";
import "./app1.js";
import "./app2.js";
import "./app3.js";
import "./app4.js";
优化MVC
带数据储存的计算器
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>MVC Demo</title>
</head>
<body>
<div class="page">
<section id="app1"></section>
<section id="app2"></section>
</div>
<script src="main.js"></script>
</body>
</html>
CSS
#app1 {
width: 50vw;
height: 50vh;
}
#app1 .output {
}
#app1 .actions {
}
reset.css(重置CSS)
* {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
*::before,
*::after {
box-sizing: border-box;
}
ol,
ul {
list-style: none;
}
JS
import './app1.css'
import $ from 'jquery'
const eventBus = $(window)
// 数据相关都放到m
const m = {
data: {
n: parseInt(localStorage.getItem('n')) //获取data(n)本地储存(字符串变成整数)
},
create() {}, //增
delete() {}, //删
update(data) { //改
Object.assign(m.data, data) //替换data
eventBus.trigger('m:updated') //触发eventBus事件
localStorage.setItem('n', m.data.n) //替换本地储存数据data
},
get() {} //查
}
// 视图相关都放到v
const v = {
el: null,
html: `
<div>
<div class="output">
<span id="number">{{n}}</span>
</div>
<div class="actions">
<button id="add1">+1</button>
<button id="minus1">-1</button>
<button id="mul2">*2</button>
<button id="divide2">÷2</button>
</div>
</div>
`,
init(container) { //初始化
v.el = $(container) //获取传入的参数(容器container)并声明v.el
},
render(n) { //渲染
if (v.el.children.length !== 0) v.el.empty()
$(v.html.replace('{{n}}', n)) //把html中占位符替换
.appendTo(v.el) //再写入html
}
}
// 其他都c
const c = {
init(container) {
v.init(container)
v.render(m.data.n) // view = render(data)
c.autoBindEvents()
eventBus.on('m:updated', () => {
console.log('here')
v.render(m.data.n)
})
},
events: {
'click #add1': 'add',
'click #minus1': 'minus',
'click #mul2': 'mul',
'click #divide2': 'div',
},
add() {
m.update({n: m.data.n + 1})
},
minus() {
m.update({n: m.data.n - 1})
},
mul() {
m.update({n: m.data.n * 2})
},
div() {
m.update({n: m.data.n / 2})
},
autoBindEvents() {
for (let key in c.events) {
const value = c[c.events[key]]
const spaceIndex = key.indexOf(' ')
const part1 = key.slice(0, spaceIndex)
const part2 = key.slice(spaceIndex + 1)
v.el.on(part1, part2, value)
}
}
}
export default c //传出c
注意:bottom初始化比rander早会导致页面失效.
采取的方式用initial(){}函数
init(){
c.ui={
button1 : $('#add1'),
button2 : $('#sub1'),
button3 : $('#mul2'),
button4 : $('#div2'),
number : $('#number')
}
c.bindEvents()
},
gloal.css
body{
overflow: hidden;
}
body > .page{
display: flex;
flex-wrap: wrap;
}
body > .page > section{
width: 50vw;
height: 50vh;
border: 1px solid grey;
}
main.js(外部引入)
import './reset.css'
import './global.css'
import x from './app1.js' //x === c
import y from './app2.js'
import './app3.js'
import './app4.js'
x.init('#app1') //x.init('#app1') === c.init('#app1'),传入到app2.js
y.init('#app2')
(大师级)优化MVC
带数据储存的计算器
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>MVC Demo</title>
</head>
<body>
<div class="page">
<section id="app1"></section>
<section id="app2"></section>
</div>
<script src="main.js"></script>
</body>
</html>
CSS
#app1 {
width: 50vw;
height: 50vh;
}
#app1 .output {
}
#app1 .actions {
}
reset.css(重置CSS)
* {
margin: 0;
padding: 0;
}
* {
box-sizing: border-box;
}
*::before,
*::after {
box-sizing: border-box;
}
ol,
ul {
list-style: none;
}
JS
import './app1.css'
import Vue from 'vue'
const init = (el) => {
const m = {
get() {
return parseFloat(localStorage.getItem('n'))
},
set(n) {
localStorage.setItem('n', n)
}
}
new Vue({
el: el,
data: {n: m.get()},
methods: {
add() {
this.n += 1
},
minus() {
this.n -= 1
},
mul() {
this.n *= 2
},
div() {
this.n /= 2
},
},
watch: {
n: function () {
m.set(this.n)
},
},
template: `
<section>
<div class="output">
<span id="number">{{n}}</span>
</div>
<div class="actions">
<button @click="add">+1</button>
<button @click="minus">-1</button>
<button @click="mul">*2</button>
<button @click="div">÷2</button>
</div>
</section>
`
})
}
export default init
思考
- data: {}是什么?
- methods: {}是什么?
- {{n}}是什么?
- @click是什么?
- 为什么可以导出export default init?
注意:this.n中的n并不是函数!当n变化的时候执行一个函数!
![ee770cad6952390628511a6bbb356c45.png](https://img-blog.csdnimg.cn/img_convert/ee770cad6952390628511a6bbb356c45.png)
gloal.css
body{
overflow: hidden;
}
body > .page{
display: flex;
flex-wrap: wrap;
}
body > .page > section{
width: 50vw;
height: 50vh;
border: 1px solid grey;
}
main.js(外部引入)
import './reset.css'
import './global.css'
import x from './app1.js' //x === c
import y from './app2.js'
import './app3.js'
import './app4.js'
x.init('#app1')
y.init('#app2')
Base(完成了EventBus的继承)
EventBus.js
import $ from 'jquery'
class EventBus {
constructor() {
this._eventBus = $(window)
}
on(eventName, fn) {
return this._eventBus.on(eventName, fn)
}
trigger(eventName, data) {
return this._eventBus.trigger(eventName, data)
}
off(eventName, fn) {
return this._eventBus.off(eventName, fn)
}
}
export default EventBus
Model.js
用自身的函数覆盖原型链上函数
import EventBus from './EventBus'
//简化版的函数
class Model extends EventBus {
//处于对象的自身上
constructor(options) {
super()
const keys = ['data', 'update', 'create', 'delete', 'get']
keys.forEach((key) => {
if (key in options) {
this[key] = options[key]
}
})
}
/*未简化的代码
this.data = options.data
this.update = options.data
this.create = options.create
this.delete = options.delete
this.get = options.get
*/
//下面的函数是处于原型链中
create() {
console && console.error && console.error('你还没有实现 create')
}
delete() {
console && console.error && console.error('你还没有实现 delete')
}
update() {
console && console.error && console.error('你还没有实现 update')
}
get() {
console && console.error && console.error('你还没有实现 get')
}
}
export default Model
View.js
import $ from 'jquery'
import EventBus from './EventBus'
class View extends EventBus{
// constructor({el, html, render, data, eventBus, events}) {
constructor(options) {
super() // EventBus#constructor()
Object.assign(this, options)
this.el = $(this.el)
this.render(this.data)
this.autoBindEvents()
this.on('m:updated', () => {
this.render(this.data)
})
}
autoBindEvents() {
for (let key in this.events) {
const value = this[this.events[key]]
const spaceIndex = key.indexOf(' ')
const part1 = key.slice(0, spaceIndex)
const part2 = key.slice(spaceIndex + 1)
this.el.on(part1, part2, value)
}
}
}
export default View
![b5e88c40cca4b545788558d6f8ab83a8.png](https://img-blog.csdnimg.cn/img_convert/b5e88c40cca4b545788558d6f8ab83a8.png)
![8b0963268d9c4dff4e97f6feae5d89b1.png](https://img-blog.csdnimg.cn/img_convert/8b0963268d9c4dff4e97f6feae5d89b1.png)
![f2072a8bea6c59ea344e055bbc8dccdd.png](https://img-blog.csdnimg.cn/img_convert/f2072a8bea6c59ea344e055bbc8dccdd.png)