您现在的位置是:亿华云 > 系统运维

完成第一个 Vue3.2 项目后,这是我的技术总结

亿华云2025-10-03 18:19:37【系统运维】9人已围观

简介第一次Composition API我认为当你写vue3时,应该把这当作默认写法。在vue3.2之前,一般会这样写。export default {setup(props,ctx){const a =

第一次Composition API

我认为当你写vue3时,完成应该把这当作默认写法。第个的技在vue3.2之前,目后一般会这样写。术总

export default {

setup(props,完成ctx){

const a = ref(0)

//必须return才能在template中使用,这里就存在一个重复操作的第个的技问题,每次都得cv,目后万一忘记就得检查

return {

a

}

}

}

</script>

那么现在,我们可以这样写,术总对比一下,减少了多少行代码呢?完成

const a = ref(0)

</script>

PS:之后的代码我会省略script setup,默认都在script setup标签下。第个的技

也许你会觉得这样就更简单了,目后其实恰恰相反,术总CompositionAPI其实要求你对逻辑处理有更清晰的完成认识,对于封装有更高的第个的技要求,否则,目后你一样会写成比以前更丑的代码。例如:

const a = ref(0)

const b = ref()

const c = ref(true)

const d = reactive({ })

const actionA = ()=>{ a.value++}

const actionC = ()=>{ c.value=!c.value}

const actionB = ()=>{ b.value += test }

const actiond = async ( )=> {

const res = await ajax(`url`)

d.a = res.a

d.b = res.b

d.c = res.c

}

const resetD = ()=>{

Object.keys(d).forEach(key=>delete d[key])

}

这一堆代码其实就是当你没有考虑逻辑,没有想过封装的时候,像流水账一样直接写出来的代码,这些代码真的比optionsApi更好阅读吗,当然不。源码下载

这里更加混乱,你很难一眼看出某个函数用的是哪个变量,顺序混乱,这时候需要封装,需要组合,这也是CompositionAPI的含义之一。

//usePage.js

export default ()=>{

const a = ref(0)

const b = ref()

const c = ref(true)

const actionA = ()=>{ a.value++}

const actionC = ()=>{ c.value=!c.value}

const actionB = ()=>{ b.value += test }

//这时候需要写return

return {

a,actionA,

b,actionB,

c,actionC

}

}

// usePageD.js

export default ()=>{

const d = reactive({ })

const actionD = async ( )=> {

const res = await ajax(`url`)

d.a = res.a

d.b = res.b

d.c = res.c

}

const resetD = ()=>{

Object.keys(d).forEach(key=>delete d[key])

}

return {

d,actionD,resetD

}

}

这时候,当我们在不同的组件中使用时,我们可以按需使用,假设我们现在有A和D两个组件。

//组件A

import usePage from ./usePage

const { a,actionA} = usePage()

//组件D

import usePage from ./usePageD

const { actionD,resetD} = usePageD()

上述两种,自然时封装组合后更好阅读。更方便的是,他有更好玩的用法。我目前这个项目是一个iOS混合开发的,这其中必不可少的需要用的jsBridge,由于iOS原生的限制,所有回调都是通过其他函数接收的。源码库例如,下方是我调取原生A方法时的代码。

//jsBridge.js

const callBridge = (msg)=>{

try {

window.webkit.xxxHandler.postMessage(msg)

}catch(e){

console.log(msg)

}

}

export const bridgeA = (id,cb=)=>{

const msg = {

func:A,

params:{ id},

cb

}

callBridge(msg)

}

而原生则会这样告诉我结果(这块是伪代码,毕竟我不会iOS)。

evaluateJavaScript(cb(data))

当我使用的时候,就会有这种逻辑。

//App.vue

const store = useStore()

window.test = function(data){

store.commit(saveA,data)

}

//其他组件中

const handleClick = ()=>{

bridgeA(123,test)

}

而现在,我可以不需要通过vuex了,这样写不香吗?

//useBridgeA.js

export default ()=>{

const id = ref()

const saved = reactive({ })

window.test = function(data){

saved.data = data

}

const handleClick = ()=>{

bridgeA(123,test)

}

onBeforeUnmount(()=>{ window.test = null})

return { saved,handleClick,id}

}

最妙的是,这里实现当使用时注册回调,不使用时移除,通过reactive通信,而且可以把回调方法隐藏起来,我需要的只是结果,而不需要把所有代码都在外层。

当我写组件时,代码将更加简单。

Action A

import useBridgeA from ./useBridgeA

const { id,handleClick} = useBridgeA()

</script>

这里其实我也确立了一些我的vue3的写法吧。

组合不仅是功能点的组合,更是把一些关联性比较高的方法,变量放到一起。云南idc服务商

在上面这个例子,其实我们可以把回调方法再抽离出来,放一个单独的文件中,我再import,但是这样只会让项目文件越来越多,每次查找的文件越来越多罢了。

思考setup

很少有人会去想,为什么这个新的生命周期叫setup,set up 有建立的意思,难道意思仅仅是这个App创建时吗,那么created显然更好理解一些。

我认为,setup是一个链接,是把数据和template连接起来的一个桥梁,因此才会使用这个动词,本质上这不是一个生命周期,是一个动作,是我们把数据和Vue连接起来。

我把你做的webApp比作一台机器,setup就好比电源线,你把你变量,逻辑作为电源,输入到电源线,机器就启动了。

最常见的问题,忘记写.value

其实在vue3中,我更喜欢用ref,ref结构简单,有着更可靠更方便的响应式。例如,当我们需要声明一个响应式的对象时,你可以有这两种写法

const a = shallowRef({ })

const b = reactive({ })

但是,当你需要替换整个对象时怎么办?对于变量来说,直接修改value即可。

a.value = { c:1}

对于变量b,那就麻烦了,如果你的对象层级比较简单,我能想到的方法就是用Object.assign

Object.assign(b,{ c:1})

如果只是删除这个c这属性,对于变量a,很简单。

a.value = { }

对于变量b呢,使用了reactive的那个呢,显然更加麻烦。

b=reactive({ }) // 报错

能直接这样写吗,不行,这样会报错,因为b是一个const。于是乎,你简单的思考一下,把const 改为let

let b = reactive({ })

b.c = 1

b = reactive({ })

理论上这样没有问题,在b没有别的依赖或者是被别的变量依赖的时候。某种程度上讲,这样也会丢失响应性。你只能这样做,这也是我之前为什么要写reset的原因。

delete b.c

//假设b这个变量中有很多属性,则需要遍历

Object.keys(b).forEach(key=>delete b[key])

上面这些其实都是一些容易被忽略的点,也是我为什么更推荐ref的原因,但是有利有弊,ref最大的问题是容易忘记写.value

const a = ref(0)

a=1 //报错

//做判断的时候

if(a){ //永远为true,因为a是一个对象,不是数字}

这时候,我推荐你使用unref,上面的if判断应该这样写。

const a = ref(0)

if(unref(a)>0){

// do sth

} else {

// do another

}

你可以毫无心智负担的使用unref,哪怕这个变量不是ref

style v-bind 的优缺点

style v-bind可能很多人不熟悉,我把这称之为vue对css变量的hack。我项目中偶也也会使用一些css变量。

具体的css变量的教程,大家可以看一下这个链接www.ruanyifeng.com/blog/2017/05/css-variables.html

123

div p:first-of-type:before{

content:attr(data-text)

}

</style>

pinia or not

pinia约等于vuex5,使用起来和vuex稍有不同,我在项目中是这样使用的。

// store/user.js中定义具体的store

export const UserStore = defineStore(user, {

state:()=>({

name:,

id:

})

getters:{

nameId:state=>`${ state.name}_${ state.id}`

}

actions:{

async getUserInfo(){ }

}

})

//store/index.js

//这样写的好处是,以后引用的时候可以直接from @/store,并且当文件多了,可以用通过webpack的require.context或者vite的import blob来自动处理

export { UserStore} from ./user

比vuex来说少了一个mutation,也不能说没有,只是用$patch函数代替了,使用起来更灵活。

import UserStore from @/store

const user = UserStore()

user.name = test

//or

user.$patch({

name:test,

id:123

})

//or

user.$patch(state =>{

state.name = test

state.id = 123

})

问题是在js环境下,Webstorm似乎没有代码提示?

完全升级你的项目依赖吧

既然都已经使用vue3了,意味着你本来就不再去兼容ie8,ie9这些,什么你可以把你的依赖完成升级到es8,es9,毫无保留的使用fetch、?. 、?? 这些最新的语法,获取更好的编程体验。

很赞哦!(8771)