Vue3 + TypeScript 开发实践总结

前言

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

Vue3 + TypeScript Study

Vue 3

一, 环境配置

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 中编写组件中的另外一种方法,内部简化了好多操做。vue

因此你还能够继续使用 Vue2 的方式来 编写 组件。java

3.2 何时使用Composition Api

  1. TypeScript` 的支持
  2. 编写大型组件时,可使用 Composition Api 组合函数很好的管理状态
  3. 跨组件重用代码时

四,Composition Api 必备基础

4.1 什么是 setup

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

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

注意:

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

4.2 ref 建立响应式变量

Vue2 中,咱们定义一个响应式变量能够直接在 data 中 定义而且在模板中使用该变量。 若是 使用的 composition api 的话,咱们得在 setup 中 使用 ref 来建立 响应式变量,而且得将它返回,才能在页面中使用。npm

使用

    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` api

sd ide

下面代码中有两个 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}

最后

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

相关文章
相关标签/搜索