Vue3.2 + TS 组合式API强类型支持

作者: 伊路顺峰 | 来源:发表于2022-06-01 08:52 被阅读0次

    一开始使用TS不太习惯,但是用了一段时间,发现有类型的支持,书写起来真是爽歪歪,下面介绍几个TS初步上手时解决的类型支持的问题
    1、父子组件通过prop传参,在子组件中强化类型支持
    父组件向子组件传值,子组件通过 defineProps接收值,有两种方式可以强化类型:
    1.1、在子组件中通过PropType 修饰,并传入泛型,这时候会发现,使用的时候写一个点,后面的属性就提示出来了

    image.png image.png
    1.2、还可以定义一个type,在 defineProps 传入这个泛型type:
    image.png

    另外补充一下:如果要设置默认值 需要使用withDefaults:

    type Props = {
      dataInfo?: DataInfo;
    };
    // const props = defineProps<Props>();
    withDefaults(defineProps<Props>(), {
      dataInfo: ()=> {return {title: '默认title',id: '默认值id'}}
    })
    

    2、vuex4 在项目中使用类型支持


    image.png
    image.png
    image.png

    用代码简单实现了一个改变登录状态的小demo
    父组件切换登录状态,子组件更新登录状态


    123123.gif

    完整代码:
    store->index.ts 文件

    import { createStore, Store } from "vuex";
    
    //从vue 中引入一个 InjectionKey 
    import {InjectionKey} from 'vue'
    
    //使用全局唯一的值创建一个injectionKey
    export const injectionKey: InjectionKey<Store<State>> = Symbol()
    
    export type State = {
        isLogin: boolean
    }
    
    export default createStore({
      state: {
        isLogin: false,
      },
      mutations: {
        changeLoginState(state, payload) {
            state.isLogin = payload
        },
      },
    });
    

    main.ts 文件

    import { createApp } from 'vue'
    import App from './App.vue'
    import store, { injectionKey } from './store'
    
    //插件安装时 作为参数传入 injectionKey
    createApp(App).use(store, injectionKey).mount('#app')
    
    

    Child.vue 文件

    <template>
      <div style="background-color:#42b983;">
        <h2>这是子组件</h2>
        <h3>{{ dataInfo?.title }}</h3>
        <h3>id: {{ dataInfo?.id }}</h3>
        <h4>当前登录状态:{{isLogin ? '已登录' : '未登录'}}</h4>
      </div>
    </template>
    <script lang="ts" setup>
    import { computed, defineProps, PropType, toRefs } from "vue";
    import { useStore } from "vuex";
    import { injectionKey } from "../store";
    export interface DataInfo {
      title: string;
      id: string;
    }
    //在组件中使用的时候 传入 injectionKey
    const store = useStore(injectionKey)
    const isLogin = computed(()=> store.state.isLogin)
    const props = defineProps({
      dataInfo: Object as PropType<DataInfo>,
    });
    const { dataInfo } = toRefs(props);
    </script>
    
    

    App.vue

    <script setup lang="ts">
    // This starter template is using Vue 3 <script setup> SFCs
    // Check out https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup
    import HelloWorld from "./components/HelloWorld.vue";
    import Child, { DataInfo } from "./components/Child.vue";
    import { reactive } from "vue";
    import { useStore } from "vuex";
    import { injectionKey } from "./store";
    
    const store = useStore(injectionKey);
    
    let state = reactive<{ dataInfo: DataInfo }>({
      dataInfo: { title: "这是标题", id: "123132123" },
    });
    
    const login = () => {
      store.commit("changeLoginState", true);
    };
    
    const logout = () => {
      store.commit("changeLoginState", false);
    };
    </script>
    <template>
      <div style="background-color: #ffccff; width: 400px; height: 400px">
        <h2>这是父组件</h2>
        <button @click="login">登录</button>
        <button @click="logout">退出</button>
        <child :data-info="state.dataInfo"></child>
      </div>
    </template>
    
    <style>
    #app {
      font-family: Avenir, Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
      margin-top: 60px;
    }
    </style>
    
    

    相关文章

      网友评论

        本文标题:Vue3.2 + TS 组合式API强类型支持

        本文链接:https://www.haomeiwen.com/subject/ehhtmrtx.html