#vue.js
#vue.js
Вопрос:
Я изо всех сил пытаюсь понять, как сделать мой компонент реактивным. На данный момент кнопка отображается правильно, но как только произойдет событие создания / удаления, шаблон не изменится. Есть какие-нибудь советы о том, как обновить компонент после того, как событие состоялось?
new Vue({
el: '#app'
});
Vue.component('favourite-button', {
props: ['id', 'favourites'],
template: '<input class="hidden" type="input" name="_method" value="{{ id }}" v-model="form.listings_id"></input><button v-if="isFavourite == true" class="favourited" @click="delete(favourite)" :disabled="form.busy"><i class="fa fa-heart" aria-hidden="true"></i><button class="not-favourited" v-else @click="create(favourite)" :disabled="form.busy"><i class="fa fa-heart" aria-hidden="true"></i></button><pre>{{ isFavourite == true }}</pre>',
data: function() {
return {
form: new SparkForm({
listings_id: ''
}),
};
},
created() {
this.getFavourites();
},
computed: {
isFavourite: function() {
for (var i = 0; this.favourites.length; i )
{
if (this.favourites[i].listings_id == this.id) {
return true;
}
}
},
},
methods: {
getFavourites() {
this.$http.get('/api/favourites')
.then(response => {
this.favourites = response.data;
});
},
create() {
Spark.post('/api/favourite', this.form)
.then(favourite => {
this.favourite.push(favourite);
this.form.id = '';
});
},
delete(favourite) {
this.$http.delete('/api/favourite/' this.id);
this.form.id = '';
}
}
});
Vue.component('listings', {
template: '#listing-template',
data: function() {
return {
listings: [], favourites: [],
};
},
created() {
this.getListings();
},
methods: {
getListings() {
this.$http.get('/api/listings')
.then(response => {
this.listings = response.data;
});
}
}
});
Ответ №1:
Vue ожидает, что разметка шаблона HTML будет идеальной. В противном случае вы столкнетесь с множеством проблем.
Я только что проверил ваш шаблон и обнаружил проблему — первый <button>
элемент не закрывается.
Вот обновленная версия вашего кода:
Vue.component('favourite-button', {
props: ['id', 'favourites'],
template: `
<input class="hidden" type="input" name="_method" value="{{ id }}" v-model="form.listings_id"></input>
<button v-if="isFavourite == true" class="favourited" @click="delete(favourite)" :disabled="form.busy">
<i class="fa fa-heart" aria-hidden="true"></i>
</button> <!-- This is missing in your version -->
<button class="not-favourited" v-else @click="create(favourite)" :disabled="form.busy">
<i class="fa fa-heart" aria-hidden="true"></i>
</button>
<pre>{{ isFavourite == true }}</pre>
`,
...
Обратите внимание на комментарий в 7-й строке выше, закрывающий </button>
тег отсутствует в вашем шаблоне.
В качестве дополнительного примечания, если вы не хотите вводить обратную косую черту в конце каждой строки, чтобы создавать многострочные строки шаблона, вы можете использовать обратные тики, как показано в моем примере кода выше. Это поможет вам избежать ошибок разметки, приводящих к проблемам с компонентами Vue и многочасовой отладке.
Еще одна ссылка: проверьте «Многострочные строки» на этой странице:https://developers.google.com/web/updates/2015/01/ES6-Template-Strings
Соответствующие строки (скопированы со страницы выше):
Любой пробел внутри синтаксиса обратной ссылки также будет считаться частью строки.
console.log(`string text line 1
string text line 2`);
РЕДАКТИРОВАТЬ: обнаружена возможная ошибка в коде
Вот еще одна проблема в вашем create
методе favourite-button
компонента:
methods: {
// ...
create() {
Spark.post('/api/favourite', this.form)
.then(favourite => {
this.favourite.push(favourite); // Note: This is the problem area
this.form.id = '';
});
},
//...
}
Ваш обработчик успеха ссылается на this.favourite.push(...)
. У вас нет this.favourite
в data
или props
вашего компонента. Разве это не должно быть this.favourites
?
Комментарии:
1. Спасибо, мани, я не заметил </button>, я также перенял вашу обратную ссылку для многострочных шаблонов — очень полезно!
2. Однако это не исправило реактивность кнопки. Я все еще изучаю решение.
3. @BenF Можете ли вы проверить мои правки в ответе выше? В вашем
create
методеfavourite-button
компонента есть потенциальная ошибка.4. принял к сведению и благодарит. По какой-то причине оба
this.favourite.push(favourite);
иthis.favourites.push(favourite);
работают. Проблема в том, что я не вижу кнопку реактивной, потому что я не вызываюisFavourite
динамическиdata
?5. Я удивлен, что this.favourite.push работает, так как в идеале он должен выдавать ошибку типа
cannot invoke push on undefined
. Тем не менее, вашеisFavourite
является вычисляемым свойством, которое мне кажется нормальным. Он не обязательно должен быть частью вашегоdata
, если вы правильно вычисляете его значение. Это не похоже на проблему с визуализацией Vue, но логику вашего приложения необходимо тщательно оценить, используяconsole.log
во многих местах, используя предварительно определенные тестовые данные, для которых вы знаете результат. Самое главное, вам нужно проверить вычисляемое свойство наisFavourite
правильность логики.