Как вызвать метод в компоненте Vue из программно вставленного компонента - PullRequest
0 голосов
/ 14 января 2020

Я пытаюсь вызвать метод из дочернего компонента, который вставлен программно. Вот мой код.

MultipleFileUploader. vue

<template>

    <div class="form-group" id="multiple-file-uploader">
        <div>
            <multiple-file-uploader-part
                    :name="uploadername" :index="1"
                    @remove="deleteUploader" @fileselected="fileSelected($event)">
            </multiple-file-uploader-part>
        </div>
    </div>

</template>

<script>
    import MultipleFileUploaderPart from './MultipleFileUploaderPart.vue';
    let index_count = 1;
    export default {
        components: {
            'multiple-file-uploader-part':MultipleFileUploaderPart,
        },
        props: {
            uploadername: {
                type: String,
                default: 'files',
            }
        },
        data() {
            return {
                next_id:1,
            }
        },
        methods: {
            fileSelected: function (target) {
                var UploaderPart = Vue.extend(MultipleFileUploaderPart);
                new UploaderPart().$on('fileselected','fileSelected')
                    .$mount('#multiple-file-uploader');
            },
            deleteUploader: function (idToRemove) {
                this.uploaders = this.uploaders.filter(
                    uploaders_id => {
                        return uploaders_id.id !== idToRemove;
                    }
                )
            }
        },
    }
</script>

<style scoped>

</style>

MultipleFileUploaderPart. vue

<template>
    <div v-bind:id="name + '['+index+']'">
        <div class="input-group margin">
            {{index}}
            <input type="file" accept="application/pdf,image/jpeg,image/png"
                   v-bind:name="name + '['+index+']'"
                   v-on:change="fileSelectedMethod($event.target)">
            <div class="input-group-btn">
                <button @click="removeClicked"
                        class="btn btn-danger btn-sm"
                        v-if="index != 1"
                        type="button">
                    Delete{{index}}
                </button>
            </div>
        </div>
        <p v-if="size_error" style="color: red">File size must be less than 2MB</p>
    </div>
</template>

<script>
    export default {
        props: {
            name: {
                type: String,
            },
            index: {
                type: Number,
            },
        },
        data() {
            return {
                size: '',
                size_error: false,
            }
        },
        methods: {
            removeClicked: function () {
                document.getElementById(this.name+'[' + this.index + ']' ).remove();
                this.$emit('remove', this.index);
            },
            fileSelectedMethod: function (target) {
                this.size = target.files[0].size;
                if (this.size < 2000000) {
                    this.size_error = false;
                    this.$emit('fileselected', target);
                } else {
                    target.value = null;
                    this.size_error = true;
                    console.log(target.files);
                }
            }
        }
    }
</script>

<style scoped>

Я пытаюсь добиться того, чтобы при заполнении файла входными данными создавался MultipleFileUploaderPart. И когда элемент ввода файла в этом компоненте заполнен, вставляется еще один MultipleFileUploaderPart.

Я бы хотел вызвать метод MultipleFileUploader fileSelected из вновь вставленных компонентов, чтобы я мог создать другой компонент.

Я также хочу удалить компонент MultipleFileUploaderPart при нажатии кнопки удаления.

Как этого добиться? или есть лучший способ?

РЕДАКТИРОВАТЬ: Это то, что у меня изначально было. MultipleFileUploader. vue

<template>

    <div class="form-group">
        <div>
            <multiple-file-uploader-part
                    v-for="uploader in uploaders"
                    :name="uploadername" :index="uploader.id"
                    @remove="deleteUploader" @fileselected="fileSelected($event)">
                slot
            </multiple-file-uploader-part>
        </div>
    </div>

</template>

<script>
    import MultipleFileUploaderPart from "./MultipleFileUploaderPart";

    let index_count = 1;
    export default {
        //name: "MultipleFileUploader",
        components: {MultipleFileUploaderPart},
        props: {
            uploadername: {
                type: String,
                default: 'files',
            }
        },
        data() {
            return {
                uploaders: [
                    {
                        id: index_count++,
                    },
                ]
            }
        },
        methods: {
            fileSelected: function (target) {
                if(target.value){
                    this.uploaders.push({
                        id: index_count++,
                    })
                }

            },
            deleteUploader: function (idToRemove) {
                this.uploaders = this.uploaders.filter(
                    uploaders_id => {
                        return uploaders_id.id !== idToRemove;
                    }
                )
            }
        },
    }
</script>

MultipleFileUploaderPart. vue

<template>
    <div class="input-group margin">
        {{index}}
        <input type="file" accept="application/pdf,image/jpeg,image/png"
               v-bind:name="name + '['+index+']'"
               v-on:change="fileSelectedMethod($event.target)">
        <div class="input-group-btn">
            <button @click="$emit('remove',index)"
                    class="btn btn-danger btn-sm"
                    v-if="index != 1"
                    type="button">
                Delete{{index}}
            </button>
        </div>
        <br>
        <p v-if="size_error" style="color: red">File size must be less than 2MB</p>
    </div>

</template>

<script>
    export default {
        props: {
            name: {
                type: String,
            },
            index: {
                type: Number,
            },
        },
        data() {
            return {
                size: '',
                size_error: false,
            }
        },
        methods: {
            checkFileSize: function () {

            },
            fileSelectedMethod: function (target) {
                console.log(target);
                console.log(target.files);
                this.size = target.files[0].size;
                console.log(this.size);
                if (this.size < 2000000) {
                    this.size_error = false;
                    this.$emit('fileselected', target);
                } else {
                    target.value = null;
                    this.size_error = true;
                    console.log(target.files);
                }
            }
        }
    }
</script>

И это происходит. пожалуйста, нажмите

Когда я нажимаю кнопку «Удалить», правильный дочерний компонент удаляется, но файл в форме ввода остается там. вот почему я ищу другой подход.

1 Ответ

0 голосов
/ 14 января 2020
  1. Объявите загрузчиков как массив объектов, которые содержат все необходимые реквизиты для создания MultipleFileUploaderPart.
  2. Используйте v-for для MultipleFileUploaderPart в основном MultipleFileUploader для реактивной генерации компонентов MultipleFileUploaderPart
  3. Используйте $ emit из MultipleFileUploaderPart в MultipleFileUploader для отправки событий создания и удаления, чтобы MultipleFileUploader мог добавлять или удалять элементы в массиве загрузчиков .
  4. Пожалуйста, не удаляйте или создавать элементы непосредственно из DOM, пусть VueJs сделает эту работу.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...