当前位置: 首页 > 科技观察

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

时间:2023-03-22 14:06:06 科技观察

p{color:var(--pcolor)}完成第一个Vue3.2项目后,这是我的技术总结,写vue3的时候,应该默认这个。在vue3.2之前,一般都是这样写的。那么现在,我们可以这样写了,对比一下到底减少了多少行代码。PS:以下代码我省略了scriptsetup,默认都在scriptsetup标签下。你可能觉得这样更简单,但事实上恰恰相反,CompositionAPI其实需要你对逻辑处理有更清晰的认识,对封装的要求也更高,否则,你会写出比以前更丑陋的代码。例如:consta=ref(0)constb=ref('')constc=ref(true)constd=reactive({})constactionA=()=>{a.value++}constactionC=()=>{c.value=!c.value}constactionB=()=>{b.value+='test'}constactiond=async()=>{constres=awaitajax(`url`)d.a=res.ad.b=res.bd.c=res.c}constresetD=()=>{Object.keys(d).forEach(key=>deleted[key])}这一堆代码其实是当你不考虑一下Logic,我从来没有想过封装的时候直接写成日记一样的代码,这些代码真的比optionsApi更易读吗,当然不是。这里就更加扑朔迷离了。你很难一眼看出某个函数使用了哪个变量,而且顺序很乱。这时候就需要封装和组合,这也是CompositionAPI的意义之一。//usePage.jsexportdefault()=>{consta=ref(0)constb=ref('')constc=ref(true)constactionA=()=>{a.value++}constactionC=()=>{c.value=!c.value}constactionB=()=>{b.value+='test'}//这时候需要写returnreturn{a,actionA,b,actionB,c,actionC}}//usePageD.jsexportdefault()=>{constd=reactive({})constactionD=async()=>{constres=awaitajax(`url`)d.a=res.ad.b=res.bd.c=res.c}constresetD=()=>{Object.keys(d).forEach(key=>deleted[key])}return{d,actionD,resetD}}此时,当我们在不同的组件中使用时,我们可以按需使用,假设我们现在有两个组件A和D://ComponentAimportusePagefrom'./usePage'const{a,actionA}=usePage()//Component从'./usePageD'const{actionD,resetD}=usePageD()上面两种很自然的打包组合起来,方便阅读。更方便的是,他有一个更有趣的用法。我现在的项目是iOS混合开发,使用jsBridge是必不可少的。由于iOS的原生限制,所有的回调都是通过其他函数接收的。例如下面是我调用原生A方法时的代码://jsBridge.jsconstcallBridge=(msg)=>{try{window.webkit.xxxHandler.postMessage(msg)}catch(e){console.log(msg)}}exportconstbridgeA=(id,cb='')=>{constmsg={func:'A',params:{id},cb}callBridge(msg)}本地会告诉我结果(这块是伪代码,毕竟我不会用iOS)evaluateJavaScript(cb(data))当我用这个逻辑的时候。//App.vueconststore=useStore()window.test=function(data){store.commit('saveA',data)}//consthandleClickinothercomponents=()=>{bridgeA('123','test')}而现在,我不需要通过vuex,这样写不是很好吗?//useBridgeA.jsexportdefault()=>{constid=ref('')constsaved=reactive({})window.test=function(data){save.data=data}consthandleClick=()=>{bridgeA('123','test')}onBeforeUnmount(()=>{window.test=null})return{saved,handleClick,id}}最好的是回调在使用的时候注册,当没有使用Remove,通过reactive通信,隐藏回调方法。我只需要结果,无需将所有代码放在外层。当我编写组件时,代码会更简单。其实我这里也建立了一些我的vue3写法。组合不仅是功能点的组合,而且是相关性高的方法和变量的组合。上面的例子,其实我们可以把回调方法再抽出来,放在一个单独的文件中,然后导入,但是这样只会让工程文件越来越多,每次要查找的文件也越来越多和更多。在考虑设置时,很少有人会想到为什么这个新的生命周期被称为设置。设置意味着建立。这是否意味着仅在创建应用程序时?然后创建显然更好理解。在我看来,setup是一个纽带,一个连接数据和模板的桥梁,所以用了这个动词。从本质上讲,这不是一个生命周期,而是一个动作。我们连接数据和Vue。我把你做的webApp比作一台机器,设置就像一根电源线。你用你的变量和逻辑作为动力,把它输入电源线,机器就启动了。最常见的问题是忘记写.value。其实在vue3中,我更喜欢用ref。ref结构简单,响应更可靠方便。比如当我们需要声明一个响应式对象时,可以有这两种写法。consta=shallowRef({})constb=reactive({})但是当你需要替换整个对象时怎么办?对于变量,直接修改值即可。a.value={c:1}对于变量b,会比较麻烦。如果你的对象层次结构比较简单,我能想到的方法是使用Object.assignObject.assign(b,{c:1})如果你只是删除变量a的属性c就很简单了。a.value={}对于变量b,使用reactive的显然比较麻烦。b=reactive({})//报错能不能直接这样写,不行,会报错,因为b是const。所以,你简单想想,把const改成letletb=reactive({})b.c=1b=reactive({})理论上是没有问题的,没有其他依赖b或者它依赖其他变量的时候。在某种程度上,这也失去了响应能力。你只能这样做,这也是我之前写reset的原因。deleteb.c//假设变量b中有很多属性,需要遍历Object.keys(b).forEach(key=>deleteb[key])这些其实是一些容易被忽略的点,这就是为什么我更喜欢推荐ref的原因,但是有利也有弊。ref最大的问题就是容易忘记写。valueconsta=ref(0)a=1//报错//判断的时候if(a){//一直为真,因为a是对象,不是数字}这个时候推荐大家使用unref,上面的if判断应该这样写。consta=ref(0)if(unref(a)>0){//dosth}else{//doanother}可以毫无精神负担地使用unref,即使这个变量不是refstylev的优缺点-bind很多人可能对v-bind风格不熟悉。我将其称为vue对css变量的hack。我还在我的项目中使用了一些css变量。具体的css变量教程可以看这个链接www.ruanyifeng.com/blog/2017/0...[1]p{color:var(--pcolor)}这个是纯原生的css写法,vue给我们做了hack。这里要注意,style中的v-bind是一个字符串。p{color:v-bind('pcolor')}但是我发现了一个问题。在某些情况下,伪元素中的内容属性似乎没有生效。还是上面那个模板。我再写几个p>divp:first-of-type:before{content:v-bind('text')}在这次v-bind好像没有生效,这个伪元素没有显示出来,也不知道是不是Bug什么的,这时候建议你这样写。divp:first-of-type:before{content:attr(data-text)}pinia还是notpinia约等于vuex5,使用方式和vuex略有不同,我在项目中是这样使用的。//在store/user.js中定义具体的storeexportconstUserStore=defineStore('user',{state:()=>({name:'',id:''})getters:{nameId:state=>`${state.name}_${state.id}`}actions:{asyncgetUserInfo(){}}})//store/index.js//这样写的好处是可以直接从'@/store',当文件过多时,可以使用webpack的require.context或者vite的importblob自动处理export{UserStore}from'./user',比vuex少一个mutation,不能说没有,只是用$patch函数代替,使用起来更灵活。importUserStorefrom'@/store'constuser=UserStore()user.name='test'//oruser.$patch({name:'test',id:123})//oruser.$patch(state=>{state.name='test'state.id=123})问题是在js环境下,Webstorm好像没有代码提示?