Vue.js 的自我介绍中,只有说自己接近 MVVM 但不是严格的 MVVM。
我觉得只要会「自动更新画面」就算是有 MVVM 的效果至於有没有达到 MVVM pattern 的结构不用太计较。XDDD
接下来,我们来挑战一个 computed 和 watch 的解释,但是不一起比较,这次我们各别介绍,以免两个人又再度难分难舍。
今天的文章比较短,为了避免观念混淆,所以特别缩短篇幅,集中一个概念的方式介绍。
参考自官网的例子: https://vuejs.org/v2/guide/computed.html
这个例子很好,只是分开讲更清楚,避免不细节用扫视的,想快速学习的朋友们,看图说故事时造成误会。
<template>
<div>
<div><input type="text" v-model="user.firstName"></input></div>
<div><input type="text" v-model="user.lastName"></input></div>
<div>{{ fullName }}</div>
</div>
</template>
export default {
name: 'demo',
data() {
return {
user: {
firstName: 'Foo',
lastName: 'Bar',
},
};
},
computed: {
fullName() {
return this.user.firstName + this.user.lastName;
},
}
}
在这个时候,想像一下 user
是来自 API 的 data。
fullName
对 API 来说是一个不存在的栏位。并且,这一个衍生资料只拿来显示,不会写入的资料,只透过其它栏位来改它。
至於它会连动画面这件事,不用开发者操心,这件事就交给尤雨渓吧。我们只要负责看好文件写 code 就好了。
如果,我们要设计一个 User 的物件
class User {
constructor() {
this.firstName = 'Foo';
this.lastName = 'Bar';
}
getFullName() {
return this.firstName + this.lastName
}
}
以物件的设计来理解,computed 是一种 getter 并且只能读。
所以,在概念上,computed 属於一种无法修改的回传值。
不过实际上,它是一个被快取起来的值,所以依然存在着修改它的可能性,但是这是千千万万不要做的事情。要小心。
原本
<div><input type="text" v-model="user.firstName"></input></div>
可以改成让 v-model
里的文字变少的写法。
<div><input type="text" v-model="firstName"></input></div>
整体的程序码如下面这样
<template>
<div>
<div><input type="text" v-model="firstName"></input></div>
<div><input type="text" v-model="lastName"></input></div>
<div>{{ fullName }}</div>
</div>
</template>
export default {
name: 'demo',
data() {
return {
user: {
firstName: 'Foo',
lastName: 'Bar',
},
};
},
computed: {
firstName: {
set(firstName) {
this.user.firstName = firstName;
},
get() {
return this.user.firstName;
},
},
lastName: {
set(lastName) {
this.user.lastName = lastName;
},
get() {
return this.user.lastName;
},
},
}
}
https://vuex.vuejs.org/guide/forms.html#two-way-computed-property
照着文件介绍,可以把 computed 的 get/set 让 v-model
绑着一个名字,并且将 vuex 存取的方式 mutation 的 commit 和 getters (的 getters) 放在 computed 的 get/set 里面。
会照着文件的指示,明明只是绑两个栏位而已,却写得很多程序码。如下:
<template>
<div>
<div><input type="text" v-model="firstName"></input></div>
<div><input type="text" v-model="lastName"></input></div>
<div>{{ fullName }}</div>
</div>
</template>
export default {
name: 'demo',
computed: {
firstName: {
set(firstName) {
this.$store.commit('firstName', firstName)
},
get() {
return this.$store.getters.firstName;
},
},
lastName: {
set(lastName) {
this.$store.commit('lastName', lastName)
},
get() {
return this.$store.getters.lastName;
},
},
}
}
若在这时候使用 pure component 就会出现在 pure component 里面直接改 props 这样做是不对的,这个之後会另外写一篇专门介绍
也有另外一派,觉得如果要写这多,也许就要槙重考虑是不是不要把所有的资料放在 vuex 里面,必要的再放。这样对状态管理上来说是一件麻烦的事情,因为你只要用方便的 vuex 就会需要很麻烦的写一堆 code
所以,在这个时候,我有延续着我那大胆的猜想,衍生出来的想法「 v-model
不是这麽必要使用呢?」
这是我偏好的写法,若把 v-model
解开,就可以不要靠 computed 的 get/set 串资料,直接把语法写在 html 上面,省掉这些一对一栏位串接的写法,允许 :value
和 @input
的写法不一样,可以拥有不少弹性
这样一来,上述的两个麻烦就不再是麻烦了。所以把资料放进 vuex 里面不是麻烦事,也不会担心 pure component 的资传递是不是光绑栏位就超级麻烦。
而且 script
就可以放进真正复杂的程序码,一行搞定的,都放 html 里面
在Components Basics — Vue.js中,除了前述的「v-model
可以拆开写」之外,拆开写还有提醒两个要注意的事情。
$event
这个关键字<input type="text" @input="$event">
的 $event
要注意它是什麽样的物件。如果是原生的 input 就可能是原生的 event 物件,如果是 UI component 套件提供的 input 像是 Bootstrap 的 <b-input>
就是 value 本身。<template>
<div>
<div><input
type="text"
:value="$store.getters.firstName"
@input="$store.commit('firstName', $event.target.value)"
></div>
<div><input
type="text"
:value="$store.getters.lastName"
@input="$store.commit('lastName', $event.target.value)"
></div>
<div>{{ fullName }}</div>
</div>
</template>
export default {
name: 'demo',
computed: {
fullName() {
return this.user.firstName + this.user.lastName;
},
}
}
万一 @input
出现复杂的情况或非同步的情况。都可以再写成 mehotd 处理。就会让复杂的情况进入 script 处理。
在之後 debug 扫视程序码,也比较快找到容易出错的复杂程序码。
这是第一步,让我感受到不用 v-model
的好处。script
的 code 就变得,让我感觉不会杂杂的,简单程序码不会出现在这。
那今天我们就来使用bloc及flutter_bloc 这两个来实作范例,基本上我们在实作BLoC p...
全球个资保护如雨後春笋般的出现,各国对於个资保护的意识更加积极主动,且也陆续参考GDPR进行个资隐私...
上次练习了变数的宣告以及如何使用变数去做简单的相加 这次则是要用cin这个指令 结合过去所学到的做几...
一. 前言 词性标注 Part Of Speech(後面皆简称POS),简单来说就是将文章、句子中,...
我们在进到主题前先来看一段程序码,随後在开发人员工具中观察执行过程 function doSomet...