从JS->TS改造小项目(做个人记录)

240 阅读3分钟

接上一个项目进行ts改造

目录结构:

image.png

比之前多了一个types文件夹,用来定义数据接口类型。一个hooks用来存放公共方法。

重点改造部分:

  1. types定义数据类型 固定的值使用枚举来定义
interface state{
    consName:ConsName,
    filed:Filed,
    errorCode?:number | string,
    today?: Array<any>,
    tomorrow?: Array<any>,
    week?: Array<any>,
    month?: Array<any>,
    year?: Array<any>,
    login?:number | string
}
enum ConsName {
    "白羊座"='白羊座',
    '处女座'="处女座",
    '金牛座'="金牛座",
    '巨蟹座'="巨蟹座",
    '摩羯座'="摩羯座",
    '射手座'="射手座",
    '狮子座'="狮子座",
    '双子座'="双子座",
    '双鱼座'="双鱼座",
    '水瓶座'="水瓶座",
    '天秤座'="天秤座",
    '天蝎座'="天蝎座"
} //英文找起来太麻烦,暂且用中文
enum Filed {
    TODAY='today',
    TOMORROW="tomorrow",
    WEEK='week',
    MONTH='month',
    YEAR='year'
}


export {
    state,
    ConsName,
    Filed
}
  1. 对象数据类型也需要定义接口约束
interface IErrorCode{
  [propName: string]: string;
}
export default<IErrorCode> {
  '10001':	'错误的请求KEY',
  '10002':	'该KEY无请求权限',
  '10003':	'KEY过期',
  '10004':	'错误的OPENID',
  '10005':	'应用未审核超时,请提交认证',
  '10007':	'未知的请求源',
  '10008':	'被禁止的IP',
  '10009':	'被禁止的KEY',
  '10011':	'当前IP请求超过限制',
  '10012':	'请求超过次数限制',
  '10013':	'测试KEY超过请求限制',
  '10014':	'系统内部异常(调用充值类业务时,请务必联系客服或通过订单查询接口检测订单,避免造成损失)',
  '10020':	'接口维护',
  '10021':	'接口停用',
  '217701':	'未搜索到数据',
  '217702':	'输入的日期格式错误'
}

如果没有这样子做,使用(该对象obj)obj[errorcode]会报错any不能为索引值。

  1. 该项目数据在vuex里使用,重点改造vuex=》完整action->mutation->改变state
  • 目录结构

image.png

  • state.ts:
import { state } from "@/types";

export default <state>{
    consName: '白羊座',
    filed: 'today', 
    errorCode: 0,
    today: {},
    tomorrow: {}, 
    week: {},
    month: {},
    year: {},
    login:0 
}
  • actionTypes定义action方法常数
export const SET_CONSNAME = 'setConsName'
export const SET_FILED = 'setFiled'
export const SET_ERRORCODE = 'setErrorCode'
export const SET_DATA = 'setdata'
export const SET_LOGINE = 'setlogin'
  • action.ts-->所有的mutation都由action触发
import {state,ConsName,Filed} from '../types/index'
import { Commit } from 'vuex';
import {SET_CONSNAME,SET_FILED,SET_ERRORCODE,SET_DATA,SET_LOGINE} from './actionTypes'
interface ICtx {
    commit: Commit,
    state: state
}
export default{
    [SET_CONSNAME]({ commit }: ICtx, consName: ConsName):void{
        commit(SET_CONSNAME,consName)
    },
    [SET_FILED]({ commit }: ICtx, filed: Filed):void{
        commit(SET_FILED,filed)
    },
    [SET_ERRORCODE]({ commit }: ICtx, errorCode: number|string):void{
        commit(SET_ERRORCODE,errorCode)
    },
    [SET_DATA]({ commit }: ICtx, data: Array<any>):void{
        commit(SET_DATA,data)
    },
    [SET_LOGINE]({ commit }: ICtx):void{
        commit(SET_LOGINE,1)
    },

}
  • mutations.ts-->改变state
import { ConsName, Filed, state } from '@/types'
import {SET_CONSNAME,SET_FILED,SET_ERRORCODE,SET_DATA,SET_LOGINE} from './actionTypes'
export default {
    [SET_CONSNAME](state:state,consName:ConsName):void{
        state.consName = consName
    },
    [SET_FILED](state:state,filed:Filed):void{
        state.filed = filed
    },
    [SET_ERRORCODE](state:state,errorCode:string|number):void{
        state.errorCode = errorCode
    },
    [SET_DATA](state:state,data:Array<any>):void{
        state[state.filed] = data
    },
    [SET_LOGINE](state:state):void{
        state.login = 1
    },
}
  1. 业务重复逻辑封装为hooks来使用
import { SET_CONSNAME, SET_FILED,SET_ERRORCODE,SET_DATA,SET_LOGINE } from '@/store/actionTypes'
import { useStore,Store } from 'vuex'
import { ConsName,Filed, state } from '../types/index'
import { computed, ref , onMounted , onActivated} from 'vue'
import { getdata } from '../apis/apis'

interface IUseSet{
    setConsName:(consName:ConsName)=>void;
    setFiled:(filed:Filed)=>void;
    setErrorCode:(errorCode:string|number)=>void;
    setData:(data:Array<any>)=>void;
    setLogin:()=>void;
    getApiData:()=>void;
}
interface IuseInit{
    pageData:any;
    getData:()=>void;
    ActivatedFunc:()=>void;
}

export function UseSet():IUseSet {
    const store:Store<any> = useStore()
    function setConsName(consName:ConsName) {
        store.dispatch(SET_CONSNAME,consName)
    }
    function setFiled(filed:Filed){
        store.dispatch(SET_FILED,filed)
    }
    function setErrorCode(errorCode:string|number){
        store.dispatch(SET_ERRORCODE,errorCode)
    }
    function setData(data:Array<any>){
        store.dispatch(SET_DATA,data)
    }
    function setLogin(){
        store.dispatch(SET_LOGINE)
    }
    async function getApiData(){
        const consName = store.state.consName,
        filed = store.state.filed,
        data:any = await getdata(consName, filed)
        console.log(data)
        if (data.error_code) {
            setErrorCode(data.error_code)
            return
        }
        setData(data)
    }
    return{
        setConsName,
        setFiled,
        setErrorCode,
        setData,
        setLogin,
        getApiData
    }
}

export function UseInit(type:Filed):IuseInit{
    const {getApiData} = UseSet()
    const store:Store<any> = useStore(),
          state:state = store.state,
          status = ref(''),
          pageData = computed(() => state[type])
    function getData(){
        onMounted(()=>{
            getApiData()
        })
    }
    function ActivatedFunc(){
        onActivated(()=>{
            if (status.value !== state.consName) {
# getApiData()
                status.value = state.consName
            }
        })
    }
    return{
        pageData,
        getData,
        ActivatedFunc
    }
}

  1. 页面中直接使用
import {UseInit} from '../hooks/index'
import { Filed } from '@/types'
const {pageData , getData , ActivatedFunc} = UseInit(Filed.TODAY)
  getData()
  ActivatedFunc()

vue3参考视频

github

项目github地址

总结:

刚接触typescript 过程磕磕碰碰。