Атрибут данных, привязанный к внешней переменной, не реагирует на изменения переменных - PullRequest
0 голосов
/ 11 сентября 2018

Я начинаю включать Vue.js (v2.5.17) для нескольких мелких вещей на сайте электронной коммерции, но я новичок в Vue и у меня возникли некоторые проблемы. Из-за некоторой структуры блейда Laravel, которую у меня нет возможности рефакторинга в настоящее время, я должен разделить различные части этой функциональности на отдельные компоненты, и у меня возникают проблемы с данными в одном экземпляре Vue, реагирующими на события с другой.

Вот CodePen с урезанной версией проблемы: https://codepen.io/jgabrielsen/pen/bxRroM/

Для удобства пользования JS:

var cartStore = {
    state: {
        products: [PRODUCT ARRAY],
        active: false
    },
}

var cartHeader = new Vue({
    el: '#cartHeader',
    data: {
        products: cartStore.state.products,
    },
    methods: {
        setActiveTrue: function() {
            cartStore.state.active = true;
            console.log('Show Cart');
        },
        setActiveFalse:function() {
            cartStore.state.active = false;
            console.log('Hide Cart');
        },          
    },
})

var cartPreview = new Vue({
    el: '#cartPreview',
    data: {
        products: cartStore.state.products,
        active: cartStore.state.active,
    },
    methods: {
        total: function() {
            var sum = 0;
            for (var i = 0; i < this.products.length; i++) {
                sum += this.products[i][1]
            }
            return sum
        },
    },
})

И HTML

<div class="header">
    <a id="cartHeader" @mouseover="setActiveTrue" @mouseout="setActiveFalse">CART({{ this.products.length }})</a>
</div>

<div id="cartPreview" v-show="active">
    <ul>
        <li v-for="product in products">
            <div class="col-80">
                {{ product[0] }}
            </div>
            <div class="col-20" style="text-align:right;">
                ${{ product[1] }}
            </div>
        </li>
    </ul>
    <div class="row">
        <div class="col-100" style="text-align:right;">
            Total Products: {{ this.products.length }}<br>
            Total: ${{ this.total() }}
        </div>
    </div>
</div>

Короче говоря, мне нужно, чтобы экземпляр cartPreview отображался при наведении на экземпляр cartHeader (основной эффект поповера).

Вот как я сейчас пытаюсь это сделать:

  • У меня есть var cartStore, который содержит массив всех данных предварительного просмотра корзины, а также состояние active.

  • cartPreview имеет атрибут данных active, связанный с cartStore.state.active (который по умолчанию равен false) and v-show="active", поэтому он скрыт, пока что-то не установит свой атрибут данных active в true.

  • cartHeader имеет @mouseover="setActiveTrue" и @mouseout="setActiveFalse", чтобы переключать атрибут cartPreview active через связанное состояние в cartStore.

Я могу сказать, что события mouseover и mouseout запускаются, потому что cartStore.state.active действительно изменяется на true и false правильно, и консоль регистрирует запись, но соответствующий атрибут данных в cartPreview не реагирует на эти изменения.

Мне кажется, что я, должно быть, упускаю из виду что-то очень простое и / или допускаю серьезные ошибки нубов, но после того, как десятки раз просматривал мой код и искал все выше и ниже, я озадачился, почему он не реагирует.

1 Ответ

0 голосов
/ 12 сентября 2018

Я наконец-то нашел решение.

cartStore.state.products был реагирующим между cartHeader и cartPreview для добавления и удаления продуктов (методы, которые я удалил из моего примера, потому что я не думал, что они актуальны), но cartStore.state.active не было. Единственное отличие, которое я видел, было то, что данные корзины в products хранились в массиве, а active - нет, поэтому я создал cartStore.state.active массив:

var cartStore = {
    state: {
        products: [PRODUCT ARRAY],
        active: [ false ]
    },
}

... обновил его до splice:

methods: {
    setActiveTrue: function() {
        this.active.splice(0,1,true);
    },
    setActiveFalse:function() {
        this.active.splice(0,1,false);
    },          
},

... и добавил v-show="active[0]" к компоненту, и вот, это работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...