目前对于Javascript的模块化编程主要就是通过以下几种方法,一种就是AMD(Asynchronous Module Definition),它的具体实现是RequireJS;一种是CMD(Common Module Definition),它的具体实现是SeaJS;一种是CommonJs;还有就是es6新出的import/export,而熟悉其中一个模块化编程实现,就比较好理解其他模块化编程的思想,所以我们就从一个简单的RequireJS和Vue结合的模块编程项目开始了解RequireJS中的模块化编程思想,当然,这种组合也方便学习搞懂RequireJS和Vue。
一、AMD的一些基本规范
require.js加载的模块,是采用AMD规范。也就是说,模块必须按照AMD的规定来写。更多RequireJS用法和AMD规范请查看RequireJS官网。
- 定义一个模块:
//math.js
define(function (){
var add = function(x,y){
return x+y;
}
return {
add : add
}
});
- 引入一个模块:
// math.js
require(['math'], function(math){
alert(math.add(1,1));
})
二、项目文件结构:
|--assets:存放公共的静态资源文件比如图片,公共的css,js等。
|--components:公共的vue组件。
|--lib:公共的依赖文件,比如vue,requireJS,vue router等。
|--modules:各个模块独立的相关文件。
|--index.html:主入口的html文件。
|--main.js:主入口的js文件
|--require.config.js:require的配置文件
|--router.js:总的vue router路由文件
三、创建require.config.js配置环境依赖
在这个项目里我引入了vue,vue-router,element。其中需要注意的是requireJS中的test.js插件的使用,text.js是为了模块化的加载html文件,但是许多浏览器不允许file://访问任何文件,所以最好从本地Web服务器提供应用程序,而不是使用本地file:// URL,否则会遇到跨域的问题。
var require = {
// 基于调用这个js的html的路径是基础路径
paths: {
// 第三方库
"vue": "lib/vue/vue",
"vueRouter":"lib/vue/vue-router",
"ELEMENT":"lib/elementUI/index"
},
// 设置js依赖特性
shim:{
// 公共模块
'baseModule': {
deps: [
'css!assets/css/common.css',
],
},
'ELEMENT': {
deps: ["css!lib/elementUI/index.css","css!lib/elementUI/reset.css","vue"],
exports: "ELEMENT"
},
},
// 包设置
packages: [
{ // 组件包路径
name: 'components',
location: 'components', //相对这个文件的路径
main: 'component'
},
{
name: 'lib',
location: 'lib',
main: 'lib'
},
{ // 模块包路径
name: 'modules',
location: 'modules',
main: 'modules'
},
],
map: {
'*' : {
"css": "lib/require/css.min", // require用于引入css的插件
"text": 'lib/require/text/' // require用于引入文本的插件
}
},
timeout : "20000"
}
四、创建index.html。
创建主入口的index.html文件之后,引入require.config.js,require.js和一些公共的css文件,特别要注意引入主要的main.js。main.js里是vue实例的开始和路由的引入等,后续的其他模块或者其他页面都是使用vue的extend去扩展当前的这个vue实例的。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>首页</title>
<link rel="stylesheet" href="assets/css/common.css">
</head>
<body>
<div id="app">
<router-view></router-view>
</div>
<script type="text/javascript" src="require.config.js"></script>
<script type="text/javascript" data-main="main.js" src="lib/require/require.js"></script>
</body>
</html>
五、创建main.js,引入路由。
require{[
"vue",
"ELEMENT",
"router"
], function(Vue,ELEMENT,router){
Vuew.use(ELEMENT);
var app = new Vue({
el: "#app",
components:{
},
data: function(){
return {
}
},
created(){
},
mounted: function(){
},
methods:{
},
router: router,
});
}};
六、定义模块中的某个页面。
在该项目中要定义一个页面的话,主要有这几部分:1.该页面的js入口,也就该页面的入口,它会加载该页面所需要的html模板,css文件,相关的一些组件;2.模板html文件;3.该页面的样式文件。需要注意的是,我们的模板html文件是基于vue的,在这里一个页面就相当于一个组件,因此它的html模板文件就只能有一个父元素,多个父元素的话vue会报错的。
比如我定义的一个首页的页面:
-
主入口的js:
其中js里就是跟平常我们使用.vue文件中的js的写法都差不多的。define([ "vue", "text!modules/home/views/home/index.html", "css!modules/home/views/home/index.css", ],function(Vue,template,css){ return Vue.extend({ template: template, data() { return { msg: 'aaa' } }, components: {
}, })
})
-
模板html文件
<div class="index"> 首页{{msg}} </div>
-
模板样式文件
.index{ background-color: #0d78bc; .index-body{ background-color: #00b38a; } }
总结:
虽然现在requirejs不是那么热门,可是去了解它,这样能帮助我们更好的理解一些模块化的底层实现方法,可以让我们对目前一些主流的构建工具中的分模块功能的实现原理有一定的帮助,当然本实例只是为大家提供一种require+vue和vue的一些插件实现一个SPA项目的方法,要是有其中有不正确的地方,欢迎指出。