将Vuejs打字稿选项转换为合成Api时出现奇怪问题

时间:2020-01-28 10:54:27

标签: typescript vue.js vuejs2 vuejs3 vue-composition-api

问题已解决,请仔细阅读问题以了解如何逐步解决问题

我阅读了有关合成api(https://vue-composition-api-rfc.netlify.com/#api-introduction)的内容,并尝试转换基于vuejs中Option api上基于打字稿的现有代码的代码,但我无法使其正常工作,并且对合成api的真正方式感到困惑工作。

我的工作代码如下:

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

合成api中的转换版本低于以下版本,无法正常运行:

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

哪个网络风暴显示3个错误:

enter image description here

反正有正确解决此问题的方法吗?

........

更新1:

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

以及遇到类似问题的道具类型错误,如下图所示 enter image description here

感谢https://frontendsociety.com/using-a-typescript-interfaces-and-types-as-a-prop-type-in-vuejs-508ab3f83480,您可以将创建的类型接口作为如下函数传递: enter image description here

,但是仍有一些问题需要解决,如下所示:

1。当我删除反应性时,似乎反应性无法正常工作,并且在模板中显示“未解决的变量或缺少导入语句” enter image description here

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

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挣扎,我重新编写代码,如下所示:

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

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

//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
  }

如您所见,通过此功能,我们可以最大限度地利用打字稿。

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

1 个答案:

答案 0 :(得分:1)

阅读documentation on props。这是一个示例:

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

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

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

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

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

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

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

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

然后使用它:

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

const inputField = helper.inputField;
相关问题