Я создаю панель инструментов с Laravel и VueJS, я создал кнопку, которая позволяет увеличить или уменьшить мою боковую панель в компоненте Sidebar.vue, вот мои компоненты:
<template>
<aside :class = "`${is_expanded ? 'is-expanded' : ''}`">
<div class = "head-aside">
<div class = "app-logo">
<i class = "bx bxl-trip-advisor"></i>
</div>
<span class = "app-name">CONTROLPANEL</span>
</div>
<div class = "menu-toggle-wrap">
<button class = "menu-toggle" @click = "ToggleMenu()">
<span class = "boxicons"><i class = "bx bx-chevrons-right"></i></span>
</button>
</div>
</aside>
</template>
<script>
export default {
data() {
return {
is_expanded: ref(localStorage.getItem('is_expanded') === 'true'),
}
},
methods: {
ToggleMenu() {
this.is_expanded = !this.is_expanded
localStorage.setItem('is_expanded', this.is_expanded)
},
},
}
</script>
Возникающая проблема заключается в том, что в другом компоненте я создал навигационную панель с фиксированной шириной, и я хотел бы сделать так, чтобы при изменении размера моей боковой панели я хотел, чтобы моя навигационная панель также менялась, в другом компоненте у меня просто есть шаблон с навигация и импорт моей боковой панели.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Этот код работает нормально
<template>
<aside :class = "`${is_expanded ? 'is-expanded' : ''}`">
<div class = "head-aside">
<div class = "app-logo">
<i class = "bx bxl-trip-advisor"></i>
</div>
<span class = "app-name">CONTROLPANEL</span>
</div>
<div class = "menu-toggle-wrap">
<button class = "menu-toggle" @click = "ToggleMenu()">
<span class = "boxicons">
<i class = "bx bx-chevrons-right"></i>click me
</span>
</button>
</div>
</aside>
</template>
<script>
export default {
data() {
return {
is_expanded: localStorage.getItem("is_expanded") === "true",
};
},
methods: {
ToggleMenu() {
this.is_expanded = !this.is_expanded;
localStorage.setItem("is_expanded", this.is_expanded);
},
},
};
</script>
Вот GIF, показывающий результат в действии: https://share.cleanshot.com/TtKsUj
эй, да, этот код работает нормально, но в другом компоненте у меня есть панель навигации с фиксированной шириной, и я хочу одновременно переключать ее ширину
как вы можете видеть на этой гифке imgflip.com/gif/6wsrli
@furaxsme смотреть некоторые localStorage в целом немного сложнее. Я предполагаю, что вы могли бы использовать этот или этот подход (немного более продвинутый), но нет дружественного способа получить к нему доступ, поскольку он сам по себе не является реактивным. Да и нужно ли оно здесь? Вы можете иметь более высокое состояние или даже использовать хранилище (Vuex, Pinia) для обработки глобального состояния, то есть замены вашего локального хранилища.
Сделайте локальное хранилище реактивным, используя наблюдатель и установив для его свойства deep значение true. https://vuejs.org/guide/essentials/watchers.html#deep-watchers или если вы используете vue2, используйте шину событий
Наблюдатель может наблюдать только за реактивной опорой.
Ваш ответ может быть улучшен с помощью дополнительной вспомогательной информации. Пожалуйста, отредактируйте , чтобы добавить дополнительные сведения, такие как цитаты или документация, чтобы другие могли подтвердить правильность вашего ответа. Вы можете найти больше информации о том, как писать хорошие ответы в справочном центре.
Вы говорите, что используете laravel с vue. Непонятно, как интегрируются компоненты vue, но я предполагаю, что laravel внедряет отдельные компоненты vue, которые вы хотели бы сообщить. (в отличие от SPA на основе vue, который взаимодействует с laravel только с использованием API)
Два компонента не знают друг о друге. Несмотря на то, что они оба имеют доступ к одному и тому же локальному хранилищу, они не знают, когда значения там обновляются.
Есть несколько способов справиться с этим, вот один из способов
создать реактивный объект вне компонентов для управления общим состоянием
import { ref, computed } from 'vue'
const isExpandedRef = ref(localStorage.getItem('is_expanded') === 'true');
window.IS_EXPANDED = computed({
get(){
return isExpandedRef.value
},
set(value){
isExpandedRef.value = !!value;
localStorage.setItem('is_expanded', isExpandedRef.value);
}
})
ref требуется, чтобы при изменении isExpandedRef.value вычисляемый геттер запускал уведомления для своих слушателей.
Если вы загрузите это перед любым из компонентов, вы создадите вычисляемую (реактивную) переменную, доступную для любого скрипта на странице (кроме фреймов и теневого дома)
то вы можете использовать в своих компонентах, как это.
<template>
<aside :class = "`${is_expanded ? 'is-expanded' : ''}`">
<div class = "head-aside">
<div class = "app-logo">
<i class = "bx bxl-trip-advisor"></i>
</div>
<span class = "app-name">CONTROLPANEL</span>
</div>
<div class = "menu-toggle-wrap">
<button class = "menu-toggle" @click = "is_expanded = !is_expanded">
<span class = "boxicons"><i class = "bx bx-chevrons-right"></i></span>
</button>
</div>
</aside>
</template>
<script>
export default {
data() {
return {
is_expanded: window.IS_EXPANDED,
}
},
}
</script>
поскольку is_expanded вычисляется с помощью геттеров и сеттеров, вы можете установить значение прямо из шаблона или использовать this.is_expanded = !this.is_expanded в методах.
Как уже говорилось, это зависит от использования глобального объекта window. Это решение предлагается из-за его простоты. У использования объекта окна есть некоторые недостатки, и более надежное решение будет полагаться на внедрение такого общего состояния вместо того, чтобы полагаться на окно, но это связано с большими накладными расходами.
refпредназначен для Composition API, если вы используете Options API сdata,methodsи т. д., он вам не нужен.