到了redux状态管理后,感觉之前的目录都没发看了,所以重构一下吧。
重构
之前的目录结构有点乱,对于一个项目来说不是一个好事。不说多人合作,一个人维护也够呛。
redux安装跟前端一样
cnpm install --save redux react-redux
先看一下目录结构
-- root
| -- src // 模板等资源放在这里
| -- components // 模板
| -- constants // 常量
| -- pages // 路由
| -- store // reducer等存放
| -- reducers
| -- actions
| -- index.js // 入口
| -- styles // 公共css
| -- static // 静态资源
| -- .babelrc
| -- next.config.js
| -- package.json
因为改动太大, 我就不一一把文件写出来了,挑几个重点的说下。
src目录
因为大部分前端框架都是从src开始的,而且next打包后会在根目录生成文件夹以及编译后的文件夹等等,如果全放到外面则会显得比较混乱。并且next是支持这样写的,会默认读取外层的pages,如果没有则会读取src里的pages。 还有一点,static是默认放静态资源的目录,如果需要,可以使用"/static/1.png"这样写。
_app.js
import React from 'react'
import { Provider } from 'react-redux'
import 'antd/dist/antd.css';
import '@/styles/style.scss';
import store from '@/store'
export default function MyApp({ Component, pageProps }) {
return <Provider store={store}>
{/*这里可以加公共头信息*/}
<Component {...pageProps} />
</Provider>
}
如果需要加入公共的头部信息是可以写到以上注释部分的,比如
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0,viewport-fit=cover">
适配手机端等,每个页面都需要的。
title,关键字等meta标签适配不同页面
比如a.js页面title是“这是a页面”,b.js页面title是“这是b页面”。这时_app.js改如何配置呢。
如果分别在各页面写Head,则会报错,只能在_app.js里写入头部。所以_app的props就起到作用了,可以获取到其他页面的模板和props。所以只需在_app.js里改写好就可。
// _app.js 标题如下
export default class MyApp extends Component {
render () {
const { Component, pageProps } = this.props;
const {
m_title='有趣实用网——收藏各类好玩沙雕实用的网站',
m_description='收集各类,有趣、实用、新奇、沙雕、恶搞又好玩以及各类白嫖动漫,漫画的网站。',
m_keywords='好玩,有趣,实用,有意思的网站,有趣的网站,好玩的网站,实用的网站,沙雕网站'
} = pageProps;
// console.log(pageProps)
return <Provider store={store}>
<Head>
<title>{m_title}</title>
<link rel="icon" href="/favicon.ico" />
<meta name="baidu-site-verification" content="S6kx3QAdX2" />
<meta name="sogou_site_verification" content="OTrlpJrfft"/>
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0,viewport-fit=cover" />
<meta
name="description"
content={filterHTMLTag(m_description)}
/>
<meta name="keywords" content={m_keywords} />
</Head>
<div id="root">
<Header></Header>
<div className="container main-content-wrapper">
<Component {...pageProps} />
</div>
</div>
<Loading />
<Dialog />
<AddWebSite isEdit={false} renderCb={ctx => eventBus.on('getAddSite#addSite', () => ctx) } />
<AddWebSite isEdit={true} renderCb={ctx => eventBus.on('getEditSite#editSite', () => ctx) } />
</Provider>
}
}
而其他页面的数据则在 getServerSideProps里添加 初始meta所需值
export async function getServerSideProps(context) {
const { query: { id }, req } = context;
const res = await axios.get(serverUrl+'/getSiteDetail', { params: { site_id: id }, headers: getServeAuthorization(req) }, )
const data = res.data.result || {}
return {
props: {
data,
m_title: data.name && '有趣实用网——' + data.name,
m_keywords: data.name && (data.name+','+data.tags.join(',')),
m_description: data.desc && data.desc
// defaultList: res.data.result.list,
// defaultTotal: res.data.result.total
},
}
}
import 使用@代表src目录
相信大家导入文件都习惯了@代表src目录,那样引入文件就可以不需要相对路径,特别是当前这么目录下,一个一个慢慢对比找相对路径就显得很麻烦,所以这里就单独抽出来。
先安装这个包
cnpm install --save-dev customize-cra
之后修改next.config.js
const path = require('path')
const withSass = require('@zeit/next-sass')
const withCss = require('@zeit/next-css');
const withPlugins = require("next-compose-plugins");
const { override, adjustStyleLoaders, addWebpackAlias } = require("customize-cra");
module.exports = withPlugins([withSass,withCss], {
webpack: override(addWebpackAlias({
'@': path.resolve('src'),
}))
});
重启,ok完美运行。
这里就不放图了,git地址
数据联动
git地址跟上面一样,分支dataAcc
挑几个重点,新建了server文件夹,用于区分服务端的代码。
页面预渲染数据getServerSideProps
当一个页面在用户看到之前就应该有数据出来,则可以使用这个函数。emm也不知道这么解释对不对,就拿我那个页面来说,在用户进来之后,会等待很长一段时间,长时间的看loading。如果能在loading之前就把数据加载好,那就不会觉得等待很长。下面看getServerSideProps是如何使用的。
这个实在index.js里的部分代码
export async function getServerSideProps() {
const res = await axios.get(url+'/test/list')
const list = res.data.data;
return {
props: {
list,
},
}
}
getServerSideProps这个函数只能放在pages下才会有效,子模块是不会生效的。形式固定
export async function getServerSideProps() {
return {
props: {
},
}
}
不可改变大体结构。具体的坑点还无法得知,毕竟没有开始正式写代码,只是大致的体验了一把,还是蛮不错的。