Задать вопрос
jackmarston
@jackmarston
human

Почему объект не объект во Vue?

К сожалению не смог воспроизвести в песочнице пример, потому что в песочнице почему-то все работает как надо. Но на рабочем примере все не так. Попробую по простому, хотя уже 10-ый час сижу над двумя чекбоксами и только сейчас нашел почему не работает.

//Значит получаю от сервера ответ 
echo json_encode($res);

//Далее в App.vue ожидаю в data() обьект

data() {
    return {
      user: {
        type: Object,
        default: {}
      }
    }
  }

//теперь в методе я его получаю и записываю
this.user = data.user

//Выводим в шаблоне {{ user }} и получаем
{open_widgets: "1", open_workbook: "0"}

//в базе значения булевые но получили мы строковые
//Далее прокидываем пропсы в дочерний компонент

<children-one :user="user"></shildren-one>

//ChildrenOne.vue

props: {
        user: {
            type: Object,
            required: true
        }
    }


и значения пришли и на экран вывелись. Теперь нам надо их пробросить пропсами отдельно чтобы исходя из значений true или false чекбоксы были либо отмечены либо нет. Однако если мы пробросим как есть то ничего не изменится так как значения строковые, и надо их сделать булевыми. Поэтому делаем 2 computed-а

computed: {
        computedWidgets() {
            if(this.user.open_widgets) {
                return this.user.open_widgets === '1';
            }
        },
        computedWorkbook() {
            if(this.user.open_workbook) {
                return this.user.open_workbook === '1';
            }
        },
    }

//Теперь у нас есть false и true вместо "0" и "1"
//Пробрасываем их в след.вложенный компонент с чекбоксами.

<children-two :userWidgets="computedWidgets" :userWorkbook="computedWorkbook"></shildren-two>

//и ожидаем их в нем

props: {
        userWidgets: {
            type: Boolean
        },
        userWorkbook: {
            type: Boolean
        }
    }

//В шаблоне у нас есть 2 чекбокса представлю их по простому

<input 
@click="widgets = !widgets" 
v-model="widgets"
 >

<input 
@click="workbook = !workbook" 
v-model="workbook"
 >

//это data() данные компонента

data() {
        return {
            widgets: this.userWidgets,
            workbook: this.userWorkbook
        }
    }


Так вот в итоге данные не приняли значения из пропсов, даже исходя из того что computed-ы их таковыми сделали. Но если перейти по маршруту а не перезагрузить страницу то все в порядке и данные применяются а при перезагрузке нет.

И здесь конечно уже руки тянутся юзать стор, но зачем стор для таких мелочей. Тем более все данные уже во всех нужных компонентах лежат так что в сторе нет смысла. Конечно стор это чит но пока хотелось бы без читов обойтись.

Но чтобы понять почему обьект не обьект надо юзать читы.

//Подключаем Pinia стор

const user = ref([]);

return {
        user
    }

//и теперь в App.vue возвращаемся и просто вместо того чтобы записать данные в data() пишем в стор 
//а data() убираем пока для примера

this.store.user = data.user

//далее в сторе делаем так

if(localStorage.getItem('user')) {
        user.value = JSON.parse(localStorage.getItem('user'))
}

watch(
     user,
        (value) => {
            localStorage.setItem('user', JSON.stringify(value));
        },
        {
            deep: true,
        }
);

//и теперь когда в App.vue мы из стора получили

return {
        user
    }

//этот самый user идет пропсами по тому же пути, и после перезагрузки страницы все работает и чекбоксы уже подгружаются исходя из своих булевых значений.


Вопрос: Че за фигня?
Чем отличается
this.user = data.user
от
user.value = JSON.parse(localStorage.getItem('user'))


если на выходе это один и тот же объект только в 1 случае оно не работает как хотелось бы.

Вот здесь пример правда без стора т.к с LocalStorage не удалось воспроизвести, но можно изменить строковое значение на числовое и получим ту же проблему.

https://stackblitz.com/edit/vitejs-vite-k2ryha?fil...
  • Вопрос задан
  • 114 просмотров
Подписаться 1 Средний Комментировать
Пригласить эксперта
Ответы на вопрос 1
@7rows
Frontend Разработчик / Vue / JS / TS / CSS
Что-то глянул код , у вас стоит вотч на эмит, но сам эмит не увидел, что он обрабатывается.
В выводе компонента , вы выводите props, а меняете через switch данные в компоненте, как только вы соедините все через emit, у вас реактивность пропса будет работать.
Можно пойти дальше, и написать компонент, который будет принимать как раз 2 v-model, и не нужно будет прокидывать пропсы, вы тем самым уменьшите 1 уровень проброса emit
По сути, у вас на нижнем уровне данные поменялись, а родитель не увидел.
Вам надо обработать эмит и тогда даные у пользователя обновятся
Еще уберите вотч, если у вас можно изменение обработать по ```@change```
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы