#vue.js #vue-component #vuejs3
Вопрос:
Я создаю динамическую таблицу, используя Vue 3 в качестве учебного проекта, в котором пользователь, среди прочего, может добавлять или удалять строки из таблицы. Я использую table-row
компонент для создания строки и table-data
компонент для создания ячеек данных в этой строке. Добавление строки выполняется с помощью следующего кода:
const app = Vue.createApp({
data() {
return {
tableRows: [],
}
},
methods: {
addRow() {
this.tableRows.push(-1);
},
},
})
Что мне нужно сделать, так это передать массив TableRows
и index
table-row
компоненту, чтобы выполнить операцию удаления строки, как показано в этом коде:
app.component('table-row', {
props: {
tableRows: Array,
index: Number,
},
methods: {
deleteRow(index) {
this.tableRows.splice(index, 1);
}
},
template: `
<tr>
<table-data></table-data>
<table-data></table-data>
<table-data></table-data>
<table-data></table-data>
<button @click="deleteRow">Delete Row</button>
</tr>
`
})
Проблема в том, что оба значения TableRows
и index
не определены (как показано в Vue DevTools), что означает, что реквизиты не передаются от родительского компонента к дочернему компоненту. Я думаю, что именно по этой причине эта ошибка появляется всякий раз, когда я нажимаю кнопку Удалить строку:
Неперехваченная ошибка типа: Не удается прочитать свойства неопределенного (чтение «сращивания»)
Вот скриншот из Vue DevTools. Вы можете видеть, что переменные реквизита имеют неопределенные значения:
Я не совсем уверен, почему это происходит, или что я могу сделать, чтобы исправить это. Мы будем очень признательны за любую помощь.
Комментарии:
1. Не на 100% об этом, но я думал, что вы должны были передать реквизиты, используя
v-on
привязку от родителя, чтобы использовать их в ребенке. Вы можете попробовать добавить html-шаблон к родительскому, а не к дочернему, и привязать реквизит, используяv-on
его.2. @Chaos_Is_Harmony Насколько я понимаю компоненты и реквизит, это не обязательно так. Примеры на странице руководства Vue передают реквизит… напрямую, я полагаю? Я не уверен, как называется их метод. Что касается перемещения шаблона в родительский, я думаю, это идея. Я попробую это сделать и посмотрю, что я могу с этим сделать, но это не решит проблему, с которой я сейчас сталкиваюсь.
3. @Chaos_Is_Harmony, Ты был прав. Мне пришлось привязать переменную к компоненту в самом HTML. Что-то вроде
<table-row :tableRow="tableRow" :index="index"></table-row>
. Тем не менее,tableRow
значение все еще не определено, даже несмотряindex
на то, что переменная передается в компонент. Я подозреваю, что данные не совпадают, но я не уверен.4. Изменить предыдущий комментарий: Это не несоответствие типов. Похоже
tableRows
, это атрибут (если бы я поверил Ву ДевТулсу), а не реквизит. Нужно ли мне сейчас открывать новый вопрос ?-? ?5. Я опубликовал ответ с более подробным ответом, который, надеюсь, поможет.
Ответ №1:
Я думаю, что все реквизиты сначала должны быть объявлены в родительских данных, прежде чем они будут привязаны к дочерним реквизитам
"PARENT"
<template>
...
<Child :tableRows="tableRows" />
...
</template>
...
<script>
...
data() {
return {
tableRows: []
}
}
...
</script>
"CHILD"
...
</script>
...
props: {
tableRows: Array
}
...
</script>
Что касается индекса, вам, скорее всего, придется отправить emit
событие обратно родителю по щелчку мыши.
"CHILD"
<template>
...
<button @click="$emit('deleteRow')">Delete Row</button>
...
</template>
Здесь вам придется иметь дело с этим в родительском, где e-значение, связанное с событием-в данном случае, предположительно, нужный вам индекс.
"PARENT"
<template>
...
<Child @deleteRow="deleteRow(e)" :tableRows="tableRows" />
...
</template>
Комментарии:
1. Да! Это сработало идеально. Мне пришлось кое-что подправить, но то, что вы описали, было ответом, который я искал. Спасибо. Забавно, но когда я прошел
i
вместоindex
этого , функция все еще работала так, как должна была, хотя и не раньше, чем выдала предупреждение в консоли. Сталкивался ли я с некоторыми ошибками JavaScript из-за того, что он не был напечатан?2. Хотел бы я знать. Я довольно новичок в Vue.js и javascript, но я уже сталкивался с этой проблемой ранее. Вот почему я вспомнил: Родитель->Ребенок = Реквизит; Ребенок->>Родитель = Излучать.
Ответ №2:
Вы не прошли index
, @click="deleteRow"
Попробуйте изменить метод на :
deleteRow() {
this.tableRows.splice(this.index, 1);
}
или перейти index
к методу:
@click="deleteRow(index)"
Комментарии:
1. Извините, пробовал и то, и другое, но все равно не работает. Я добавил скриншот Vue DevTools, на котором по-прежнему отображаются значения реквизитов как неопределенные.