将 Vuejs Typescript 选项转换为 Composition Api 中的奇怪问题 [英] odd problems in Convert Vuejs Typescript Options to Composition Api

查看:34
本文介绍了将 Vuejs Typescript 选项转换为 Composition Api 中的奇怪问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题已解决,请通读问题以了解如何逐步解决问题

我阅读了关于组合 api(

有没有办法正确解决这个问题?

................

更新 1:

我在使用 props 时犯了一个错误(我以为我是新的 vue,它不需要类型,它会自动从父组件的 typescript 中获取它).多亏了paleo,问题已经解决了.

以及任何在获取道具类型错误时遇到类似问题的人,如下图所示

感谢

但仍有一些问题需要修复,如下所示:

1.当我删除反应性时,反应性似乎无法正常工作,并且在模板中显示未解析的变量或缺少导入语句"

.................................

update2分享道具和使用合成功能:

对我来说,在将基于选项的 api 转换为组合 api 之后,它似乎比新的更好,这要归功于 Paleo 和 Maximilian shrwazmuller(我强烈建议观看此免费视频:https://www.youtube.com/watch?v=V-xK3sbc7xI),以及谷歌搜索这个 https://vue-composition-api-rfc.netlify.com/api.html#template-refs 我将代码重写为如下所示:

如您所见,它非常简洁,因为将在组件之间共享的所有内容都在另一个文件(名为:inputFiled.compositons)中,如下所示:

//inputField.composition.ts从@vue/composition-api"导入{PropType,reactive};从@/types"导入 {FormGeneratorInputField};从@/mixins/Helpers/FormGeneratorInputFieldHelper/InputField.Helper.mixin"导入{InputFieldHelper};导出 const inputFieldProps = {实例: {类型:Object as PropType,要求:真实},价值: {类型:对象,要求:真实},表格部分:{类型:字符串,要求:真实},启用:{类型:布尔型,要求:真实},};export const useInputFieldComposition = (props: any, context: any) =>{让 inputField = reactor(new InputFieldHelper(props.value, props.instance, props.formSection, props.isEnable));const updateValue = (): any =>{让 new_data = inputField.passInfoMixedValue();新数据 ?context.emit("updateValue", new_data) : "";返回新数据;};返回 {道具,输入字段,更新值}

正如您所看到的,通过此功能,我们可以最大程度地使用打字稿.

最后我应该告诉你,如果你遵循路径并使用 vue-composition api,你的项目将完美运行,但 webstorm 会向你显示一些关于模板中特定代码的警告,比如未解析的变量.这些新的语法支持正在开发中,您可以在本期 https://youtrack.jetbrains 中看到.com/issue/WEB-41565所以不要担心它并使用它.

解决方案

阅读文档在 props 上.下面是一个例子:

 道具:{实例: {类型:对象,要求:真实},价值: {类型:对象,要求:真实},表格部分:{类型:对象,要求:真实},启用:{类型:布尔型,要求:假},},

为了启用更好的类型,可以使用PropType:

import { PropType } from "@vue/composition-api/dist/component/componentProps";//...道具: {实例: {类型:Object as PropType,要求:真实},//...

要发出事件,请遵循错误消息中的建议:context.emit("updateValue").

关于InputFieldHelper的实例,我建议重构这个类的实现:

class InputFieldHelper {只读输入字段:{输入值:字符串 |空值}构造函数(/* ... */){this.inputField = 反应性({输入值:空})}}

然后,使用它:

const helper = new InputFieldHelper(props.value, props.instance, props.formSection, props.isEnable);const inputField = helper.inputField;

the problem has been solved, read through the question to see how step by step fix the problems

I read about composition api(https://vue-composition-api-rfc.netlify.com/#api-introduction), and tried to convert my existing code which is based on typescript on Option api in vuejs, and i failed to make it work, and kinda confused about how composition api really work.

my working code is below:

<script lang="ts">
  import Vue from "vue";
  import {inputFields} from "@/mixins/inputField/inputField";
  import VuePersianDatetimePicker from "vue-persian-datetime-picker"
  import {util_timestampz_formatter, util_timestampz_now} from "@/utils/commonUtility";
  import {InputFieldHelper} from "@/mixins/Helpers/FormGeneratorInputFieldHelper/InputField.Helper.mixin";

  export default Vue.extend({
    name: "DateTimePicker",
    props: ['instance', "value", "formSection", "isEnable"],
    components: {
      datePicker: VuePersianDatetimePicker
    },
    data() {
      return {
        inputField: new InputFieldHelper(this.value, this.instance, this.formSection, this.isEnable)
      }
    },
    mounted() {
      //@ts-ignore
      this.instance.min = util_timestampz_now();
    },
    methods: {
      updateValue() {
        let new_data = this.inputField.updateValue();
        new_data ? this.$emit("updateValue", new_data) : "";
      },
      updateDateTime(time: string) {
        //@ts-ignore
        this.inputField.inputValue = util_timestampz_formatter(this.inputField.inputValue);
        //@ts-ignore
        this.updateValue();
      },
    }
  });
</script>

the converted version in composition api is below which is not run properly:

<script lang="ts">
  import Vue from "vue";
  import {reactive, createComponent, onMounted} from "@vue/composition-api";
  import VuePersianDatetimePicker from "vue-persian-datetime-picker"
  import {util_timestampz_formatter, util_timestampz_now} from "@/utils/commonUtility";
  import {InputFieldHelper} from "@/mixins/Helpers/FormGeneratorInputFieldHelper/InputField.Helper.mixin";
  import {FormGeneratorInputField} from "@/types";

  export default createComponent({
    name: "DateTimePicker",
    props: {
      instance,
      value,
      formSection,
      isEnable,
    },
    components: {
      datePicker: VuePersianDatetimePicker
    },
    setup(props, context) {
      const inputField = reactive(new InputFieldHelper(props.value, props.instance, props.formSection, props.isEnable));
      onMounted(() => {
        props.instance.min = util_timestampz_now();
      });
      const updateValue = () => {
        let new_data = inputField.updateValue();
        new_data ? context.$emit("updateValue", new_data) : "";
      };
      const updateDateTime = (time: string) => {
        inputField.inputValue = util_timestampz_formatter(inputField.inputValue);
        updateValue();
      };
      return {
        inputField, updateValue, updateDateTime
      }
    }
  });
</script>

which webstorm shows 3 error:

is there anyway to fix this problems properly?

.................

update1:

i did mistake in using props(i thought i new vue, it does not need the type, and it takes it automatically in typescript from parent component). thanks to paleo the problem has been gone and it fixed.

and to anyone which has similar problem in getting type error for props like what you see in below picture

thanks to https://frontendsociety.com/using-a-typescript-interfaces-and-types-as-a-prop-type-in-vuejs-508ab3f83480 ,you can pass your created type interface as function like below:

but there is still some issues which is need to be fixed, like below :

1.when i removed reactive, it seems the reactivity is not working properly, and in the template which says "unresolved variable or missing import statement"

..........................

update2 sharing props and using composition functions:

to me, after converting option based api to composition api, it seemed that it was better than the new one, thanks to paleo and Maximilian shrwazmuller(i strongly suggest to see this free video: https://www.youtube.com/watch?v=V-xK3sbc7xI), and google search struggling with this https://vue-composition-api-rfc.netlify.com/api.html#template-refs i re-write the code to be something like below:

<script lang="ts">
  import {createComponent, onMounted} from "@vue/composition-api";
  import VuePersianDatetimePicker from "vue-persian-datetime-picker"
  import {util_timestampz_formatter, util_timestampz_now} from "@/utils/commonUtility";
  import {
    useInputFieldComposition,
    inputFieldProps
  } from "@/mixins/Helpers/FormGeneratorInputFieldHelper/inputField.composition";
  import {ComponentPropsOptions} from "@vue/composition-api/dist/component/componentProps";

  export default createComponent({
    name: "DateTimePicker",
    props: inputFieldProps as ComponentPropsOptions,
    components: {
      datePicker: VuePersianDatetimePicker
    },
    setup(props, context) {
      const {inputField, updateValue} = useInputFieldComposition(props, context);
      onMounted(() => {
        props.instance.min = util_timestampz_now();
      });
      const updateDateTime = (time: string) => {
        inputField.inputValue = util_timestampz_formatter(inputField.inputValue);
        updateValue();
      };
      return {
        inputField, updateValue, updateDateTime
      }
    }
  });
</script>

as you can see, it has been pretty neat, because everything which will be shared among components are in another file(named: inputFiled.compositons) like below:

//inputField.composition.ts
import {PropType, reactive} from "@vue/composition-api";
import {FormGeneratorInputField} from "@/types";
import {InputFieldHelper} from "@/mixins/Helpers/FormGeneratorInputFieldHelper/InputField.Helper.mixin";

export const inputFieldProps = {
  instance: {
    type: Object as PropType<FormGeneratorInputField>,
    required: true
  },
  value: {
    type: Object,
    required: true
  },
  formSection: {
    type: String,
    required: true
  },
  isEnable: {
    type: Boolean,
    required: true
  },
};
export const useInputFieldComposition = (props: any, context: any) => {
  let inputField  = reactive(new InputFieldHelper(props.value, props.instance, props.formSection, props.isEnable));
  const updateValue = (): any => {
    let new_data = inputField.passInfoMixedValue();
    new_data ? context.emit("updateValue", new_data) : "";
    return new_data;
  };

  return {
    props, inputField, updateValue
  }

as you can see with this feature we can use typescript to the fullest potential.

and finally i should tell you if you following the path and using vue-composition api, your project will work perfectly, but webstorm will show you some warning about the code specificly in your template, like unresolved variable. these new syntax support is under develop which you can see in this issue https://youtrack.jetbrains.com/issue/WEB-41565 so don't be worry about it and use it.

解决方案

Read the documentation on props. Here is an example:

    props: {
      instance: {
        type: Object,
        required: true
      },
      value: {
        type: Object,
        required: true
      },
      formSection: {
        type: Object,
        required: true
      },
      isEnable: {
        type: Boolean,
        required: false
      },
    },

In order to enable better types, PropType can be used:

import { PropType } from "@vue/composition-api/dist/component/componentProps";
// …

    props: {
      instance: {
        type: Object as PropType<FormGeneratorInputField>,
        required: true
      },
      // …

To emit an event, follow the suggestion in your error message: context.emit("updateValue").

Regarding the instance of InputFieldHelper, I suggest to refactor this class implementation:

class InputFieldHelper {
  readonly inputField: {
    inputValue: string | null
  }

  constructor(/* … */) {
    this.inputField = reactive({
      inputValue: null
    })
  }
}

Then, use it:

const helper = new InputFieldHelper(props.value, props.instance, props.formSection, props.isEnable);

const inputField = helper.inputField;

这篇关于将 Vuejs Typescript 选项转换为 Composition Api 中的奇怪问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆