art-template渲染分页模板

//环境:简单webpack环境

webpack.config.js

const path = require('path')

const HtmlWebpackPlugin = require('html-webpack-plugin')

 

const VueLoaderPlugin = require('vue-loader/lib/plugin') // 引入这行

 

const webpack = require('webpack')

const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin')

 

//将css样式单独抽离成一个文件

let MiniCssExtractPlugin = require('mini-css-extract-plugin');


 

//添加optimize-css-assets-webpack-plugin插件,与uglifyjs-webpack-plugin插件

let OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');

let UglifyJsPlugin = require('uglifyjs-webpack-plugin')

 

const isDev = process.env.NODE_ENV === 'development'

 

const config = {

  mode: 'development',

  entry: path.join(__dirname, './src/index.js'),

  output: {

    filename: 'bundle.js',

    //路径必须是一个绝对路径

    path: path.resolve(__dirname, 'dist')

  },

 

  optimization: { //优化项

    minimizer: [

      new UglifyJsPlugin({

        cache: true,

        parallel: true,

        sourceMap: true

      }),

      new OptimizeCSSAssetsPlugin()

    ],

  },

 

  plugins: [

    //process.env.NODE_ENV = development 为一个变量报错

    new webpack.DefinePlugin({

      'process.env': {

        NODE_ENV: isDev ? '"development"' : '"production"' //Or JSON.stringify('development')

      }

    }),

    //js打包后自动插入模板

    new HtmlWebpackPlugin({

      filename: 'index.html',

      template: path.resolve(__dirname, './src/index.html'),

      minify: {

        removeAttributeQuotes: true,

        collapseWhitespace: true

      },

      hash: true

 

    }),

    new VueLoaderPlugin(),

 

    new MiniCssExtractPlugin({

      filename: '[name].css',

      chunkFilename: '[id].css',

    })

  ],

 

  module: {

    //规则 css-loader 解析类似import这种语法的语句

    //style-loader 把css插入到head标签中

    //loader的用法:字符串只用一个loader

    //loader的特点:单一

    //多个loader,需要[]

    //loader顺序,从右向左,从下到上执行

    //loader还可以写出对象方式

    rules: [{

        test: /\.vue$/,

        loader: 'eslint-loader',

        exclude: /node_modules/,

        enforce: 'pre'

      },

      {

        test: /\.vue$/i,

        use: ['vue-loader']

      },

      {

        test: /\.jsx$/,

        loader: 'babel-loader'

      },

 

      {

        test: /\.js$/,

        loader: 'eslint-loader',

        enforce: "pre",

        include: [path.resolve(__dirname, 'src')], // 指定检查的目录

        options: { // 这里的配置项参数将会被传递到 eslint 的 CLIEngine

          formatter: require('eslint-friendly-formatter') // 指定错误报告的格式规范

        }

      },

      {

        test: /\.js$/i,

        use: {

          loader: 'babel-loader',

          options: {

            presets: [

              '@babel/preset-env'

            ],

            plugins: [

              //注意插件顺序

              ["@babel/plugin-proposal-decorators", {

                "legacy": true

              }],

              //https://www.npmjs.com/package/@babel/plugin-proposal-class-properties

              ["@babel/plugin-proposal-class-properties", {

                "loose": true

              }],

              //https://babeljs.io/docs/en/babel-plugin-transform-runtime#docsNav

              "@babel/plugin-transform-runtime",


 

            ],

            include: path.resolve(__dirname, 'src'),

            exclude: /node_modules/

          }

        }

      },

      {

        test: /\.css$/,

        use: [

          // 'style-loader',

          MiniCssExtractPlugin.loader,

          'css-loader',

          'postcss-loader', //给css样式添加浏览器前缀 -moz- ...

        ]

      },

 

      {

        test: /\.(jpg|jpeg|png|svg|gif)$/i,

        use: {

          loader: 'url-loader',

          options: {

            name: '[name].[ext]',

            limit: 10 * 1024

          }

        }

 

      },

 

      {

        test: /\.scss$/i,

        use: [

          // 'style-loader',

           MiniCssExtractPlugin.loader,

           {

            loader:'css-loader',

              options:{

                importLoaders:1

              }

          },

          // {

          //   loader: 'postcss-loader',

          //   options: {

          //     // nables source map support, postcss-loader will use the previous source map given by other loaders and update it accordingly,

          //     // if no previous loader is applied before postcss-loader, the loader will generate a source map for you.

          //     sourceMap: true

          //   }

          // },

 

          {

            loader: "postcss-loader",

            options: {

              ident: 'postcss',

              plugins: [

                require('autoprefixer')({

                  'browsers': ['> 1%', 'last 2 versions']

                }),

              ]

            }

          },


 

          'sass-loader'

        ]

 

      },



 

        {

 

          test: /\.art$/,

 

          loader: 'art-template-loader'

 

      }


 

    ]

  }

}

 

if (isDev) {

  config.module.rules.push({

    test: /\.styl(us)?$/, //rules里面修改下匹配styl的正则表达式,文件内写的lang是等于"stylus"的

    use: [

      'style-loader',

      'css-loader',

      {

        loader: 'postcss-loader',

        options: {

          //nables source map support, postcss-loader will use the previous source map given by other loaders and update it accordingly,

          //if no previous loader is applied before postcss-loader, the loader will generate a source map for you.

          sourceMap: true

        }

      },

      'stylus-loader'

    ]

  })

  config.devtool = '#cheap-nodule-eval-source-map' //webpack官方推荐

  config.devServer = {

    port: 8888,

    contentBase: './build', //指定目录

    progress: true, //打包时显示进度条

    // open:true, //打包后自动打开浏览器

    host: '0.0.0.0', //可localhost、可IP及手机连接wifi访问等等

    compress: true,

    overlay: {

      warnings: true,

      errors: true

    },

    hot: true //热替换

  }

 

  config.plugins.push(

    new webpack.HotModuleReplacementPlugin(),

    new webpack.NoEmitOnErrorsPlugin()

  )

} else {

  config.output.filename = '[name].[chunkhash:8].js' //开发环境会报错

  config.module.rules.push({

    test: /\.styl(us)?$/,

    use: ExtractTextWebpackPlugin.extract({

      fallback: 'style-loader',

      use: [

        'css-loader',

        {

          loader: 'postcss-loader',

          options: {

            //nables source map support, postcss-loader will use the previous source map given by other loaders and update it accordingly,

            //if no previous loader is applied before postcss-loader, the loader will generate a source map for you.

            sourceMap: true

          }

        },

        'stylus-loader'

      ]

    })

  })

 

  config.plugins.push(

    new ExtractTextWebpackPlugin({

      //因为webpack4包含了contenthash这个关键字段,所以extarct-text-webpack-plugin中不能使用contenthash

      //解决:使用md5:contenthash:hex:8替代

      // filename:'styles.[contentHash:8].css'

      filename: 'styles.[md5:contenthash:hex:8].css'

    })

  )

}


 

module.exports = config

 

// 构建分页逻辑所需要的数据(代码来自慕课网某课程)

// art-template的使用原则:不要在里面拼接大段的HTML代码。

// 类似本利中的分页组件,最好是构造一份适合Handlebars的数据,然后传给它,来生成html。

formatPag.js

const formatPag = function (pagData) {

  var arr = []

  var total = parseInt(pagData.totalCount)

  var cur = parseInt(pagData.curPage)

  // 处理首页的逻辑:<<

  var toLeft = {}

  toLeft.index = 1 // index代表点击按钮的时候可以跳转到的页面

  toLeft.text = '&laquo;' // text代表button的文本

  if (cur !== 1) {

    toLeft.clickable = true

  }

  arr.push(toLeft)

  // 处理到上一页的逻辑

  var pre = {}

  pre.index = cur - 1

  pre.text = '&lsaquo;'

  if (cur !== 1) {

    pre.clickable = true

  }

  arr.push(pre)

 

  var pag

 

  // 处理到cur页前的逻辑

  if (cur <= 5) {

    for (var i = 1; i < cur; i++) {

      pag = {}

 

      pag.text = i

 

      pag.index = i

 

      pag.clickable = true

 

      arr.push(pag)

    }

  } else {

    // 如果cur>5,那么cur前的页要显示为...

    pag = {}

 

    pag.text = 1

 

    pag.index = 1

 

    pag.clickable = true

 

    arr.push(pag)

 

    pag.text = '...'

 

    arr.push(pag)

 

    // 当前页前面2个页数显示出来

 

    for (var j = cur - 2; j < cur; j++) {

      pag = {}

 

      pag.text = j

 

      pag.index = j

 

      pag.clickable = true

 

      arr.push(pag)

    }

  }

 

  // 处理当前页

  pag = {}

 

  pag.text = cur

 

  pag.index = cur

 

  pag.cur = true

 

  arr.push(pag)

 

  // 处理cur页后的逻辑

 

  if (cur >= total - 4) {

    for (var k = cur + 1; k <= total; k++) {

      pag = {}

 

      pag.text = k

 

      pag.index = k

 

      pag.clickable = true

 

      arr.push(pag)

    }

  } else {

    // 如果cur < total - 4, 那么cur后的页面显示为...

 

    // 显示以当前页后面的2个页数

 

    for (var m = cur + 1; m <= cur + 2; m++) {

      pag = {}

 

      pag.text = m

 

      pag.index = m

 

      pag.clickable = true

 

      arr.push(pag)

    }

 

    pag = {}

 

    pag.text = '...'

 

    arr.push(pag)

 

    pag = {}

 

    pag.text = total

 

    pag.index = total

 

    pag.clickable = true

 

    arr.push(pag)

  }

 

  // 处理到下一页的逻辑

 

  var next = {}

 

  next.index = cur + 1

 

  next.text = '&rsaquo;'

 

  if (cur !== total) {

    next.clickable = true

  }

 

  arr.push(next)

 

  // 处理到尾页的逻辑

 

  var toRight = {}

 

  toRight.index = total // index代表点击按钮的时候可以跳转到的页面

 

  toRight.text = '&raquo;' // text代表button的文本

 

  if (cur !== total) {

    toRight.clickable = true

  }

 

  arr.push(toRight)

 

  return arr

}

 

export default formatPag

 

//page.art

<ul>
    {{if data && data.length>0}}
    {{each data}}
    <li data-id={{$value.index}} {{if $value.cur}} class="cur" {{/if}} {{if $value.clickable}} class="clickable" {{/if}}>{{# $value.text}}</li>
    {{/each}}
     {{else }}
        {{/if}}
</ul>

 

//page.js

const $ = require('jquery');

const page = require('./page.art');

$.getJSON('http://imoocnote.calfnote.com/inter/getClasses.php', {

    curPage: 1

}, function (data) {

 

    console.log(JSON.stringify(formatPag(data)));

    var html = page({"data":formatPag(data)});

    $("#page").html(html);

    

});

 

index.js

 

import Vue from 'vue'

import App from './app.vue'

// img.src = './meinv.png';就是一个普通字符串

import beauty from './images/profile.jpg'

// import axios from 'axios'

 

import formatPag from './formatPag.js'

 

require('@primer/css/buttons/index.scss')

require('@primer/css/utilities/index.scss')

require('./style/page.css')

 

const img = new Image()// 把图片引入,返回一个新的图片地址

img.src = beauty

 

const root = document.createElement('div')

document.body.appendChild(root)

 

document.body.appendChild(img)

 

const $ = require('jquery')

 

const page = require('./tpl/page.art')

 

console.log(formatPag)

 

$.getJSON('http://imoocnote.calfnote.com/inter/getClasses.php', {

  curPage: 1

}, function (data) {

  console.log(JSON.stringify(formatPag(data)))

  var html = page({ data: formatPag(data) })

  $('#pag').html(html)

})

 

new Vue({

  // 通过h把App组件挂载到html里面,这里只是声明了渲染的是组件App的内容,还需通过$mount挂载到html的一个节点上面

  render: (h) => h(App)

}).$mount(root)

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值