關於require.js的基本使用和其插件使用,可以參考阮一峰的教程,寫的很詳細 http://www.ruanyifeng.com/blog/2012/11/require_js.html 。
本實例是測試關於require.js與 vue.js之間的使用,不涉及任何的設計,記在這里方便以后自己查詢,寫的不對,請批評指正。如果不會vue,這並不適合你看。
首先明確幾點:
第一:模塊發開發的思想,將每一部分的功能中js的文件和css文件和html結構放在一起,形成一個模塊,方便復用、維護和修改,各個模塊之間形成聯系,構成spa的單頁應用。
第二:require.js 可以實現按需加載模塊,這里測試能否與vue.js結合使用,若用vue構建,建議使用vue-cli 安裝。
第三:關於各個文件,有可能沒使用到,使用到了會說明,這里是構建搭建一個前端應用的模塊開發框架,不涉及做具體的內容。
第四:關於有些內容是放在data.js文件中,測試vue-resourse能否使用,若是用webstrom 編寫,項目不用放在服務器下,它本身自己會有一個端口可以使用,若是用sublime,需要放到服務器環境下測試數據,這里用的是Xampp,將項目放到 Xampp 安裝目錄下的htdoces即可。打開index.html方式
前面的是自己電腦的ip的地址,自己ipconfig查看。
第一步:各個文件夾的目錄如下,說到的是必須有的,沒有說到的,基本沒用到,可以不管:

epproject 項目名
libs 下面是依賴的文件
data.json 是模擬數據
index.html是頁面
第二步: 新建index.html ,代碼如下:
<!DOCTYPE html> <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="css/reset.css"/> <link rel="stylesheet" href="libs/bootstrap/dist/css/bootstrap.min.css"/> <!-- 主入口js文件app.js --> <script src="libs/requirejs/require.js" data-main="js/app"></script> </head> <body > <!-- v-cloak vue中,防止文件加載時,出現{{djjjj}}字符串 --> <div v-cloak id="app"> <!-- 路由的顯示區域 --> <router-view></router-view> </div> </body> </html>
data.json文件為:
{ "pixel":{ "toolArr":[ {"img":"img/u256.png","toolName":"影像校正","author":"z1","time":"2017-04-06","type":"基礎服務","method":"全自動","desc":"對1A級影像進行校正,要求輸入RPB參數和校正影像。"}, {"img":"img/u256.png","toolName":"勻光勻色","author":"z2","time":"2017-05-06","type":"高級服務","method":"半自動","desc":"對3A級影像進行均勻處理。"}, {"img":"img/u256.png","toolName":"影像融合"},{"toolName":"工具名稱"},{"toolName":"工具名稱"} ], "processDesc":[{"processName":"無控定位","img":"img/u256.png"},{"processName":"影像融合","img":"img/u256.png"}], "sidebar":[ { "testName":"局部影像", "allTool":[ {"name":"局部輸入","inputFile":{"singleOne":["fad流","sdf結","dfd開","df文","ff關"],"singleTwo":["1sdaf","fds結束","fdf開始","文本","關聯"]}}, {"name":"局部輸出","inputFile":{"singleOne":["aae流s","adf結","dfad開","fffff文","sf關"],"singleTwo":["sfad2","fasfd結束","開始","文本","關聯"]}} ] }, { "testName":"柵格地圖", "allTool":[ {"name":"柵格地圖輸入文件夾","inputFile":{"singleOne":["dd公司流","分管結","東方紅開","施工隊文","關"],"singleTwo":["1","結束","開始","文本","關聯"]}}, {"name":"柵格地圖輸出文件夾","inputFile":{"singleOne":["是大法官流s","剛剛結","發的廣泛地開","不規范的文","收到關"],"singleTwo":["2","結束","開始","文本","關聯"]}} ] }, { "testName":"無控定位", "allTool":[ {"name":"輸入文件夾","inputFile":{"singleOne":["流","結","開","文","關"],"singleTwo":["1","結束","開始","文本","關聯"]}}, {"name":"輸出文件夾","inputFile":{"singleOne":["流s","結","開","文","關"],"singleTwo":["2","結束","開始","文本","關聯"]}} ] } ] } }
第三步:首先第二步構建好,主題頁面就是這樣,現在開始寫app.js,寫app.js入口前,要配置依賴的關系confige.js ,在js文件下,建立如下:

confige.js 中配置依賴文件為:
/** * Created by domea on 17-6-2. */ 'use strict'; define({ packages: [], // urlArgs: "bust=" + (new Date()).getTime(), baseUrl:'js/', paths: { "jquery": '../libs/jquery/dist/jquery', "bootstrap":'../libs/bootstrap/dist/js/bootstrap', 'validate':'../libs/bootstrapValidator/dist/js/bootstrapValidator', //表單驗證插件 'domReady':'../libs/domReady/domReady', 'text':'../libs/text/text', //require.js的插件text.js用於加載.html的文件 'css':'../libs/text/css', //require.js的插件css.js用於加載.css的文件 'vue':'../libs/vue/dist/vue', //vue.js 'vueRouter':'../libs/vue/dist/vue-router', //vue的路由 'vueResource':"../libs/vue/dist/vue-resource", //ajax插件 'vueX':'../libs/vue/dist/vuex' //全局狀態管理,可以用於不同的組件通信 }, shim: { 'bootstrap':{ deps:[ 'jquery', 'text!../libs/bootstrap/dist/css/bootstrap.css', 'text!../libs/bootstrap/dist/css/bootstrap-theme.css' ] }, 'validate':{ deps:[ 'jquery' ], exports:'validate' } } });
app.js為:
'use strict'; (function(root){ require(["config"], function(config){ requirejs.config(config); require(['app/ui/main','domReady!'], function(ui){ //調用ui文件下的main.js的routerDemo的函數,routerDemo加載頁面全局使用的路由、ajax、組件全局狀態管理 ui.routerDemo(); }); }); })(this);
第四步:js文件下目錄為,加載main.js

components 是組件文件夾 router 是配置路由 views是單頁應用的不同的頁面 vuex狀態管理,下面用到再具體說。
main.js代碼:
//UI主入口,加載各種依賴 define(['vue','vueResource','./vuex/store', './router/router'],function (Vue,VueResource,Store,Router) { var _app = function() { Vue.use(VueResource); //全局使用vueVueResource new Vue({ router:Router, //路由掛載 store:Store, //狀態掛載 el: "#app" //掛載點是index.html 中的 id="#app"的元素 }); }; return { routerDemo:_app } });
第五步: 配置路由和 vuex全局
在router文件下新建 router.js ,其內代碼如下:
define(['vue','vueRouter','.././views/mainPage/mainPage','.././views/edit/edit','.././views/run/run'],function(Vue,VueRouter,MainPage,Edit,Run){ Vue.use(VueRouter); //使用 路由 return new VueRouter({ //返回路由實例 //路由表 routes:[ {path:'/',component:MainPage.app}, //默認的進入頁面(隨便取的) {path:'/edit',component:Edit.edit}, //編輯頁面 {path:'/run',component:Run.run} //運行頁面 ] }); });
在vuex文件下新建 store.js ,其內代碼如下:
/** * 基本只要標紅的部分就能使用,其他部分是后來要用到的,暫時不管。此時就可以新建簡單路由和vuex測試頁面了,可以自己寫個小例子測試 */ define(['vue','vueX'],function(Vue,VueX){ Vue.use(VueX); var state={ fileFlag:false, obj:"", testName:"", allTool:"" }; //相當於計算屬性 var getters = { }; var mutations = { showFileInfo:function(state,n){ state.fileFlag = true; for(var i in state.obj){ if(i == n.a){ state.testName = state.obj[i].testName; state.allTool = state.obj[i].allTool; } } } }; return new VueX.Store({ state:state, mutations:mutations }); });
第六步:
結構為:

默認的頁面為mainPage.html
代碼為:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> </head> <body> <template id="main"> <div id="tool"> <div class="container"> <div class="row"> <div class="tool-list col-md-12"> <button type="button" class="btn btn-default single-tool" v-for="(item,index) in toolArr" @click.stop="showCreateInfo(item,index)" >{{item.toolName}}</button> </div> </div> </div> </div> <router-link to="/edit">編輯</router-link> </template> </body> </html>
其相關的js文件為:
define(['vue','jquery','text!./mainPage.html','validate','css!./main.css'],function(Vue,$,Template){ var App ={ //組件 data:function(){ return { toolArr:"", toolDesc:"", processDesc:"" } }, template:Template, mounted:function(){ //ajax獲取數據 this.$http.get('./data.json').then(function(res){ var data = res.body.pixel; this.toolArr = data.toolArr; this.processDesc = data.processDesc; },function(){ window.document.write("Error 404"); }) }, methods:{ showCreateInfo:function(item,index){ //后面刪除了一些內容,這一部分沒咋用,可 以反映可以使用vue for(var i=0;i<this.toolArr.length;i++){ if(index === i){ this.toolDesc = this.toolArr[i]; } } } } }; return { app:App } });
頁面為:

點擊編輯,單頁跳轉,不是用a標簽跳轉的新的一個頁面 ,點擊后 ,可以發現

跳轉的edit.html 為:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> </head> <body> <template> <div id="edit"> <aside class="left-content" style="display:inline-block; vertical-align: top;"> <v-sidebar ></v-sidebar> </aside> <router-link to="/run">添加</router-link> </div> </template> </body> </html>
edit.js 代碼:
/** * Created by Administrator on 2017/6/26. */ define(['vue','text!./edit.html','../.././components/sidebar/sidebar','../.././components/createwizard/createwizard'],function(Vue,Template,Sidebar,Creat){ var Edit = { data:function(){ return { } }, template:Template, methods:{ }, components:{ "v-sidebar":Sidebar.sidebar, //要使用的組件 ,這部分的代碼不附了,也沒什么用。 "v-pop":Creat.creatWizard } }; return { edit:Edit } });
run.html 代碼:
<div id="test-run"> <div class="test-run-wrapper"> <div class="test-header"> <div class="test-list" style="display: inline-block"> <span class="name">任務列表</span> <button type="button" class="btn btn-default" @click="__fileList()">打開</button> </div> <div class="test-control" style="display: inline-block"> <button type="button" class="btn btn-default" @click="__showTest()">新建</button> <!--寫成路由--> <button type="button" class="btn btn-default">返回</button> </div> </div> <div class="left-box" v-show="$store.state.fileFlag"> <v-leftsidebar ></v-leftsidebar> </div> <div class="right-box"> <div id="preview-log"> <div class="preview-log-wrapper"> <div class="" > <input type="button" class="btn btn-default" @click ="__showPre()" value="預覽" /> <input type="button" class="btn btn-default" @click ="__showLog()" value="日志" /> </div> <div class="preview" v-show="showPre" style="width:300px;height:300px;background:#b2b2b2;" > 預覽區 </div> <div class="log" v-show="showLog" style="width:300px;height:300px;background:#176aa3;"> 日志區 </div> </div> </div> </div> <!--任務彈出框--> <div class="container"id="test-wizard" v-show="showTest"> <div class="row"> <div class="col-md-4 col-md-offset-4"> <div class="panel panel-default"> <div class="panel-heading"> <h3 class="panel-title"><span class="glyphicon glyphicon-user"></span>任務向導</h3> <h3></h3> </div> <div class="panel-body"> <form id="defaultForm" method=""> <div class="form-group"> <input type="text" class="form-control" name="testName" placeholder="任務名稱" /> </div> <div class="form-group"> <input type="text" class="form-control" name="author" placeholder="創建者" /> </div> <div class="form-group"> <textarea name="desc" class="form-control" placeholder="描述信息" style="resize: none;height:100px;"></textarea> </div> <div class="form-group"> <div class="row"> <label class="col-md-4 control-label">數據來源</label> <div class="col-md-8"> <select class="form-control" name="country"> <option value="">未知.</option> <option value="FR">資源一號</option> <option value="DE">資源三號</option> <option value="IT">天繪衛星</option> <option value="JP">高分二號</option> </select> </div> </div> </div> <fieldset> <legend>參考系</legend> <div class="form-group"> <label class="col-md-4 control-label">源參考系:</label> <div class="col-md-8"> <select class="form-control" name="country"> <option value="">f</option> <option value="">f</option> <option value="">g</option> <option value="">h</option> <option value="">d</option> </select> </div> </div> <div class="form-group"> <label class="col-md-4 control-label">目的參考系:</label> <div class="col-md-8"> <select class="form-control" name="country"> <option value="">gd</option> <option value="">g</option> <option value="">g</option> <option value="">h</option> <option value="">d</option> </select> </div> </div> </fieldset> <div class="form-group"> <button type="submit" class="btn btn-primary">提交</button> <button type="reset" class="btn btn-primary">重置</button> </div> </form> </div> </div> </div> </div> </div> <!--文件列表彈出框--> <section id="file-list" v-show="toggleShow"> <ul> <li v-for="(item,index) in obj" @click = "$store.commit('showFileInfo',{a:index})"> {{item.name}} </li> </ul> </section> </div> </div>
run.js代碼:
/** * Created by Administrator on 2017/6/16. */ define(['vue','text!./run.html','../.././components/leftsidebar/leftsidebar'],function(Vue,Template,LeftSidebar){ var Run ={ data:function(){ return { showPre:true, showLog:false, showTest:"", toggleShow:'', obj:[{"name":"局部影像"},{"name":"柵格地圖"},{"name":"無控定位"}] } }, template:Template, mounted:function(){ $('#defaultForm').bootstrapValidator({ feedbackIcons: { valid: 'glyphicon glyphicon-ok', invalid: 'glyphicon glyphicon-remove', validating: 'glyphicon glyphicon-refresh' }, fields: { testName: { validators: { notEmpty: { message: '請輸入,不能為空!' }, stringLength: { min: 3, max: 20, message:'字符必須在3到20之間' }, regexp: { regexp: /^[\u4E00-\u9FA5A-Za-z0-9_]+$/, message: '只能輸入中文、英文和_' } } }, author: { validators: { notEmpty: { message: '請輸入,不能為空!' }, stringLength: { min: 3, max: 20, message:'字符必須在3到20之間' }, regexp: { regexp: /^[\u4E00-\u9FA5A-Za-z]+$/, message: '只能輸入中文、英文' } } }, desc: { validators: { notEmpty: { message: '請輸入,不能為空!' }, stringLength: { min: 3, message:'不能少於6個字符' } } } } }); }, methods:{ __showTest:function(){ this.showTest= true; }, __fileList:function(){ this.toggleShow = !this.toggleShow; }, __showPre: function(){ this.showPre = true; this.showLog = false; }, __showLog:function() { this.showPre = false; this.showLog = true; } }, components:{ "v-leftsidebar":LeftSidebar.leftSidebar } }; return { run:Run } });
這里就用到了store.js的其它代碼
其中用到的 leftsidebar 的結構和js代碼為:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <template id="test-info"> <div class="test-info-wrapper" style="width:200px;"> <header><h3>{{$store.state.testName}}</h3></header> <ul> <li v-for=" (item,index) in $store.state.allTool" @click.stop.prevent = "_showEveryTool(index+1)" style="display:block"> <div class="header"> <span class="glyphicon glyphicon-triangle-bottom" v-if="showEveryTool == (index+1)"></span> <span class="glyphicon glyphicon-triangle-right" v-else></span> <span>{{item.name}}</span> </div> <ul v-show="showEveryTool == (index+1)"> <li v-for="(innerItem1,index1) in item.inputFile.singleOne" @click.stop = "__showEveryTool1(index1+1)" style="padding-left:20px;display: block"> <div class="header"> <span class="glyphicon glyphicon-triangle-bottom" v-if="showEveryTool1 == (index1+1)"></span> <span class="glyphicon glyphicon-triangle-right" v-else></span> <span>{{innerItem1}}</span> </div> <ul v-show="showEveryTool1 == (index1+1)"> <li v-for="(innerItem2,index2) in item.inputFile.singleTwo" @click.stop = "__showEveryTool2(index2+1)" style="padding-left:20px;display: block"> <div class="header"> <span>{{innerItem2}}</span> </div> </li> </ul> </li> </ul> </li> </ul> </div> </template> </body> </html>
/** * Created by Administrator on 2017/6/27. */ define(['vue','text!./leftsidebar.html'],function(Vue,Template){ var LeftSidebar = { data:function(){ return { showEveryTool:false, showEveryTool1:false, showEveryTool2:false } }, computed:{ //當一些數據要根據其他的一些數據變化時,需要用到計算屬性 }, template:Template, mounted:function(){ this.$http.get("./data.json").then(function(res){ var data = res.body.pixel; this.$store.state.obj = data.sidebar; }); }, methods:{ _showEveryTool: function(current){ this.showEveryTool = current; }, __showEveryTool1:function(current){ this.showEveryTool1 = current; }, __showEveryTool2:function(current){ this.showEveryTool2 = current; } } }; return { leftSidebar:LeftSidebar } });
頁面為:

點擊打開 ,點擊 日志

點擊局部影像,柵格地圖地圖 ,無控定位
會顯示切換相關的信息

點擊新建會出現:

其中表單驗證不通過會報紅色。
總結:
require.js可以加載vue.js 因為vue.js也是模塊化的東西,其vue相關的插件也可以使用,這里僅僅舉的一個小例子,其核心是構建一個單頁應用的框架搭建,如有錯誤,請指教。既然使用vue ,建議使用webpack 和node 去構建項目,表單驗證可以使用 vee-validator 這個vue的插件。
