最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 无星的前端之旅(十八)-Vue3+ts常见问题

    正文概述 掘金(XingXiaoWu)   2021-02-15   1774

    第一次用Vue3+ts,采用了eslint(aribnb),遇到了一些问题,又不想用经常性使用any,只能逼迫自己解决问题。

    本文只是记录一些自己遇到的检测问题

    1.使用less并导出变量到ts使用,但是ts报错找不到

    报错内容:

    Cannot find module 'xxx.less' or its corresponding type declarations.
    

    解决方法:

    CSS in Typescript

    2.setup中获取proxy,但提示可能为null

    const { proxy } = getCurrentInstance();
    

    提示报错内容:

    Property 'proxy' does not exist on type 'ComponentInternalInstance | null'.
    

    解决方法:

    1.直接强制确认,因为毫无疑问,在页面或组件中,CurrentInstance一定存在,因此可以使用!强制标记存在

    但在aribnb的eslint规则下,仍然会报警告

    const { proxy } = getCurrentInstance()!;
    

    2.使用as强转

    import { ComponentInternalInstance } from 'vue';
    const { proxy } = getCurrentInstance() as ComponentInternalInstance;
    

    3.如何使用ref获取dom节点

    <template>
      <div :ref="setDivRef" />
    </template>
    <script lang="ts">
    import { defineComponent, ref } from 'vue';
    
    export default defineComponent({
      setup() {
        const divRef = ref<HTMLElement>();
        const setDivRef = (el: HTMLElement) => {
          divRef.value = el;
        };
        return {
          setDivRef,
        };
      },
    });
    </script>
    
    

    4.如果使用Element-Plus的form组件,使用resetFields或者validate方法时,提示没有该属性

    报错内容:

    Property 'resetFields' does not exist on type 'HTMLElement'
    Property 'validate' does not exist on type 'HTMLElement'
    

    解决方法:

    使用InstanceType<typeof ElForm>作为范型约束

    <template>
      <!-- 表单 -->
      <el-form :model="form" :ref="setFormRef" label-width="100px">
        <!-- 注释 -->
      </el-form>
    </template>
    
    <script lang="ts">
    import { ElForm } from 'element-plus';
    import { defineComponent, ref } from 'vue';
    
    export default defineComponent({
      setup() {
        const formRef = ref<InstanceType<typeof ElForm>>();
        const setFormRef = (el: InstanceType<typeof ElForm>) => {
          formRef.value = el;
        };
    
        const resetForm = () => {
          formRef.value?.resetFields();
        };
        const confirm = () => {
          formRef.value?.validate((valid) => {
            if (valid) {
              // do
            }
          });
        };
        return {
          setFormRef,
          resetForm,
          confirm,
          formRef,
        };
      },
    });
    </script>
    
    

    参考:

    Treffen人事管理项目记录

    Vue.js の Composition API における this.$refs の取得方法

    6.props中已经加上约束,但是在setup中使用还是在报错

    报错内容:

    Property 'xxx' does not exist on type 'Readonly<{ [x: number]: string; } & { length?: number | undefined; toString?: string | undefined; toLocaleString?: string | undefined; concat?: string[] | undefined; join?: string | undefined; slice?: string[] | undefined; ... 16 more ...; flat?: unknown[] | undefined; }> | Readonly<...>'.
      Property 'xxx' does not exist on type 'Readonly<{ [x: number]: string; } & { length?: number | undefined; toString?: string | undefined; toLocaleString?: string | undefined; concat?: string[] | undefined; join?: string | undefined; slice?: string[] | undefined; ... 16 more ...; flat?: unknown[] | undefined; }>'.
    

    解决方法:

    额外添加一个interface,名字任意,并将setup的props参数类型标记为定义类型

    <script lang="ts">
    import {
      computed,
      defineComponent,
    } from 'vue';
    
    interface Props1 {
      modelValue: boolean;
      loading: boolean;
    }
    export default defineComponent({
      props: {
        modelValue: {
          type: Boolean,
          default: false,
        },
        loading: {
          type: Boolean,
          default: false,
        },
      },
      setup(props: Props1, context) {
        const visible = computed({
          get: () => props.modelValue,
        });
        const loadingnow = computed({
          get: () => props.loading,
        });
    
        return {
          visible,
          loadingnow,
        };
      },
    });
    </script>
    
    

    7.如何给template加上ts类型推断

    解决方法:

    使用vscode,并添加vetur插件>0.29.0版本,在配置中添加

    vetur.experimental.templateInterpolationService: true
    

    参考: 木子李的回答

    8.在‘no-unused-expressions’的eslint规则下,经常将?.这个判断是否存在的语法糖标记为eslint错误

    (实际上?这个语法糖,除了ts,js在ES2020中也支持了,所以我觉得这个判读机制该升级了)

    例如:

    const foo = bar && bar.tea && bar.tea.cup;
    //简写为
    const foo = bar?.tea?.cup;
    

    报错内容:

    Expected an assignment or function call and instead saw an expression. eslint(no-unused-expressions)
    

    解决方法:

    如果是使用vue-cli创建的项目,默认会引入'@typescript-eslint'

    在eslint配置规则中,关闭'no-unused-expressions',开启'@typescript-eslint/no-unused-expressions'

    'no-unused-expressions': 'off',
    '@typescript-eslint/no-unused-expressions': 'error',
    

    参考:

    Typescript optional chaining and ESLint no-unused-expressions

    9.添加全局挂载属性,比如axios

    挂载代码:

    //main.ts
    import axios from 'axios';
    app.config.globalProperties.$api = axios;
    

    使用代码:

    setup(){
    const { proxy } = getCurrentInstance() as ComponentInternalInstance;
    proxy.$api.xxx
    }
    

    会发现根本没有任何提示,并且会报错

    解决方法:

    新建一个xxx.d.ts声明文件,并在tsconfig中引入(可以使用include,也可以使用typeRoots等,主要看自己项目配置和路径)。

    import { AxiosInstance } from 'axios';
    
    declare module '@vue/runtime-core' {
      interface ComponentCustomProperties {
        $api: AxiosInstance;
      }
    }
    
    

    参考: componentPublicInstance.ts#L41-L66

    p.s:因为我对axios做了二次封装,我所有的api都写在一个文件里,类似:

    // api.ts
    export default {
    	login:()=> axios.get(xxx,xxx),
    	xxx
    }
    

    这种,有n个接口,并且随着项目变动,我目前是手动写了一个d.ts,描述了一个interface,类似

    // api.d.ts
    export interface Api{
    	login:()=>{}
        xxx
        xxx
        xxx
    }
    

    这样,但是每新增一个接口,或者变动,我就要手动添加声明。请问有没有什么办法能把我解放出来TAT。

    因为依赖了比较多的东西,我使用tsc命令单独为这个文件生成d.ts的时候会报错,无法生成。

    求个答案,大佬们都是怎么做的。


    起源地下载网 » 无星的前端之旅(十八)-Vue3+ts常见问题

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元