materialize - 无法使用 NextJS 实现 Materialize-CSS 初始化脚本
问题描述
我正在使用Materialize CSS来设置我正在开发的 Web 应用程序的样式。我正在使用 NextJS 和 ReactJS 构建应用程序。我已经使用 Materialize CSS 文件中定义的类设置了导航栏的样式。但是,我无法按照Materialize 网站上的说明使用规定的初始化脚本来实现响应式侧边栏功能。
我的导航栏组件 (./components/Navbar.js) 如下所示:
import React, { Component, Fragment } from 'react';
import Link from 'next/link';
import $ from 'jquery';
class Navbar extends Component {
constructor(props) {
super(props)
this.props = props;
}
componentDidMount = () => {
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('.sidenav');
var instances = M.Sidenav.init(elems, options);
});
}
render() {
return (
<Fragment>
<nav>
<div className="nav-wrapper blue">
<Link prefetch href='/'>
<a href="/" className="brand-logo">Project Coco</a>
</Link>
<a href="#" data-target="slide-out" className="sidenav-trigger"><i className="material-icons">menu</i></a>
<ul id="nav-mobile" className="right hide-on-med-and-down">
<li>
<Link prefetch href='/'>
<a>Home</a>
</Link>
</li>
<li>
<Link prefetch href='/about'>
<a>About</a>
</Link>
</li>
<li>
</li>
</ul>
</div>
</nav>
{/* Sidenav markup */}
<ul className="sidenav" id="slide-out">
<li>
<Link prefetch href='/'>
<a>Home</a>
</Link>
</li>
<li>
<Link prefetch href='/about'>
<a>About</a>
</Link>
</li>
</ul>
</Fragment>
);
}
}
export default Navbar;
很明显,这个功能(侧边栏)需要 JQuery。所以我已经通过添加它yarn
并正在使用它来调用它import $ from 'jquery'
。但是在运行时,它会抛出一个错误,说sidenav is not a function。
我什至尝试完全取消 JQuery,只使用初始化脚本的 vanilla JS 版本componentDidMount
:
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('.sidenav');
var instances = M.Sidenav.init(elems, options);
});
但这一次,虽然没有错误,但该功能仍然无法正常工作,并且单击汉堡菜单不会触发应该触发的 sidenav。
整个代码库都在Github上供参考,原型应用程序在shandillia.com上运行。有什么解决办法吗?
PS:似乎问题在于初始化代码在ComponentDidMount
MaterializeCSS.js (被称为外部文件)之前执行,它依赖于它。解决这个问题的任何工作都可能是一个潜在的解决方案,尽管这只是一个假设。
解决方案
您需要将 materialize-css 导入到您的组件中。可悲的是,如果你尝试这样做,import 'materialize-css'
你会得到一个window is undefined
错误。window
这是因为 Next.js 是通用的,这意味着它首先在不存在的服务器端执行代码。我用于此问题的解决方法如下:
如果您还没有安装 materialize-css:
$ npm i materialize-css
仅当window
定义时才将 materialize-css 导入您的组件:
if (typeof window !== 'undefined') {
window.$ = $;
window.jQuery = $;
require('materialize-css');
}
然后,在您的componentDidMount
方法中:
componentDidMount = () => {
$('.sidenav').sidenav();
}
所以你的组件看起来像这样:
import React, { Component, Fragment } from 'react';
import Link from 'next/link';
import $ from 'jquery';
if (typeof window !== 'undefined') {
window.$ = $;
window.jQuery = $;
require('materialize-css');
}
class Navbar extends Component {
constructor(props) {
super(props)
this.props = props;
}
componentDidMount = () => {
$('.sidenav').sidenav();
}
render() {
return (
<Fragment>
<nav>
...
</nav>
{/* Sidenav markup */}
<ul className="sidenav" id="slide-out">
...
</ul>
</Fragment>
);
}
}
export default Navbar;
资料来源:Next.js FAQ和这个问题。
推荐阅读
- c# - CKFinder ConnectorBuilder 在启动 asp.net mvc Web 应用程序时引发泛型类型定义异常
- python - 我如何只从 PRAW 中获取图片
- java - java.util.List 上的 get(0) 是否总是 O(1)?
- reactjs - 用户授权后如何在所有子组件之间传递状态?
- c++ - 我应该如何在不同的线程中加载图像?
- c++ - C++ 在数组中,我必须在每两个连续元素之间插入乘积和求和。为什么它不起作用,我怎样才能使它起作用?
- python - 尝试从 pip 安装软件包时出现问题
- angular - 以角度显示组件调用元素之间的内容
- php - Composer 安装错误,要求从系统路径中删除
- c++ - 为什么我在调用 [myclass alloc] misx c++ 到 object-c++ 到 object-c 时会出错?