#javascript #object #vue.js #vuejs2
#javascript #объект #vue.js #vuejs2
Вопрос:
Итак, у меня есть следующие данные, и моя цель — пересчитывать результаты пользователя каждый раз, когда данные в этом объекте изменяются. Вот данные.
data() {
return {
test: 0,
userData: {
sex: null,
age: null,
feet: null,
inches: null,
activity: null,
goal: null,
},
}
}
Теперь я попытался реализовать как watch, так и computed, но это приводит к тому, что Vue не замечает, когда изменяются отдельные элементы в объекте. Однако, если я извлекаю некоторые данные из объекта, он замечает изменение.
Вот что я пробовал для watch:
watch: {
userData: function () {
console.log("Changed");
}
}
В результате в консоли ничего не было.
Для computed я попробовал следующее:
computed: {
results: function () {
console.log(this.userData);
return this.userData.sex;
}
}
Но снова в консоли ничего не было напечатано.
Если бы я попытался с помощью тестовой переменной:
watch: {
test: function () {
console.log("Changed");
}
}
При изменении переменной вывод изменился бы. Итак, это работает, потому что это не объект.
Любая помощь была бы очень признательна. Опять же, цель состоит в том, чтобы пересчитывать результаты всякий раз, когда изменяются какие-либо пользовательские данные.
Комментарии:
1. Возможно, вы захотите использовать
Vue.set
иVue.delete
, поскольку Vue не обладает реактивностью для вложенных объектов: vuejs.org/v2/api/#Vue-set2. @match Однако, как я могу запустить функцию при изменении с помощью этого подхода?
3. Просто убедитесь, что любые изменения, которые использует объект
Vue.set
(а не прямое манипулирование объектом — это позволит Vue «заметить», что это изменилось, и вашаwatch
функция будет запущена.4. @match Итак, для sex я мог бы использовать что-то вроде этого?
Vue.set( userData, sex, male )
. И будет ли теперь работать тот же наблюдатель?5. Да — это должно позволить Vue «увидеть» изменение. Возможно, вы также захотите изучить Vuex как лучший способ обработки изменений состояния.
Ответ №1:
Вот один из способов сделать это. Вам нужно (как упоминал @match) использовать Vue.set()
или vm.$set()
. Я обнаружил, что также необходимо обновить ваше свойство watcher до userData.sex
.
new Vue({
el: "#app",
data: {
status: '',
userData: {
sex: ''
},
},
methods: {
updateValues(){
// Or Vue.set()
this.$nextTick( function(){
const newUserData = Object.assign({}, this.userData);
newUserData.sex = "Male";
this.userData = newUserData;
});
}
},
watch: {
userData: function (v) {
this.status = "userData Changed";
},
'userData.sex': function (v) {
this.status = "nuserData.sex Changed";
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.8/dist/vue.min.js"></script>
<div id="app">
<pre v-text="'userData.sex = ' userData.sex"></pre>
<pre v-text="status"></pre>
<button @click="updateValues()">
Change Sex
</button>
</div>
Редактировать:
Повторное назначение всего объекта userData
запускает watch.userData
.
Комментарии:
1. обнаружило бы это изменение, если бы я просматривал userData? Я хочу запускать одну функцию для любого изменения пользовательских данных.
2. @AnthonySette Я обновил код, чтобы заставить это работать, требуется переназначение всего
userData
объекта.
Ответ №2:
Вы на самом деле используете results
свойство (например, в вашем шаблоне)? Вычисленные свойства не пересчитываются, если они не используются.
В отличие от того, что говорит @match, я сомневаюсь, что у вас проблема с реактивностью, поскольку вы не добавляете и не удаляете свойства (они уже существуют в ваших данных, поэтому они уже реактивные).
Комментарии:
1. Я не был, позвольте мне попробовать!
2. Это сработало, вычисленный, который я написал, работал, но у меня не было результатов на странице, поэтому он не был запущен!