Vue3 + TypeScript 开发实践总结

海军
• 阅读 1612

Vue3 + TypeScript 开发实践总结

前言

迟来的Vue3文章,其实早在今年3月份时就把Vue3过了一遍。
在去年年末又把 TypeScript 重新学了一遍,为了上Vue3 的车,更好的开车。
在上家公司4月份时,上级领导分配了一个内部的 党务系统开发 ,这个系统前端是由我一个人来开发,功能和需求也不怎么复杂的一个B 端 系统,直接上的 Vue3 + TypeScript + Element Plus 开发的,开发两周到最后的上线,期间也遇到很多小坑,很多无处可查,慢慢琢磨最后还是克服了。

Vue3 + TypeScript Study

Vue3 + TypeScript 开发实践总结

一, 环境配置

1.1 安装最新 Vue 脚手架

npm install -g @vue/cli

yarn global add @vue/cli

1.2 创建Vue3 项目

vue create projectName

1.3 现有Vue 2 项目 升级到 Vue3

vue add typescript

二, 进击Vue3

2. 1 Vue 2 局限性

  1. 随着组件与组件依赖之间不断变大,组件很难读取和维护

  2. 没有完美的方法解决跨组件代码重用

2.2 Vue 3 如何解决Vue 2 局限

  1. 组件难以维护管理

【在Vue3 中 编写组合函数,使用 Compositon Api setUp 来解决】

  1. 没有完美的方法解决跨组件代码重用

三,Vue3 Composition Ap i

3.1 关于 Composition Api

在Vue3中,也可以不使用 Composition Api 来编写组件,它只是在Vue3 中编写组件中的另一种方法,内部简化了好多操作。

所以你还可以继续使用 Vue2 的方式来 编写 组件。

3.2 什么时候使用Composition Api

  1. TypeScript` 的支持

  2. 编写大型组件时,可以使用 Composition Api 组合函数很好的管理状态

  3. 跨组件重用代码时

四,Composition Api 必备基础

4.1 什么是 setup

setup 是用来配置组件状态的另一种实现。

在setup 中定义的状态,方法要想在模板中使用,必须 return

注意:

  • setup 方法是在 components , props data Methods Computed Lifecycle methods 之前执行
  • 同时在 setup 中是不能访问 this

4.2 ref 创建响应式变量

Vue2 中,我们定义一个响应式变量可以直接在 data 中 定义并且在模板中使用该变量。 如果 使用的 composition api 的话,我们得在 setup 中 使用 ref 来创建 响应式变量,并且得将它返回,才能在页面中使用。

使用

    1. 引入 ref import { ref } from 'vue'
    1. 初始变量 const name = ref('指定默认值')
    1. 返回变量 return { name } 在return中还可以返回方法
    1. setup 中 访问 定义的变量值,不能直接通过变量名来获取,必须通过 变量名.value 来获取到该对象 、 值

这样的好处

  • 状态好管理,可以划分好几个 setup 状态管理,最后在一个 文件导入所有,并且使用。
<template>
    <div>
        <h1>{{title}}</h1>
    </div>
</template>

<script>
import {ref,defineComponent} from 'vue'
export default defineComponent({
    setup () {
        // 定义响应式变量
        const title = ref('前端自学社区')

          // 访问该变量
        console.log(title.value)
        // 返回变量
        return {title}
    }
})
</script>

4.3 生命周期

Composition Api生命周期钩子 和 Vue 2 选项式 生命周期钩子名称一样,只是在使用 组合式API时,前缀为 on, onMounted`

sd

下面代码中有两个 mounted 生命钩子,你猜哪个会先执行?

setup 会先执行

    setup () {
        // 定义响应式变量
        const title = ref('前端自学社区')
        console.log(title)
        // 返回变量
        function getTitle(){
            console.log(title.value)
        }
        // 页面在加载
        onMounted(getTitle)
        return {title}
    },
    mounted() {
        console.log('测试 mounted 执行顺序')
    },

4.4 watch

setup 中使用 watch响应式更改

  • 引入 watch, import { watch } from 'vue'

  • 直接使用watch,watch 接受 3 个参数

    1. 要监听更新的 响应式引用或者 getter 函数
    2. 一个回调用来做更新后的操作
    3. 可选配置项
import {wathc} from 'vue'

// 定义响应式变量
const num = ref(0)
// 更新响应式变量
function  changeNum(){
            num.value++
}

// wathc 监听响应式变量
watch(
 num,(newValue, oldValue) => {
 console.log(`newValue为:${newValue},--------oldValue为:${oldValue}`)
   }
 )

4.5 computed

它也是 从 vue 导入,computed 函数返回一个作为 computed 的第一个参数传递的 getter 类回调的输出的一个只读响应式引用。为了访问新创建的计算变量的 value,我们需要像使用 ref 一样使用 .value property。

*当num值变化时,nums 的值会 *3 *

import {ref,computed} from 'vue';

const num = ref(0)

//更新num
function  changeNum(){
   num.value++
 }
//监听num变化
 const nums = computed(() =>{
  return num.value * 3
 })

五,setup

5.1 接受两个参数

props: 父组件传递过来的属性, setup` 函数中 props 是响应式的,它会随着数据更新而更新,并且不能使用 ES6 解构,因为它会不能使 props 为响应式。

context : 它是一个普通的 对象,它暴露3个组件的· property

  1. Attribute
  2. 插槽
  3. 触发事件

context 不是 响应式的,所以可以使用ES6 解构来简便写法。

   props:{
        obj:{
            type:Object
        }
    },
     setup (props,{attrs,slots,emit}) {
            console.log(attrs)
            console.log(slots)
            console.log(emit)
             console.log(props.obj)
     }

5.2 组件加载 setup 时注意

在组件执行 setup 时, 组件实例没有被创建,因此就无法访问以下属性

  • data
  • computed
  • methods

六,生命周期

setup 中使用 生命周期时,前缀必须加 on.

选项式 API Hook inside setup
beforeCreate
created
beforeMount onBeforeMount
mounted onMounted
beforeUpdate onBeforeUpdate
updated onUpdated
beforeUnmount onBeforeUnmount
unmounted onUnmounted
errorCaptured onErrorCaptured
renderTracked onRenderTracked
renderTriggered onRenderTriggered

七, 跨组件之间传值

Vue 2 中,我们可以使用 Provide/Inject 跨组件传值,在 Vue 3 中也可以。

setup 中 使用,必须从 vue 中导入使用。

使用 Provide 时,一般设置为 响应式更新的,这样的话,父组件变更,子组件,子孙组件也跟着更新。

怎么设置为响应式更新呢?

  1. 使用 ref / reactive 创建响应式变量
  2. 使用 provide('name', '要传递的响应式变量')
  3. 最后添加一个更新 响应式变量的事件,这样响应式变量更新,provide 中的变量也跟着更新。

父组件

父组件
import { provide, defineComponent, ref, reactive } from "vue";

<template>

  <Son/>

</template>


<script>
    import { provide, defineComponent, ref, reactive } from "vue";
    export default defineComponent({
    setup() {
            const father = ref("我父组件");
    const info = reactive({
      id: 23,
      message: "前端自学社区",
    });
    function changeProvide(){
      info.message = '测试'
    }
    provide('father',father)
    provide('info',info)
    return {changeProvide};
    }

})
</script>

子组件

<template>
    <div>
        <h1>{{info.message}}</h1>
        <h1>{{fatherData}}</h1>
    </div>
</template>

<script>
import {provide, defineComponent,ref,reactive, inject} from 'vue'
export default defineComponent({
    setup () {
        const fatherData = inject('father')
        const info = inject('info')

        return {fatherData,info}
    }
})
</script>

八, 在Vue 中 使用 TypeScirpt 技巧

8.1 接口约束约束属性

采用 TypeScirpt 的特性, 类型断言 + 接口 完美的对 属性进行了 约束

interface
分页查询 字段属性类型验证
export default  interface queryType{
    page: Number,
    size: Number,
    name: String,
    age:  Number
}
组件中使用
import queryType from '../interface/Home'


    data() {
        return {
            query:{
                page:0,
                size:10,
                name:'测试',
                age: 2
            } as queryType
        }
    },

8.2 组件使用 来 defineComponent 定义

这样 TypeScript 正确推断 Vue 组件选项中的类型

import { defineComponent } from 'vue'

export default defineComponent({
    setup(){
        return{ }
    }
})

8.3 类型声明 reactive

export default  interface Product {
    name:String,
    price:Number,
    address:String
}



import  Product from '@/interface/Product' 
import {reactive} from 'vue'
const product = reactive({name:'xiaomi 11',price:5999,address:'北京'}) as Product

return {fatherData,info,product}

精选文章

1. Vue权限路由[菜单权限/按钮权限控制]
2. Vue | 路由守卫面试常考
3. Vue 组件通信的 8 种方式
4. Vue中Axios的封装管理
5. 【查缺补漏】 15个高频微信小程序面试题

更多精彩文章在微信公众号 Vue3 + TypeScript 开发实践总结

最后

文中如有错误,欢迎码友在评论区指正,如果对你有所帮助,欢迎点赞和关注~

点赞
收藏
评论区
推荐文章
秃头王路飞 秃头王路飞
4个月前
webpack5手撸vue2脚手架
webpack5手撸vue相信工作个12年的小伙伴们在面试的时候多多少少怕被问到关于webpack方面的知识,本菜鸟最近闲来无事,就尝试了手撸了下vue2的脚手架,第一次发帖实在是没有经验,望海涵。languageJavaScript"name":"vuecliversion2","version":"1.0.0","desc
浅梦一笑 浅梦一笑
4个月前
初学 Python 需要安装哪些软件?超级实用,小白必看!
编程这个东西是真的奇妙。对于懂得的人来说,会觉得这个工具是多么的好用、有趣,而对于小白来说,就如同大山一样。其实这个都可以理解,大家都是这样过来的。那么接下来就说一下python相关的东西吧,并说一下我对编程的理解。本人也是小白一名,如有不对的地方,还请各位大神指出01名词解释:如果在编程方面接触的比较少,那么对于软件这一块,有几个名词一定要了解,比如开发环
技术小男生 技术小男生
4个月前
linux环境jdk环境变量配置
1:编辑系统配置文件vi/etc/profile2:按字母键i进入编辑模式,在最底部添加内容:JAVAHOME/opt/jdk1.8.0152CLASSPATH.:$JAVAHOME/lib/dt.jar:$JAVAHOME/lib/tools.jarPATH$JAVAHOME/bin:$PATH3:生效配置
光头强的博客 光头强的博客
4个月前
Java面向对象试题
1、请创建一个Animal动物类,要求有方法eat()方法,方法输出一条语句“吃东西”。创建一个接口A,接口里有一个抽象方法fly()。创建一个Bird类继承Animal类并实现接口A里的方法输出一条有语句“鸟儿飞翔”,重写eat()方法输出一条语句“鸟儿吃虫”。在Test类中向上转型创建b对象,调用eat方法。然后向下转型调用eat()方
刚刚好 刚刚好
4个月前
css问题
1、在IOS中图片不显示(给图片加了圆角或者img没有父级)<div<imgsrc""/</divdiv{width:20px;height:20px;borderradius:20px;overflow:h
blmius blmius
1年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
小森森 小森森
4个月前
校园表白墙微信小程序V1.0 SayLove -基于微信云开发-一键快速搭建,开箱即用
后续会继续更新,敬请期待2.0全新版本欢迎添加左边的微信一起探讨!项目地址:(https://www.aliyun.com/activity/daily/bestoffer?userCodesskuuw5n)\2.Bug修复更新日历2.情侣脸功能大家不要使用了,现在阿里云的接口已经要收费了(土豪请随意),\\和注意
晴空闲云 晴空闲云
4个月前
css中box-sizing解放盒子实际宽高计算
我们知道传统的盒子模型,如果增加内边距padding和边框border,那么会撑大整个盒子,造成盒子的宽度不好计算,在实务中特别不方便。boxsizing可以设置盒模型的方式,可以很好的设置固定宽高的盒模型。盒子宽高计算假如我们设置如下盒子:宽度和高度均为200px,那么这会这个盒子实际的宽高就都是200px。但是当我们设置这个盒子的边框和内间距的时候,那
艾木酱 艾木酱
3个月前
快速入门|使用MemFire Cloud构建React Native应用程序
MemFireCloud是一款提供云数据库,用户可以创建云数据库,并对数据库进行管理,还可以对数据库进行备份操作。它还提供后端即服务,用户可以在1分钟内新建一个应用,使用自动生成的API和SDK,访问云数据库、对象存储、用户认证与授权等功能,可专
Stella981 Stella981
1年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
helloworld_28799839 helloworld_28799839
4个月前
常用知识整理
Javascript判断对象是否为空jsObject.keys(myObject).length0经常使用的三元运算我们经常遇到处理表格列状态字段如status的时候可以用到vue
海军
海军
Lv1
海军,专注Web前端领域开发,分享开发经验与最新前端技术。 微信公众号: 前端自学社区
26
文章
5
粉丝
18
获赞