Mui-Vue-Pug-Sass-Starter

本文做为个人近几个月接触 Mui 的总结,主要通过 Vue 来模块化开发

NodeJs & cnpm

此部分跳过,请自行脑补

Vue-Cli

全局安装

cnpm install --global vue-cli

初始化Vue

vue init webpack mui-vue-pug-sass-starter

PS: vue-router 这一步,输入 n,其余全部默认

? Project name mui-vue-pug-sass-starter
? Project description A Vue.js project
? Author jun
? Vue build standalone
? Install vue-router? No
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Standard
? Set up unit tests Yes
? Pick a test runner jest
? Setup e2e tests with Nightwatch? Yes
? Should we run npm install for you after the project has been created? (recommended) npm

要最大化利用 Webview 运行效率,采用 Mpa 方案来进行 Vue 的开发,所以关闭 vue-router


漫长的等待后...


配置篇

安装所需依赖

cnpm install --save-dev glob node-sass sass-loader pug pug-loader pug-filters clean-webpack-plugin
cnpm install --save axios
cnpm install

目录结构

+-- builder
+-- config
+-- src
|   +-- app // 多页面入口,每个目录为一个页面,build 输出以目录为名的 html
|   |   +-- page1
|   |   |   --- App.vue  // 主模块
|   |   |   --- page1.js  // 入口,文件名同目录名
|   |   |   --- page1.pug  // html 模板,文件名同目录名
|   |   +-- page2
|   |   +-- ...
|   +-- assets  // 存放一些公共静态文件及 js 库
|   |   +-- img
|   |   +-- js
|   |   +-- sass
|   +-- components  // 公共 vue 组件目录
+-- static
|   --- mui.min.css  // 需修改 mui.ttf 路径为 ./
|   --- mui.min.js
|   --- mui.ttf 

修改 Vue 为 Mpa 多页面入口模式

为最大化利用 Webview,需修改 Vue 为多页面入口模式

build/utils.js

添加输出遍历多页面入口的函数

// 使用glob模块遍历导入多页面入口
const glob = require('glob')

exports.entries = (globPath) => {
  let entries = {}, baseName, tmp, pathName
  glob.sync(globPath)
    .forEach(entry => {
      baseName = path.basename(entry, path.extname(entry))
      tmp = entry.split('/').splice(-3)
      pathName = tmp.splice(0, 1) + '/' + baseName
      entries[pathName] = entry
    })
  return entries
}
build/webpack.base.conf.js

修改 module.exports.entry

  /**
   * 遍历 app 目录中所有子目录,生成多页面入口
   */
  entry: utils.entries('./src/app/**/*.js'),
build/webpack.dev.conf.js

注释掉单页面入口

    /* 关闭单页面入口
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'index.html',
      inject: true
    }),
    */

在最后添加多页面入口代码段

// 多页面入口配置
let templates = utils.entries('./src/app/**/*.pug')
for (let pathName in templates) {
  let conf = {
    filename: pathName + '.html',
    template: templates[pathName],
    inject: true,
    chunksSortMode: 'dependency'
  }
  if (pathName in devWebpackConfig.entry) {
    conf.chunks = ['manifest', 'vendor', pathName]
    conf.hash = true
  }
  devWebpackConfig.plugins.push(new HtmlWebpackPlugin(conf))
}
build/webpack.prod.conf.js

注释掉单页面入口代码段

    /* 关闭单面页入口
    new HtmlWebpackPlugin({
      filename: process.env.NODE_ENV === 'testing'
        ? 'index.html'
        : config.build.index,
      template: 'index.html',
      inject: true,
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
        // more options:
        // https://github.com/kangax/html-minifier#options-quick-reference
      },
      // necessary to consistently work with multiple chunks via CommonsChunkPlugin
      chunksSortMode: 'dependency'
    }),
    */

在最后添加多页面入口代码段

// 多页面入口配置
let templates = utils.entries('./src/app/**/*.pug')
for (let pathName in templates) {
  let conf = {
    filename: pathName + '.html',
    template: templates[pathName],
    inject: true,
    chunksSortMode: 'dependency'
  }
  if (pathName in module.exports.entry) {
    conf.chunks = ['manifest', 'vendor', pathName]
    conf.hash = true
  }
  module.exports.plugins.push(new HtmlWebpackPlugin(conf))
}

配置 pug

build/webpack.base.conf.js

在 module.exports.module.rules 中添加 pug 定义

      {
        test: /\.pug$/,
        loader: 'pug-loader'
      },

其它配置

build/utils.js

修正 css 中引入外部文件(如字体、图片等)路径问题

    // Extract CSS when that option is specified
    // (which is the case during production build)
    if (options.extract) {
      return ExtractTextPlugin.extract({
        use: loaders,
        fallback: 'vue-style-loader',
        /**
         * 修正css 引入外部字体、图片等路径
         */
        publicPath: '../../../'
      })
    } else {
      return ['vue-style-loader'].concat(loaders)
    }
build/webpack.base.conf.js

定义路径别名 module.exports.resolve

  resolve: {
    extensions: ['.js', '.vue', '.json', 'scss', 'css'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
      'assets': resolve('src/assets'),
      'components': resolve('src/components'),
      'js': resolve('src/assets/js'),
      'img': resolve('src/assets/img'),
      '@img': resolve('src/assets/img'),
      '@fonts': resolve('src/assets/fonts'),
      '@sass': resolve('src/assets/sass')
    }
  },
build/webpack.prod.conf.js

run build 时自动清空 dist 目录

// 在头部 require
const CleanPlugin = require('clean-webpack-plugin')
// 在 const webpackConfig 代码段中的 plugins 数组内添加如下代码
    // build时清空dist目录
    new CleanPlugin(['../dist']),
config/index.js

修正 run build 后的 html 页面内的 路径问题

// module.exports.build.assertsPublicPath
    assetsPublicPath: '../',
package.json

修改 browserslist 项,自动适配浏览器

  "browserslist": [
    "> 1%",
    "not ie <= 8",
    "iOS >= 7",
    "Android > 4",
    "Firefox > 20",
    "last 5 versions"
  ]

应用篇

关于 ESLint

本文配置项中已开启 ESLint Standard 的支持,目的为规范代码的编写,具体 ESLint 的作用和用法,请自行脑补

vue 如何整合 mui ?

经过多次试验,最终还是在主html模板中引入mui这种方式最为合适

复制 mui.min.js、mui.min.css、mui.ttf 到 static 目录
需要修改 mui.min.css 中 mui.ttf 的路径为 ./mui.ttf

创建页面入口

src/app 目录为所有页面入口,每一个子目录代表一个页面,包含一个主模板、一个入口JS、一个主VUE模块

范例(基于 Webview 的 tab bar)

在 src/app 目录下新建 index 目录和 nav 目录

+-- src
|   +-- app
|   |   +-- index
|   |   +-- nav

新建 index 模块

// src/app/index/index.pug
// 主模板,文件名称需和目录名一致

doctype html
html
  head
    meta(charset='UTF-8')
    title index
    meta(name='viewport' content='width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no')
    link(rel="stylesheet", href="../static/mui.min.css")
  body
    script(src='../static/mui.min.js')
    #app

// src/app/index/index.js
// 入口文件,需和目录名一致
// 基本所有入口文件都可如下一致

import Vue from 'vue'
import App from './App'

// eslint-disable-next-line
new Vue({
  el: '#app',
  components: { App },
  template: ''
})

// src/app/index/App.vue
// 主模块文件






因 mui 是在主模板中 script src 引入,在 模块和入口里没有定义,需在 script 段第一行加入 /* global mui / 将mui全局化,如不加这一行,编译时会报错,如果用到了 plus ,则为 / global mui plus */

mui.init 或 mui.plusReady 等初始化函数,需写入 vue 生命周期 mounted 内

新建 nav 模块

可以直接将 src/app/index/index.js 和 src/app/index/index.pug 复制到 src/app/nav 目录下,并分别改名为 nav.js 和 nav.pug,这两个文件的内容可以不改动

// src/app/nav/App.vue





本示例中应用到了 vue 的特性,v-on:tap, v-bind:class, v-for

新建 home 模块

同 nav 模块,可直接复制 pug 与 js 文件到 src/app/home

// src/app/home/App.vue





新建 axios 模块

同上操作复制 pug 与 js 到 src/app/axios 目录
本示例示范 vue 官方推荐的 ajax 库 axios 的简单操作
点击查看 axios 中文文档

// src/app/axios/App.vue





至此,一个简单的,基于 Vue 的 mui 模块化开发示范大体结束


调试篇

npm run build
输入上面一行命令,将我们的开发成果 build 出成品

HBuilder 入场

请出我们久违了的 HBuilder,开始调试我们的成果

  1. HBuilder >> 文件菜单 >> 选择目录
  2. 选择 build 后生成的 dist 目录,并起个项目名称,然后完成
  3. 左侧项目管理器中,鼠标右键点击上一步完成后出现的项目,选择右键菜单中 “转换成移动App”,此时,HBuilder 将会在 dist 目录下添加 manifest.json 文件
  4. HBuilder 中打开 manifest.json 开始配置我们的 App,请注意要选择一下 页面入口这一项,这里我们设置成 app/index.html
  5. 其他相关 manifest.json 的设置请参照 dcloud 官方文档

至此,本文档大体结束,可以按照我们之前的操作习惯在 HBuilder 中进行真机测试了。


后续,计划在本文档的基础上,再次整理一个新的文档出来
名称拟定为 Mui-Vue-TypeScript-Starter

本文档推荐IDE:VS Code

Github: Mui-Vue-Pug-Sass-Starter

你可能感兴趣的:(Mui-Vue-Pug-Sass-Starter)