zoukankan      html  css  js  c++  java
  • Next

    笔记来自
    技术胖视频
    github项目

    使用

    • react必须是16.x以上
    • 安装
    npm install next react react-dom --save
    
    • 文件夹static,固定,所有的静态文件,图片都放在这里面,不会被打包进.next
    • css样式打包
    npm install @zeit/next-css --save-dev
    
    • next.config.js
    // 使用了这个之后,项目里使用到的css都会被打包到.next/static/css文件夹下
    const withCSS = require('@zeit/next-css')
    
    // fix: prevents error when .css files are required by node
    if (typeof require !== 'undefined') {
      require.extensions['.css'] = (file) => {}
    }
    
    module.exports = withCss();
    
    • page/_app.js
    // 这是入口文件,也就是第一加载的js
    // 在这里引入css,router,redux
    // 还有判断token等
    
    import React from 'react'
    import App from 'next/app'
    import { Provider } from 'react-redux'
    import withRedux  from 'next-redux-wrapper'
    import { Router } from 'next/router'
    import API from '../api/api'
    import Layout from '../components/Layout'
    import PageLoading from '../components/PageLoading'
    import makeStore from '../store/store'
    import {getJwt} from '../lib/auth'
    
    class MyApp extends App {
      static async getInitialProps({Component, ctx,router}) {
            let {reduxStore,req} = ctx;
            let {dispatch} = reduxStore;
            let pageProps = {}
            let token = getJwt({req});
            if (Component.getInitialProps) {
                pageProps = await Component.getInitialProps(ctx)
            }
            if(token&&!!req){
                let res = await API.getUserInfo({token})
                if (res.data.code === 1) {
                    let {username,avatar,_id} = res.data.data;
                    dispatch(updateInfo({
                        avatar,
                        username,
                        userId:_id
                    }))
                }
            }
            return { pageProps }
      }
    
      state = {
         loading: false
      }
    
      startLoading = () => {
         this.setState({
            loading: true
         })
      }
      stopLoading = () => {
         this.setState({
            loading: false
         })
      }
      componentDidMount () {
        Router.events.on('routeChangeStart', this.startLoading)
        Router.events.on('routeChangeComplete',this.stopLoading)
        Router.events.on('routeChangeError', this.stopLoading)
      }
      componentWillUnmount() {
        Router.events.off('routerChangeStart', this.startLoading)
        Router.events.off('routerChangeComplete',this.stopLoading)
        Router.events.off('routerChangeError', this.stopLoading)
      }
    
      render() {
         const {Component, pageProps, store} = this.props
         return (
            <div>
              <Provider store={store}>
                <Layout>
                  { this.state.loading ? <PageLoading/> : null}
                  <Component {...pageProps} />
                </Layout>
              </Provider>
           </div>
         )
       }
    }
    
    export default withRedux(makeStore)(MyApp);
    
    • 打包在.next文件夹下的文件会被自动生成一个html文件,渲染到浏览器端
    • 也可以自定义html
    // _document.js
    import Document, { Head, Main, NextScript } from 'next/document'
    
    export default class MyDocument extends Document {
        render() {
            return (
                <html>
                  <Head>
                    // 这里不要设置title标签,原因往下看 
                    <style>{
                        'body{color:red}'
                    }</style>
                  </Head>
                  <body className="custom_class">
                     123123
                     <Main />
                     <NextScript />
                  </body>
                </html>
            )
        }
    }
    
    • 错误页面
    // _error.js
    // next自带_error.js这个可以在.next里找到这个页面,如果觉得不好看
    // 重写就行
    
    import React from 'react'
    
    export default class Error extends React.Component {
      static async getInitialProps({ res, err }) {
        const statusCode = res ? res.statusCode : err ? err.statusCode : null;
        return { statusCode }
      }
    
      render() {
        return (
          <p>
            {this.props.statusCode
              ? `An error ${this.props.statusCode} occurred on server`
              : 'An error occurred on client'}
          </p>
        )
      }
    }
    
    • 路由,跟nuxt一样,根据pages文件夹的文件摆放生成的,但是还是需要添加进路由里
    pages/
    --| _slug/
    -----| index.vue
    --| users/
    -----| _id.vue // 注意这里是下划线
    --| index.vue
    
    // 生成
    <Switch>
      <Route path="/" exact component={pages/index.jsx} />
      <Route path="/:slug" component={pages/_slug/index.jsx} />
      <Route path="/users/:id" component={pages/users/_id.jsx} />
    </Switch>
    
    • 组件添加进路由里,添加redux
    import React, { Component } from 'react'
    import { connect } from 'react-redux'
    import { Button,Icon, Tabs } from 'antd'
    import { withRouter } from 'next/router'
    import API from '../../api/api'
    import { setArticles } from "../store/articles/action"
    
    class LoginComponent extends Component {
      // 这是componentDidMount前的服务器生命周期
      static async getInitialProps({Component, ctx,router}) {
            let {reduxStore,req} = ctx;
            // 取值
            let article = reduxStore.getState().article
            let {dispatch} = reduxStore;
            let articleList = await API.getArticleList();
            // 更新
            dispatch(setArticles(articleList))
            // 这些数据都在this.props里
            return { articleList, article  }
      }
      state = { }
      render() {
        const { articleList,article} = this.props
        return (
            <div>
                // 如果想给页面添加title,就在return添加title标签
                <title>一个路由一个title</title>
                {resBlog}
            </div>
        )
    }
    
    export default connect(state => ({
      article: state.article,
    }), {
      setArticles
    })(withRouter(Text));
    
    • redux,跟redux一样,查看【JS/redux】笔记
    // store/article/action.js
    import * as article from './action-type';
    
    export const setArticles = (articleList) => {
      return {
        type: article.SAVEFORMDATA,
        articleList: articleList,
      }
    }
    
    // store/article/action-type.js
    export const SAVEFORMDATA = 'SAVEFORMDATA';
    
    // store/article/reducer.js
    import * as article from './action-type';
    
    let defaultState = {
      article:"测试"
    }
    // 首页表单数据
    export const article = (state = defaultState , action = {}) => {
      switch(action.type){
        case article.SAVEFORMDATA:
          // 这个state是defaultState,articleList是action.js传过来的
          // 这是个合并并更新defaultState的操作
          return {...state, ...{ articleList }};
        default:
          return state;
      }
    }
    
    • server/index.js
    // 起个服务器,不会的查看【Koa】笔记
    const Koa = require('koa')
    const next = require('next')
    const Router = require('koa-router')
    const Redis  = require('koa-redis')
    const session = require('koa-session')
    const json = require('koa-json')
    const bodyParser = require('koa-bodyparser')
    
    //开发状态
    const port = 3000
    const dev = process.env.NODE_ENV !== 'production'
    const app = next({ dev })
    
    //http响应
    const handle = app.getRequestHandler()
    
    //页面编译完成后响应请求
    app.prepare().then(()=>{
      const server = new Koa()
      const router = new Router()
      server.proxy = true
    
      server.use(bodyParser({
        entableTypes: ['json','form','text']
      }))
      server.use(json())
      server.keys= ['_ayuan#']
      server.use(session(SESSION_CONFIG,server))
    
      // 接口路由
      router.get('/login', async (ctx) => {
         ...
      })
    
      server.use(router.routes())
    
      //监听
      server.use(async (ctx,next) => {
        ctx.req.session = ctx.session
        await handle(ctx.req, ctx.res)
        //不处理返回响应
        ctx.respond = false
      })
    
      server.listen(port,() => {
        console.log(`server is running on ${port}`)
      })
    })
    
    • 启动服务
    "scripts": {
      // 执行这个就会自动打包出.next文件夹
      "dev": "node ./server/index.js",
      "build": "next build",
      "start": "next start"
    },
    

    我还是不会用怎么办
    把上面的github下载下来,没用的代码删了,改成自己的就行

  • 相关阅读:
    【计蒜客习题】取石子游戏
    【SCOI2005】骑士精神
    依赖背包
    强连通分量
    2017 Multi-University Training Contest
    2017 Multi-University Training Contest
    3月每日。
    2月每日DONE。
    寒假划水。
    基础实验2-2.5 整数分解为若干项之和 (20分)--dfs
  • 原文地址:https://www.cnblogs.com/pengdt/p/13092147.html
Copyright © 2011-2022 走看看