多页网站的Vue.js 2项目结构

时间:2017-05-30 20:42:45

标签: webpack vue.js vuejs2

我正在使用Vue 2构建一个多页面应用程序,使用Webpack和CommonsChunkPlugin来分离共享功能。在common.js包中我有Vue,一些Vue组件,一个字体加载器和一个对象,它具有初始化我导出的Vue实例的功能,以防特定页面需要扩展该实例。具有额外交互性的页面使用导入的函数来初始化Vue并将mixin作为参数传递。

为了防止new Vue和另一个入口点同时调用common.js,我在window.m中将全局变量0设置为global.js,在其他入口点增加它,global.js只有new Vue才会运行0

这感觉非常糟糕,我想知道如何更好地设置我的项目结构。

webpack.babel.js



const webpack = require('webpack')
const path = require('path')
const UglifyJSPlugin = require('uglifyjs-webpack-plugin')

module.exports = {
	entry: {
		common: './src/js/global.js',
		home: './src/js/home.js',
		imp_single: './src/js/imp_single.js',
		parent_single: './src/js/parent_single.js',
		faq: './src/js/faq.js'
	},
	output: {
		path: __dirname + '/dist/js',
		filename: '[name].bundle.js'
	},
	devtool: 'sourcemap',
	module: {
		rules: [
			{ // eslint
				enforce: 'pre',
				test: /\.(vue|js)$/,
				loader: 'eslint-loader',
				exclude: /node_modules/,
				options: {
					formatter: require('eslint-friendly-formatter')
				}
			},
			{
				loader: 'babel-loader',
				include: path.resolve(__dirname, 'src'),
				exclude: /node_modules/,
				test: /\.(vue|js)$/,
				query: {
					presets: ['es2015', 'stage-2']
				}
			},
			{
				test: /\.vue$/,
				loader: 'vue-loader',
				options: {
					loaders: {
						js: 'babel-loader'
					}
				}
			}
		]
	},
	plugins: [
		new webpack.optimize.CommonsChunkPlugin({
			name: 'common',
			filename: 'common.js',
			minChunks: 0
		}),
		new webpack.optimize.UglifyJsPlugin({
			compress: {
				warnings: false
			},
			sourceMap: true
		})
	],
	resolve: {
		extensions: ['.js', '.vue', '.json'],
		modules: [
			path.resolve(__dirname, 'src'),
			path.resolve(__dirname, 'node_modules')
		],
		alias: {
			vue: 'vue/dist/vue.common.js',
			src: path.resolve(__dirname, '/src'),
			components: path.resolve(__dirname, '/src/components')
		}
	}
}




global.js



import WebFont from 'webfontloader'
import Vue from 'vue'

// Vue Components
import accordion from './components/accordion'
import dropdown from './components/dropdown'
import progressbar from './components/progressbar'
import quiz from './components/quiz'
import timeline from './components/timeline'

// Setting a global variable to check for other mixins. If there's additional functionality, let the other bundle initialize Vue
window.m = 0

// Disable typography immediately to avoid FOUT
document.getElementsByTagName('html')[0].classList.value = 'wf-loading'
// Load our fonts
WebFont.load({
  typekit: {
    id: 'xxxxxxx',
    families: ['Calluna', 'Open Sans', 'Bookmania', 'Freight Text Pro']
  },
  classes: false,
  active () {
    document.getElementsByTagName('html')[0].classList.value = 'wf-active'
    setTimeout(function () {
      document.getElementsByTagName('html')[0].classList.value = ''
    }, 500)
  }
})

const global = {
  init (mixin = []) {
    new Vue({ // eslint-disable-line no-new
      el: '#sos',
      components: {
        accordion: accordion,
        dropdown: dropdown,
        progressbar: progressbar,
        quiz: quiz,
        timeline: timeline
      },
      data () {
        return {
          hrStatus: false
        }
      },
      methods: {
        helplines () {
          this.hrStatus = !this.hrStatus
        }
      },
      mixins: [mixin]
    })
  }
}

document.addEventListener('DOMContentLoaded', () => {
  // Global Vue, extended by other pages
  if (window.m === 0) {
    global.init()
  }
})

export default global




home.js:



import sos from './global'

// TODO Find a better way to do this
window.m++

document.addEventListener('DOMContentLoaded', () => {
  sos.init({
    data: {
      forgotText: 'Forgot Password?',
      forgot: false
    },
    methods: {
      who () {
        // Shows the parent/implementer buttons
        this.forgot = !this.forgot
        // Update text
        if (this.forgotText === 'Forgot Password?') {
          this.forgotText = 'Who are you?'
        }
        else {
          this.forgotText = 'Forgot Password?'
        }
      },
      parentFAQ () {
        // Toggle the 'who are you' buttons
        this.who()
        // This relies on the forgot password FAQ being at the top. Might have to find a better way
        if (this.$children[0].open === false) {
          this.$children[0].toggle()
        }
        // Distance from top, then scroll to it
        let top = this.$children[0].$el.offsetTop
        window.scrollBy(0, top)
      }
    }
  })
})




0 个答案:

没有答案