在已经写好的MVC设计模式下,改成Vue:
一.下载
yarn add vue
二. 引入
import Vue from 'vue'
三. 改写
1. MVC
const m = new Model({
data: {
n: parseInt(localStorage.getItem("n")),
},
update(value) {
Object.assign(m.data, value);
m.trigger("m:update");
localStorage.setItem("n", m.data.n);
},
});
//合并v和c,重命名为view,用class,省略对象名view.放到一个函数里
const init = (el) => {
new View({
el: el, //容器,由外部传进来
data: m.data, //数据
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="multi2">*2</button>
<button id="divide2">÷2</button>
</div>
</div>
`,
render(data) { //渲染
const n = data.n;
if (this.el.children.length !== 0) {
this.el.empty();
}
$(this.html.replace("{{n}}", n)).prependTo(this.el);
},
events: { //表驱动
"click #add1": "add",
"click #minus1": "minus",
"click #multi2": "multi",
"click #divide2": "div",
},
add() {
m.update({ n: m.data.n + 1 });
},
minus() {
m.update({ n: m.data.n - 1 });
},
multi() {
m.update({ n: m.data.n * 2 });
},
div() {
m.update({ n: m.data.n / 2 });
},
});
};
export default init;
在main.js里调用init函数:
init('#app1') //传容器,el
2. Vue
import "./app1.css";
import Vue from "vue";
const init = (el) => {
new Vue({
el: el,
data: { n: parseInt(localStorage.getItem("n")) },
template: `
<section id='app1'>
<div class="output">
<span id="number">{{n}}</span>
</div>
<div class="actions">
<button @click="add">+1</button>
<button @click="minus">-1</button>
<button @click="multi">*2</button>
<button @click="div">÷2</button>
</div>
</section>
`,
methods: {
add() {
this.n += 1;
},
minus() {
this.n -= 1;
},
multi() {
this.n *= 2;
},
div() {
this.n /= 2;
},
},
watch: {
n() {
localStorage.setItem("n", this.n);
},
},
});
};
export default init;
1. el
需要一个容器
2. data
Vue认为对象m没必要,数据就直接存成data这个对象
3. template
就是MVC里的html。注意:我们原来的容器是index.html里写好的<section id='app1'></section> 但是Vue的template会把外边的section替换成字符串里的最外层div,所以字符串里也写和外边一样的容器。还把id带上是因为css样式是根据id找的。
4. methods
把事件触发执行的函数都放在methods里。函数里改变数据时,本来是this.data.n,但是Vue认为data多余,所以写成 this.n 即可。
5. @click
绑定事件不需要再用jQ获取元素和遍历events表去绑定了。只需要在template里的特定标签上加一个属性,@click='add' ,表示点击该标签元素触发add函数。
6. watch
表示监听,当n发生变化时,就把它存进localStorage里。
四. 总结
但是这个思想在Vue里没有应用。我们只是改变了n,并没有调用render,那这个变化是怎么应用到页面中的呢?Vue认为每次都要render很麻烦,于是在n变化时,就自动地把这个变化渲染到页面,而且Vue的更新页面不是全部更新,是哪里变化,就局部地重新渲染哪里。
React是显式调用render的