该系列是为了让看过Vue官方文件或学过Vue但是却不知道怎麽下手去重构现在有的网站而去规画的系列文章,在这边整理了许多我自己使用Vue重构很多网站的经验分享给读者们。
我常常在重构专案的时候会看到前人写的一些关於 vue 的 code 让人摸不着头绪,以及满头问号的情况,今天我将把一些我常常看到觉得不必要的写法以及可以改善的 code 做个比较,让大家在写 code 的时候可以多多注意不要写出让人满头问号的程序码。
这是我在很多专案常见到的 methods 的写法
// option api style from vue-cli
methods: {
init: function() {
let that = this;
axios.get("https://test.api/data").then(function(res){
that.resVal = res.data
})
}
}
这个写法不能说不能 work,只不过不是最理想的写法,首先
在 Vue cli 里面写 methods 的时候,就可以采用 es6 写法去掉:function()
直接 init()
就好。
使用其他第三方工具的时候,call back function 应该使用 ES6 的箭头函式 ( arrow function ),使用箭头函式就不需要去外面宣告一个 that 塞入this ,因为箭头函示内部是没有 this 的指向,所以会往外部查找,就会直接指向 Vue。
// option api style from vue-cli
methods: {
init() {
axios.get("https://test.api/data").then((res)=>{
this.resVal = res.data
})
}
}
天阿!太多人分不清楚什麽时候应该用 let
还是 const
,所以乾脆一律 let
到底,我们来看一下什麽东西应该let
什麽应该 const
。
methods: {
loginUser (){
let url = "/api/login";
let postData = {
name: this.name,
password: this.password,
phone: this.phone,
};
axios.post(url, postData).then((res)=> {
console.log("login success");
})
}
}
这是一个很简单的使用 API post 来进行登入的 function,你会看到这边的 url 还有要 post 出去的 data 都是使用let 进行宣告,我们来分析一下,首先 let 除了是以大括号为界,具有scoped
的效果,也具有可以修改的特性,你可以随意地修改它里面的 value ,例如下面这种操作都是可以的
let a = 1;
console.log(a);
a = "mike"
console.log(a);
但是我们有些变数是不需要被修改的,例如我们的范例一样,我们的 url 就是一个 API 的路径,它是不会被修改的,所以这边我们就应该用 const
来宣告,而不是 let
,我们的 postData 其实也是一样的,它是最後将所需要的值给组合起来 post 出去的,所以他也应该用 const
。
const url = "/api/login";
const postData = {
name: this.name,
password: this.password,
phone: this.phone,
};
关於 let 跟 const 的更多差异我相信网路上已经有很多这类的比较资料,这边我就不再多做赘述。
这边附上 MDN 的文件,还不了解的可以看一下。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#declarations
我看过好多人在写 Component 的时候 props 都这样写,直接用一个 Array 包起来这样
<script>
export default {
props: ["usertype", "handleOpenNav", 'count'],
...
}
</script>
但是我们可以看到 Vue 官方的 style guide 上面有明确的讲说这样是你在一开始设计 component 的时候用,当你的资料类型都确定完成後,要改成以下写法。
<script>
export default {
props: {
usertype: {
type: String
},
handleOpenNav: {
type: Function
},
count: {
type: Number
}
},
...
}
</script>
这样我们就可以去定义我们传入的 props 的类型,也可以一眼就知道这个传入的 props 类型是什麽,即便传错了类型的参数,log 也会报错跟你说参数传入错误了。
props style guide
https://v3.vuejs.org/style-guide/#prop-definitions-essential
然後我最推荐的写法是除了加上 type 以外,还加入了 default 的处理 props 的方式。
<script>
export default {
props: {
usertype: {
type: String,
default: "default"
},
handleOpenNav: {
type: Function,
default: ()=> {}
},
count: {
type: Number,
default: 0
}
},
...
}
</script>
你可以看到我给了每一个 props 一个 default value,如果今天我没有传入的 props,它就会当成你 default 设定的那个 value 来使用,这样可以避免掉很多如果你没有传入参数的时候,也可以透过这种方式来处理画面上面的状态,让它有预设的 status。
https://v3.vuejs.org/style-guide/#empty-lines-in-component-instance-options-recommended
这边我列几个很容易写错了的 props default 给大家参考
<script>
export default {
props: {
handleOpenNav: {
type: Function,
default: ()=> {}
},
userList: {
type: Array,
default: ()=> ([])
},
fetchData: {
type: Object,
default: ()=> ({})
},
},
...
}
</script>
最常看到写错的就是 Function
、Array
、Object
这三个 type,你仔细看 Function
、Array
都是需要透过函式的方式去回传,而不是直接定义一个空的 []
或是 {}
,这点要特别注意。
关於 props 定义的部分可以看这份文件
https://v3.vuejs.org/guide/component-props.html#prop-validation
我们很常会搞不清楚什麽时候应该用 Computed 什麽时候应该用 Methods 来处理资料的回传,我们先来看一下Computed 的部分,在我们前一篇的文章有提到
computed 是一个计算属性,设计它的初衷是用於简单运算的,在模板中放入太多的逻辑会让模板过重且难以维护,所以会需要透过computed 来重新处理过那些复杂的资料,官方文件有提到说
computed 属性是基於Vue绑定的资料依赖关系缓存的
这意味者 computed 只在透过Vue绑定的资料发生改变时它们才会重新去执行处理计算,所以今天你的资料只要是Vue绑定的资料,都可以被计算处理过。
我们来看以下例子
<script>
export default {
props: {
showType: {
type: String,
default: 'not_login',
},
},
setup(props) {
const isShowBtnStatus = () => props.showType === "not_login";
return { isShowBtnStatus };
},
};
</script>
<template>
<a v-if="isShowBtnStatus()">登入</a>
<a v-if="!isShowBtnStatus()">登出</a>
<a v-if="!isShowBtnStatus()">观看纪录</a>
</template>
我们可以看到这边 isShowBtnStatus 这个 methods去判断我的 props,然後在 template 的地方去call 这个 methods,让它回传状态,但其实我们应该要改成使用 computed 才对
<script>
import { computed } from "vue";
export default {
props: {
showType: {
type: String,
default: 'not_login',
},
},
setup(props) {
const isShowBtnStatus = computed(() => props.showType === "not_login");
return { isShowBtnStatus };
},
};
</script>
<template>
<a v-if="isShowBtnStatus">登入</a>
<a v-if="!isShowBtnStatus">登出</a>
<a v-if="!isShowBtnStatus">观看纪录</a>
</template>
透过 computed 的方式可以让资料达到缓存的效果,资料没变就不会重新计算,除非今天你是要传参数进去做计算,才需要选择 methods 来return value.不然的话大部分的计算需求使用 computed 是比较恰当的!
很多在刚开始升级 Vue3 的朋友会因为还不习惯使用 composition api 而写出以下的 code
import { ref } from 'vue'
export default {
props: {
user: {
type: String,
required: true
}
},
data () {
return {
filters: {},
searchQuery: ''
}
},
setup (props) {
const repositories = ref([])
const handleLog = () => {
console.log("use")
}
return {
repositories,
handleLog
}
},
watch: {
searchQuery(){ ... }
},
mounted () {
this.handleLog()
}
}
你会发现这边把 Composition Api 跟 Option Api 给混再一起,变得很奇怪,定义data的地方变成了两个,使用 methods 的时候一下在Option Api 里面要使用 this 但是在 setup 里面又不用,整个变得难以阅读且凌乱,在使用 Composition Api 的时候就可以全部解决这样的问题。
import { ref, reactive, watch, onMounted } from 'vue'
export default {
props: {
user: {
type: String,
required: true
}
},
setup (props) {
const repositories = ref([])
const searchQuery = ref("")
const filters = reactive({})
const handleLog = () => {
console.log("use")
}
watch(searchQuery, (newVal)=> {
console.log("newVal=>", newVal)
})
onMounted(()=> {
handleLog()
})
return {
repositories,
handleLog
}
}
}
你看我把原本 Option Api 的部分全部改成 Composition Api 是不是清爽许多,官方也是建议 Composition Api 跟 Option Api 则一选择就好,不推荐两种写法混用,导致你的 code 看起来很混乱。
更多关於 Composition Api 的内容
https://v3.vuejs.org/guide/composition-api-introduction.html#introduction
好啦!今天就到这边啦~明天见!
Ps. 购买的时候请登入或注册该平台的会员,然後再使用下面连结进入网站点击「立即购课」,这样才可以让我获得更多的课程分润,还可以帮助我完成更多丰富的内容给各位。
我有开设了一堂专门针对Vue3从零开始教学的课程,如果你觉得不错的话,可以购买我课程来学习
https://hiskio.com/bundles/9WwPNYRpz?s=tc
那如果对於JS基础不熟的朋友,我也有开设JS的入门课程,可以参考这个课程
https://hiskio.com/bundles/b9Rovqy7z?s=tc
Mike 的 Youtube 频道
Mike的medium
MIke 的官方 line 帐号,好友搜寻 @mike_cheng
>>: Day 09:「啊~不要碰我!我会变色~」- 变化模式 (Variants)
https://plan.seek.intel.com/TW_ICX_Event-REG?track...
过去统计数 CISSP Member Counts as of July 1, 2020 ISC2...
由於 Figma 的核心是 GUI 设计工具,附带原型制作能力,所以一般来说我们都会使用它来进行高精...
这次要来建立一个我说甚麽你跟着说的机器人。 你需要从刚刚申请的LINE帐号中拿两个东西跟你的程序码做...
图片在网页里是不可或缺的元素,可以增加网站的丰富度及美感,但是也可能造成网站花太多时间载入,使用者体...