完成第一个 Vue3.2 项目后,使用体会

这篇具有很好参考价值的文章主要介绍了完成第一个 Vue3.2 项目后,使用体会。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

第一次Composition API

在vue3.2中,正式支持了script setup的写法,这样可以大大简化组件的代码量,减少一些重复操作,我认为当你写vue3时,应该把这当作默认写法。在vue3.2之前,一般会这样写。

<script>
   export default {
     setup(props,ctx){
      const a = ref(0)
      //必须return才能在template中使用,这里就存在一个重复操作的问题,每次都得cv,万一忘记就得检查
      return {
          a
      }
     }
   }
</script>

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


<script setup>
    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通信,而且可以把回调方法隐藏起来,我需要的只是结果,而不需要把所有代码都在外层。
当我写组件时,代码将更加简单

<template>
  <input v-model="id" />
  <button @click="handleClick">
    Action A
  </button>
</template>
<script setup>
  import useBridgeA from './useBridgeA'
  const {id,handleClick} = useBridgeA()
</script>

这里其实我也确立了一些我的vue3的写法吧。
组合不仅是功能点的组合,更是把一些关联性比较高的方法,变量放到一起。
在上面这个例子,其实我们可以把回调方法再抽离出来,放一个单独的文件中,我再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

<template>
  <p>123</p>
</template>
<style scoped>
  p{
    color:var(--pcolor)
  }
</style>

这样是纯粹的原生css的写法,vue帮我们做了一个hack.这里需要注意,style中的v-bind里面是一个字符串。

<template>
  <p>123</p>
</template>
<script setup>
  const pcolor = ref('#000')
</script>
<style scoped>
  p{
    color:v-bind('pcolor')
  }
</style>

但是我发现一个问题,在某些情况下的伪元素中的content属性似乎不生效,依旧是上面那个模板,我多写几个p

<template>
  <div>
    <p>123</p>
    <p>123</p>
    <p>123</p>
    <p>123</p>
  </div>
</template>
<script setup>
  const text = ref('hello')
</script>
<style scoped>
  div p:first-of-type:before{
    content:v-bind('text')
  }
</style>

这时候v-bind似乎没生效,这个伪元素不显示,也不知道是bug还是什么,这时候我建议你这样写

<template>
  <div>
    <p :data-text="text">123</p>
    <p>123</p>
    <p>123</p>
    <p>123</p>
  </div>
</template>
<script setup>
  const text = ref('hello')
</script>
<style scoped>
  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函数代替了,使用起来更灵活文章来源地址https://www.toymoban.com/news/detail-472085.html

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
})

到了这里,关于完成第一个 Vue3.2 项目后,使用体会的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • git第一次推送gitlab项目

    git第一次推送gitlab项目

    第一次本地项目提交git远程厂库 1、通过命令 git init 把这个目录变成git可以管理的仓库 2、把文件添加到本地暂缓区 3、commit提交到本地分支 4、去gitlib上拿到你项目的地址 5、切换main分支 6、提交远程仓库 提交步骤 1、首先你先通过git init git clone 基本环境准备好后,你写完自

    2024年02月02日
    浏览(11)
  • idea(第一次)启动项目,端口变成了8080

    idea(第一次)启动项目,端口变成了8080

    先上配置 该排查的问题也都没问题,重启idea也试过了,还是8080 解决办法:点击右侧的maven ,左上角的重新导入 reimport all maven projects  我又没有改动pom文件,居然还要点这里,也是很奇怪的报错。

    2024年02月07日
    浏览(18)
  • Git第一次初始化项目到远程仓库

    Git第一次初始化项目到远程仓库

    git init 命令用于初始化Git 仓库。git init之后会提示“Initialized empty Git repository in 某个目录”,此时就会在相应的目录下创建一个“.git”文件夹。这个文件夹里的文件就是git的实现。没有git init之前,git status会提示“not a git repository” git@gitee.com:flytalei/JavaEE-Basic.git 当本地新项

    2024年02月04日
    浏览(14)
  • Django项目第一次打开加载不出css文件

    Django项目第一次打开加载不出css文件

    你需要找到setting.py如下部分  修改你存放css文件和js等文件的目录 指定正确,本地就能跑了

    2024年02月10日
    浏览(11)
  • 当我第一次通过Kotlin和Compose来实现一个Canvas时, 我收获了什么?

    自从2019年Google推荐Kotlin为Android开发的首选语言以来已经经历了将近四年的时间, Compose的1.0版本也发布了将近2年的时间, Kotlin+Compose在现阶段的Android开发过程中还远远达不到主流的程度. 我们是否应该开始尝试这个组合? 这个组合有会给我们带来什么? 对于我来说, 我是个守旧又

    2023年04月27日
    浏览(13)
  • uniapp踩坑之项目:canvas第一次保存是空白图片

     在ctx.draw()回调生成图片,参考canvasToTempFilePath接口文档 上一篇文章, vue3+elementPlus:el-drawer新增修改弹窗复用_element plus drawer onclick outside 嵌套弹窗-CSDN博客 文章浏览阅读854次,点赞5次,收藏6次。vue3+elementPlus:el-drawer新增修改弹窗复用。在el-drawer的属性里设置:title属性,和

    2024年01月22日
    浏览(9)
  • git第一次拉取远程分支项目(ssh的方式)

    git第一次拉取远程分支项目(ssh的方式)

    一.生成SSH keys,并将生成的key复制到远程库 1.本地用命令生成密钥对。 ssh-keygen -t rsa -C \\\"yourEmailAddress\\\" 或 ssh-keygen -t ed25519 -C \\\"yourEmailAddress\\\" 按三次enter直接生成密钥对。 2.切换至ssh目录下,复制key(公钥)。 cd ~/.ssh more id_rsa.pub 3.登陆远程库,复制key到SSH Keys。 此处以github为例

    2024年02月16日
    浏览(18)
  • 手把手完成前端Vue3 + Vite项目工程化搭建

    基于 Vue3 + Vite 搭建的前端工程化项目演示模板 开发环境: Node.js v16.14.2 + npm v8.3.2 开发工具: Visual Studio Code or WebStorm 源代码管理: Git npm镜像: npm config set registry https://registry.npmmirror.com 技术栈 描述 Vue 渐进式 JavaScript 框架 Vite 新一代前端开发与构建工具 Element Plus 基于 Vue

    2024年04月11日
    浏览(17)
  • 【UE5】第一次尝试项目转插件(Plugin)的时候,无法编译

    【UE5】第一次尝试项目转插件(Plugin)的时候,无法编译

    VS显示100条左右的错误,UE热编译也不能通过。原因可能是[名字.Build.cs]文件的错误,缺少一些内容,比如说如果要写UserWidget类,那么就要在 ]名字.Build.cs] 中加入如下内容: 根据你的文件进行添加。如果说依然有如图的问题,那你就去原来的项目里看看哪些没加上去。 正在创

    2024年01月22日
    浏览(64)
  • 给出一个包含n个整数的数列,问整数a在数列中的第一次出现是第几个。

    输入 第一行包含一个整数 n 。 第二行包含 n 个非负整数,为给定的数列,数列中的每个数都不大于 10000 。 第三行包含一个整数 a ,为待查找的数。 输出 如果 a 在数列中出现了,输出它第一次出现的位置(位置从 1 开始编号),否则输出 -1 。 测试说明 样例输入: 6 1 9 4 8 3

    2024年02月04日
    浏览(18)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包