【问题标题】:Vue 3 new instance of .vue fileVue 3 .vue 文件的新实例
【发布时间】:2021-05-06 16:27:27
【问题描述】:

在 vue 2 中,我可以轻松创建一个实例: 让 vueTemplate = 新模板();

它会起作用的。但它在 vue 3 中不起作用。

这是 Vue 2 中我如何访问新实例的代码:

import template from './edit-text-field.vue';

export default class EditTextFieldInitializer {
    public static InitEditTextField(config: EditTextFieldConfig) {
     // VueConstructor
     let vueTemplate = new template(); // How can i do the same in vue 3 ?
     vueTemplate .$mount(config.element);
  }
}

错误:

Uncaught TypeError: _edit_text_field_vue__WEBPACK_IMPORTED_MODULE_0__.default is not a constructor

我的模板 vue 文件:

<template>
    <el-form :model="form" :rules="rules" ref="form" label-width="0px"
             @submit.prevent
             @validate="onValidate"
             class="gantt-text-field-edit-form"
             v-loading="isLoading">
        <el-form-item prop="value">
            <el-popover placement="bottom"
                        v-model="isPopoverVisible"
                        width="200"
                        trigger="manual"
                        :content="errorMessage">
                                      <template #reference>
                <el-input  ref="input" @blur="submitForm"
                          :placeholder="$l('PleaseEnterValue')" v-model="form.value"></el-input>
                                        </template>
            </el-popover>

        </el-form-item>

    </el-form>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
        name: 'edit-text-field',
        data: () => {
            return {
                isPopoverVisible: false,
                isGettingErrorMsg: false,
                errorMessage: null,
                isFormSubmited: false,
                isLoading: false,
                form: {
                    value: null
                },
                rules: {

                },
                onValueChanged: null,
                onEditModeExit: null

            }
        },
        methods: {
            onChanged(value) {
                this.submitForm();
            },
            setData(data) {
                this.form = data.form;
                this.rules = data.rules;
                this.onValueChanged = data.onValueChanged;
                this.onEditModeExit = data.onEditModeExit;
            },
            onBlur() {
                this.$beforeUnmount();
                this.$data.onEditModeExit();
            },
            processInput(event: any): void {
                if (event.keyCode === 13) {
                    this.submitForm();
                }
            },
            processEscButtonPress(event: any): void {
                //esc button
                if (event.keyCode === 27) {
                    this.onBlur();
                }
            },
            submitForm() {
                let component: any = this;
                if (component.$data.isFormSubmited)
                    return;
                component.$data.isFormSubmited = true;
                component.$refs.form.validate((valid) => {
                    if (valid) {
                        component.setFormValid();
                        var promise = component.$data.onValueChanged(component.$data.form.value);
                        if (promise == null) {
                            component.onBlur();
                            component.$data.isFormSubmited = false;
                        } else {
                            component.$data.isLoading = true;
                            promise.then(() => {
                                component.$data.isFormSubmited = false;
                                component.$data.isLoading = false;
                                component.onBlur();
                            });
                        }
                        return true;

                    } else {
                        component.setFormInvalid();
                        component.$data.isFormSubmited = false;
                        return false;
                    }
                });
            },
            onValidate(name: string, isValid: boolean) {
                let component: any = this;

                if (this.$data.isGettingErrorMsg == true) {
                    this.$data.isGettingErrorMsg = false;
                    return;
                }
                if (isValid) {
                    this.setFormValid();
                } else {
                    component.$refs.form.validateField(name, (msg) => {
                        this.$data.isGettingErrorMsg = true;
                        this.$data.errorMessage = msg;
                        this.setFormInvalid();
                    });
                }
            },
            setFormValid() {
                let component: any = this;
                this.$data.isPopoverVisible = false;
                component.$refs.form.$el.classList.add('valid');
            },
            setFormInvalid() {
                let component: any = this;
                this.$data.isPopoverVisible = true;
                component.$refs.form.$el.classList.remove('valid');
                component.$refs.input.focus();
            }
        },
        // created() {
        //     debugger
        //     // alert("Created - Not a bug - If you still see this message - I'm working on it.")
        // },
        mounted() {
            debugger
            let component: any = this;
            component.setFormValid();
            component.$refs.input.$el.addEventListener('keypress', component.processInput);
            component.$refs.input.$el.addEventListener('keydown', component.processEscButtonPress);
            component.$refs.input.focus();
        },
        beforeUnmount() {
            this.$data.isPopoverVisible = false;
        }
    });
</script>

        const vueTemplate:any = createApp(template);
        const instance = vueTemplate.mount(config.element); // Breaking here
        // Uncaught TypeError: Cannot read property 'created' of undefined
        // and error:
        // Error: [Vue warn]: Failed to resolve component: el-input 
        //at <EditTextField>
        instance.$data.onValueChanged = config.onValueChanged;
        instance.$data.onEditModeExit = config.onEditModeExit;
        instance.$data.rules = config.validationRules;

配置:

element: div.pointer.gantt-grid-value
onEditModeExit: ƒ ()
onValueChanged: ƒ (newValue)
validationRules: {value: Array(2)}
value: "0"
__proto__: Object

没用: import EditTextField from './edit-text-field.vue'; 它打破了这一行 createApp(EditTextField).mount(config.element); config.element:是元素:div.pointer.gantt-grid-value (dom中的元素)

错误:

runtime-core.esm-bundler.js?5c40:38 [Vue warn]: Failed to resolve directive: loading 
  at <EditTextField>
runtime-core.esm-bundler.js?5c40:38 [Vue warn]: Failed to resolve component: el-popover 
  at <EditTextField>
runtime-core.esm-bundler.js?5c40:38 [Vue warn]: Failed to resolve component: el-form-item 
  at <EditTextField>
runtime-core.esm-bundler.js?5c40:38 [Vue warn]: Failed to resolve component: el-form 
  at <EditTextField>
runtime-core.esm-bundler.js?5c40:2911 Uncaught TypeError: Cannot read property 'created' of undefined
    at invokeDirectiveHook (runtime-core.esm-bundler.js?5c40:2911)
    at mountElement (runtime-core.esm-bundler.js?5c40:3853)
    at processElement (runtime-core.esm-bundler.js?5c40:3822)
    at patch (runtime-core.esm-bundler.js?5c40:3742)
    at componentEffect (runtime-core.esm-bundler.js?5c40:4243)
    at reactiveEffect (reactivity.esm-bundler.js?a1e9:42)
    at effect (reactivity.esm-bundler.js?a1e9:17)
    at setupRenderEffect (runtime-core.esm-bundler.js?5c40:4208)
    at mountComponent (runtime-core.esm-bundler.js?5c40:4167)
    at processComponent (runtime-core.esm-bundler.js?5c40:4127)
    at patch (runtime-core.esm-bundler.js?5c40:3745)
    at render (runtime-core.esm-bundler.js?5c40:4828)
    at mount (runtime-core.esm-bundler.js?5c40:3046)
    at Object.app.mount (runtime-dom.esm-bundler.js?830f:1234)
    at Function.EditTextFieldInitializer.InitEditTextField (edit-text-field.ts?b6bf:15)
    at Object.GanttInstance.editProgessValue (gantt-tab.ts?3a72:701)

休养:

createApp(EditTextField).mount(config.element)

无法解析模板中的html元素 像上面的 el-form-item 和 html 错误。

  • 创建一个新应用,但我无法使用我的 main.ts 应用

此代码以某种方式工作。 但问题是: 我需要再次添加所有导入以使其正常工作。 编辑文本字段.ts

import template from './edit-text-field.vue';
import ElementPlus from 'element-plus';
import locale from "element-plus/lib/locale/lang/ru";
import { VueLocalizationPlugin } from "@/helpers/localization";

const comp = createApp(template);
        debugger
        comp.use(ElementPlus, { locale, size: "mini" }).use(VueLocalizationPlugin);

这不是像 vue 2 那样的好解决方案

【问题讨论】:

    标签: vue.js vuejs3


    【解决方案1】:

    要创建组件实例,请在组件定义上使用 createApp(),在 HTML 元素上使用 mount()

    import { createApp } from 'vue'
    import MyComponent from '@/components/MyComponent.vue'
    
    //...
    
    let vueTemplate = createApp(MyComponent).mount(config.element)
    

    demo (simple)

    demo (with Element UI)

    【讨论】:

    • runtime-core.esm-bundler.js?5c40:38 [Vue 警告]:无法解析组件: 处的 el-input
    • and Uncaught TypeError: Cannot read property 'created' of undefined
    • 代码太多,生产代码很大。它曾经在 vue 2 中使用简单的一行 let vueTemplate = new template(); ---- 当它点击 .mount(config.element) 时,它在创建时失败
    • 创建一个最小的可重现示例来帮助排除故障。您不需要包含整个项目。该错误似乎表明您的代码中存在与原始问题无关的其他问题,但我们需要查看组件代码才能确定。
    • 使用方法见答案中的演示链接。
    猜你喜欢
    • 2021-08-25
    • 2021-07-01
    • 1970-01-01
    • 2020-05-28
    • 1970-01-01
    • 2018-02-15
    • 2021-01-07
    • 2021-02-06
    • 2017-03-25
    相关资源
    最近更新 更多