使用Livewire wire:navigate时JS与@frostui/tailwind功能失效
使用Livewire的wire:navigate在侧边栏、顶部栏等区域实现无刷新页面跳转时,出现@frostui/tailwind CSS框架及自定义app.js中的功能失效问题。已尝试监听wire:navigate、wire:navigating、wire:navigated事件,以及使用wire:key属性,但均未解决,尤其@frostui/tailwind功能在跳转后无法再次触发。相关代码如下:
app.js代码
import "@frostui/tailwindcss" import axios from 'axios'; import feather from 'feather-icons'; window.axios = axios; import.meta.glob([ "../images/**", ]); class App { initComponents() { feather.replace() const myButton = document.querySelector('[data-toggle="back-to-top"]'); if (myButton) { window.addEventListener('scroll', function () { if (window.pageYOffset > 72) { myButton.classList.add('flex'); myButton.classList.remove('hidden'); } else { myButton.classList.remove('flex'); myButton.classList.add('hidden'); } }); myButton.addEventListener('click', function (e) { e.preventDefault(); window.scrollTo({ top: 0, behavior: 'smooth' }); }); } } init() { this.initComponents(); } } class ThemeCustomizer { constructor() { this.html = document.getElementsByTagName('html')[0] this.config = {}; this.defaultConfig = window.config; } initConfig() { this.defaultConfig = JSON.parse(JSON.stringify(window.defaultConfig)); this.config = JSON.parse(JSON.stringify(window.config)); this.setSwitchFromConfig(); } initSidenav() { let self = this; let pageUrl = window.location.href.split(/[?#]/)[0]; document.querySelectorAll('ul.menu a.menu-link').forEach((element) => { if (element.href === pageUrl) { element.classList.add('active'); let parentMenu = element.parentElement.parentElement.parentElement; if (parentMenu && parentMenu.classList.contains('menu-item')) { const collapseElement = parentMenu.querySelector('[data-fc-type="collapse"]'); if (collapseElement && frost != null) { const collapse = frost.Collapse.getInstanceOrCreate(collapseElement); collapse.show(); } } } }) setTimeout(function () { let activatedItem = document.querySelector('ul.menu .active'); if (activatedItem != null) { let simpleBarContent = document.querySelector('.app-menu .simplebar-content-wrapper'); let offset = activatedItem.offsetTop - 300; if (simpleBarContent && offset > 100) { scrollTo(simpleBarContent, offset, 600); } } }, 200); // scrollTo (Sidenav Active Menu) function easeInOutQuad(t, b, c, d) { t /= d / 2; if (t < 1) return c / 2 * t * t + b; t--; return -c / 2 * (t * (t - 2) - 1) + b; } function scrollTo(element, to, duration) { let start = element.scrollTop, change = to - start, currentTime = 0, increment = 20; let animateScroll = function () { currentTime += increment; element.scrollTop = easeInOutQuad(currentTime, start, change, duration); if (currentTime < duration) { setTimeout(animateScroll, increment); } }; animateScroll(); } } changeThemeMode(color) { this.config.theme = color; this.html.setAttribute('data-mode', color); this.setSwitchFromConfig(); } changeTopbarColor(color) { this.config.topbar.color = color; this.html.setAttribute('data-topbar-color', color); this.setSwitchFromConfig(); } changeMenuColor(color) { this.config.menu.color = color; this.html.setAttribute('data-menu-color', color); this.setSwitchFromConfig(); } changeSidenavView(view, save = true) { this.html.setAttribute('data-sidenav-view', view); if (save) { this.config.sidenav.view = view; this.setSwitchFromConfig(); } } initSwitchListener() { let self = this; document.querySelectorAll('input[name=data-mode]').forEach(function (element) { element.addEventListener('change', function (e) { self.changeThemeMode(element.value); }) }); document.querySelectorAll('input[name=data-topbar-color]').forEach(function (element) { element.addEventListener('change', function (e) { self.changeTopbarColor(element.value); }) }); document.querySelectorAll('input[name=data-menu-color]').forEach(function (element) { element.addEventListener('change', function (e) { self.changeMenuColor(element.value); }) }); document.querySelectorAll('input[name=data-sidenav-view]').forEach(function (element) { element.addEventListener('change', function (e) { self.changeSidenavView(element.value); }) }); // 明暗切换按钮 let themeColorToggle = document.getElementById('light-dark-mode'); if (themeColorToggle) { themeColorToggle.addEventListener('click', function (e) { if (self.config.theme === 'light') { self.changeThemeMode('dark'); } else { self.changeThemeMode('light'); } }); } // 菜单切换按钮(位于顶部栏) let menuToggleBtn = document.querySelector('#button-toggle-menu'); if (menuToggleBtn) { menuToggleBtn.addEventListener('click', function () { let configView = self.config.sidenav.view; let view = self.html.getAttribute('data-sidenav-view', configView); if (view === 'mobile') { self.showBackdrop(); self.html.classList.toggle('sidenav-enable'); } else { if (configView == 'hidden') { if (view === 'hidden') { self.changeSidenavView(configView == 'hidden' ? 'default' : configView, false); } else { self.changeSidenavView('hidden', false); } } else { if (view === 'sm') { self.changeSidenavView(configView == 'sm' ? 'default' : configView, false); } else { self.changeSidenavView('sm', false); } } } }); } } showBackdrop() { const backdrop = document.createElement('div'); backdrop.id = 'backdrop'; backdrop.classList = 'transition-all fixed inset-0 z-40 bg-gray-900 bg-opacity-50 dark:bg-opacity-80'; document.body.appendChild(backdrop); if (document.getElementsByTagName('html')[0]) { document.body.style.overflow = "hidden"; if (window.innerWidth > 1140) { document.body.style.paddingRight = "15px"; } } const self = this backdrop.addEventListener('click', function (e) { self.html.classList.remove('sidenav-enable'); self.hideBackdrop(); }) } hideBackdrop() { let backdrop = document.getElementById('backdrop'); if (backdrop) { document.body.removeChild(backdrop); document.body.style.overflow = null; document.body.style.paddingRight = null; } } initWindowSize() { let self = this; window.addEventListener('resize', function (e) { self.adjustLayout(); }) } adjustLayout() { let self = this; if (window.innerWidth <= 1140) { self.changeSidenavView('mobile', false); } else { self.changeSidenavView(self.config.sidenav.view); } } setSwitchFromConfig() { sessionStorage.setItem('__CONFIG__', JSON.stringify(this.config)); document.querySelectorAll('#theme-customization input[type=radio]').forEach(function (radio) { radio.checked = false; }) let config = this.config; if (config) { let layoutModeSwitch = document.querySelector('input[type=radio][name=data-mode][value=' + config.theme + ']'); let topbarColorSwitch = document.querySelector('input[type=radio][name=data-topbar-color][value=' + config.topbar.color + ']'); let menuColorSwitch = document.querySelector('input[type=radio][name=data-menu-color][value=' + config.menu.color + ']'); let sidenavViewSwitch = document.querySelector('input[type=radio][name=data-sidenav-view][value=' + config.sidenav.view + ']'); if (layoutModeSwitch) layoutModeSwitch.checked = true; if (topbarColorSwitch) topbarColorSwitch.checked = true; if (menuColorSwitch) menuColorSwitch.checked = true; if (sidenavViewSwitch) sidenavViewSwitch.checked = true; } } init() { this.initConfig(); this.initSidenav(); this.initSwitchListener(); this.initWindowSize(); this.adjustLayout(); this.setSwitchFromConfig(); } } new App().init(); new ThemeCustomizer().init();
config.js代码
(function () { let savedConfig = sessionStorage.getItem("__CONFIG__"); // let savedConfig = localStorage.getItem("__CONFIG__"); let defaultConfig = { theme: "dark", topbar: { color: "dark", }, menu: { color: "dark", }, sidenav: { view: "default" }, }; const html = document.getElementsByTagName("html")[0]; let config = Object.assign(JSON.parse(JSON.stringify(defaultConfig)), {}); config.theme = html.getAttribute("data-mode") || defaultConfig.theme; config.topbar.color = html.getAttribute("data-topbar-color") || defaultConfig.topbar.color; config.menu.color = html.getAttribute("data-menu-color") || defaultConfig.menu.color; config.sidenav.view = html.getAttribute("data-sidenav-view") || defaultConfig.sidenav.view; window.defaultConfig = JSON.parse(JSON.stringify(config)); if (savedConfig !== null) { config = JSON.parse(savedConfig); config.sidenav.view = html.getAttribute("data-sidenav-view") || defaultConfig.sidenav.view; } window.config = config; if (config) { html.setAttribute("data-mode", config.theme); html.setAttribute("data-topbar-color", config.topbar.color); html.setAttribute("data-menu-color", config.menu.color); if (window.innerWidth <= 1140) { html.setAttribute("data-sidenav-view", "mobile"); } else { html.setAttribute("data-sidenav-view", config.sidenav.view); } } })();
wire:navigate示例标签
<a wire:navigate class="flex items-center py-2 px-3 rounded-md text-sm text-gray-800 hover:bg-gray-100 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-gray-300" href="{{ route('profile.edit') }}"> <i class="mgc_pic_2_line me-2"></i> <span>@lang('Profile')</span> </a>
包含Livewire组件的视图
<x-app-layout :title="__('Profile')"> <x-slot name="header"> <h2 class="font-semibold text-xl text-gray-800 dark:text-gray-200 leading-tight"> {{ __('Profile') }} </h2> </x-slot> <div class="py-12"> <div class="max-w-7xl mx-auto sm:px-6 lg:px-8 space-y-6"> <div class="p-4 sm:p-8 bg-white dark:bg-gray-800 shadow sm:rounded-lg"> <div class="max-w-xl"> <livewire:admin.profile.update-profile-information /> </div> </div> <div class="p-4 sm:p-8 bg-white dark:bg-gray-800 shadow sm:rounded-lg"> <div class="max-w-xl"> <livewire:admin.profile.update-password /> </div> </div> </div> </div> </x-app-layout>
内容的提问来源于stack exchange,提问作者Nikola Main
相关产品推荐
相关产品推荐

