基于angular+bower+glup的webapp

一:bower介绍

1:全局安装安装bower

cnpm i -g bower

bower常用指令:

bower init    //初始化文件
bower install
bower uninstall

2:bower初始化配置:

bower init

后续的填写全部选yes

3:安装依赖(angularjs)这里可能会报没有安装git的错,所以我们还要安装git。

bower install -- save angular

4:创建.bowerrc

null>.bowerrc

这时候会提示null不是内部指令,但是没问题,已经创建好了。

然后在文件中输入:

{
        "directory": "lib"
}

这段代码的意思是,接下来我们bower install后的依赖都会放在lib这个文件夹下

5:安装requirejs

bower install --save requirejs

这时候我们发现angular和require都放到了lib这个文件夹下了

6:删除目录,卸载requirejs

刚才4、5步在项目中没啥用处,我们使用bower uninstall卸载requirejs,然后删除lib目录和bowerrc文件

bower uninstall --save requirejs

二:自动化构建工具gulp项目结构介绍

gulp新建目录

1:全局安装gulp

cnpm i -g gulp

2:定义node的安装模块文件package.json

npm init

后面需要填写的部分全部回车跳过

3:安装模块

模块安装的语法:cnpm i --save-dev xxxx

cnpm i --save-dev gulp

接下来我们批量安装其他的模块,多个模块之间用空格隔开:语法为cnpm i --save-dev xxxx xxxx xxxx xxxx

cnpm i --save-dev gulp-clean gulp-concat gulp-connect gulp-cssmin gulp-imagemin gulp-less gulp-load-plugins gulp-plumber gulp-uglify open

4:新建配置文件gulpfile.js

拷贝依赖文件的方法:

var gulp = require('gulp'); //引用gulp模块
var $ = require('gulp-load-plugins')(); //其他以gulp-开头的模块都不需要再定义变量了,可以直接用$引用
var open = require('open'); //这个不是以gulp开头,需要引用

var app = {  //声明目录路径的全局变量
  srcPath: 'src/',
  devPath: 'build/',
  prdPath: 'dist/'
};
gulp.task('lib', function() {               //拷贝js的方法
  gulp.src('bower_components/**/*.js')      //读取bower_components路径下所有的js文件
  .pipe(gulp.dest(app.devPath + 'vendor'))  //dest()是写文件api
  .pipe(gulp.dest(app.prdPath + 'vendor'))
});

接下来我们执行gulp lib。执行成功后会我们会将所有的依赖文件都拷贝到build和dist文件夹下

注意:如果这里报错:cannot find module xxx说明之前安装依赖时有的依赖没有安装上,那缺什么依赖我们就cnpm i xxx啥依赖

接下来写拷贝html的方法:

gulp.task('html', function() {
  gulp.src(app.srcPath + '**/*.html') //读取app.srcPath路径下所有的html文件
  .pipe(gulp.dest(app.devPath))
  .pipe(gulp.dest(app.prdPath))
})

我们新建一个src文件夹,然后在src文件夹下新建index.html。view文件夹和view下的view.html

接着我们执行gulp html。执行成功后会我们会将index.html和view文件夹都拷贝到build和dist文件夹下

然后我们写拷贝json的方法,因为项目的数据没有和后台交互,所以我们要定义假的数据。

gulp.task('json', function() {
  gulp.src(app.srcPath + 'data/**/*.json') //读取app.srcPath路径下所有的json文件
  .pipe(gulp.dest(app.devPath + 'data'))
  .pipe(gulp.dest(app.prdPath + 'data'))
});

在src文件夹下新建data文件夹,然后在data文件夹下新建1.json。 

接着我们执行gulp json。执行成功后会我们会将data文件夹和1.json都拷贝到build和dist文件夹下

接下来是拷贝less的方法:

gulp.task('less', function() {
  gulp.src(app.srcPath + 'style/index.less') //读取app.srcPath路径下所有的less文件
  .pipe($.less())
  .pipe(gulp.dest(app.devPath + 'css'))
  .pipe($.cssmin()) //生产环境压缩
  .pipe(gulp.dest(app.prdPath + 'css'))
});

我们在src下新建style文件夹,然后在里面新建index.less

接着我们执行gulp less。执行成功后会我们会将css文件夹和index.css拷贝到build和dist文件夹下(这里的index.css是编译过后的index.less)

接下来是拷贝js的方法:

gulp.task('js', function() { //读取app.srcPath路径下所有的js文件
  gulp.src(app.srcPath + 'script/**/*.js')
  .pipe($.concat('index.js')) //合并js文件
  .pipe(gulp.dest(app.devPath + 'js'))
  .pipe($.uglify())  //生产环境压缩
  .pipe(gulp.dest(app.prdPath + 'js'))
});

我们在src下新建script文件夹,然后在里面新建1.js和2.js,测试是否合并了js文件

接着我们执行gulp js。执行成功后会我们会将js文件夹和index.js拷贝到build和dist文件夹下(这里的index.js是合并过后的)

接下来是拷贝image的方法:

gulp.task('image', function() { //读取app.srcPath/image路径下所有的文件(jpg,png等)
  gulp.src(app.srcPath + 'image/**/*')
  .pipe(gulp.dest(app.devPath + 'image'))
  .pipe($.imagemin()) //生产环境再压缩
  .pipe(gulp.dest(app.prdPath + 'image'))
});

我们在src下新建image文件夹,然后在里面放入一个png格式的图片

接着我们执行gulp image。在这里可能会抛出一个unhanded error event。这个错误好像是这个图片压缩插件对win7不友好。

如果我们需要删除某个文件夹:

gulp.task('clean', function() {  //清除build和dist文件
  gulp.src([app.devPath, app.prdPath])
  .pipe($.clean());
});

接着我们执行gulp clean。执行完成后build和dist文件夹都被删除了。

合并上述方法:

gulp.task('build', ['image', 'js', 'less', 'lib', 'html', 'json']); //合并方法

执行gulp build后,会将执行合并的几个方法。

接下来是开启服务的方法:

gulp.task('serve', ['build'], function() {  //开启服务
  $.connect.server({
    root: [app.devPath],  //根目录
    livereload: true,     // 热更新
    port: 3000
  });
  open('http://localhost:3000');

  gulp.watch('bower_components/**/*', ['lib']);  //监控文件的变化,并实时编译
  gulp.watch(app.srcPath + '**/*.html', ['html']);
  gulp.watch(app.srcPath + 'data/**/*.json', ['json']);
  gulp.watch(app.srcPath + 'style/**/*.less', ['less']);
  gulp.watch(app.srcPath + 'script/**/*.js', ['js']);
  gulp.watch(app.srcPath + 'image/**/*', ['image']);
});

执行gulp serve后,浏览器会打开http://localhost:3000。因为在win7上image这个方法会报错,所以我们得将build中的image和gulp.watch的image都去掉。编译成功后,我们直接修改index.html中的内容,保存一下发现页面已经刷新内容了(热更新)。gulp.watch这个方法使用的前提是需要给其监控的方法中加上一句代码

.pipe($.connect.reload());

:如html这个方法修改为:

gulp.task('html', function() {
  gulp.src(app.srcPath + '**/*.html') //读取app.srcPath路径下所有的html文件
  .pipe(gulp.dest(app.devPath))
  .pipe(gulp.dest(app.prdPath))
  .pipe($.connect.reload());
})

然后是默认的方法

gulp.task('default', ['serve']); //默认的方法

当我们执行gulp指令时,会执行默认的gulp serve。

三:页面的开发

模块划分: 本次应用划分为: 职位 搜索 用户

一:页面架构 :页面中的相对路径都是dist和build下的。

1:在index.html中引入angular.min.js和index.js

<script src="vendor/angular/angular.min.js" charset="utf-8"></script>
<script src="js/index.js" charset="utf-8"></script>

注意:这里的index.js是所有的js合并的js文件。

2:在script下新建app.js

'use strict';
angular.module('app', ['ui.router']); //全局对象angular,module方法可以创建模块,[]里面是模块的依赖。模块需要启动,第一种是angular.boostrap()

  

二:路由配置与安装

1:安装与引用

bower install --save angular-ui-router

之后我们在页面中引入: 这里的vendor其实是打包后dist和build下的文件目录。

<script src="vendor/angular-ui-router/release/angular-ui-router.min.js" charset="utf-8"></script>

然后在app.js中引入此模块

angular.module('app', ['ui.router']);

2:在script>config>router.js

'use strict'

angular.module('app').config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
  $stateProvider.state('main', {
    url: '/main',
    templateUrl: 'view/main.html',
    controller: 'mainCtrl'
  })
  $urlRouterProvider.otherwise('main');
}])

3:新建src>view>main.html

<div class="">
  angular
</div>

4:新建script>controller>mainCtrl.js

'use strict';
angular.module('app').controller('mainCtrl', ['$scope', function($scope){

}]);

三:职位页面的开发

1:在main.html添加

<div app-head></div>
<div app-position-list></div>
<div app-foot></div>

2:添加head模板template>head.html

<div class="head">
  <span>10秒定制职位</span>
  <button>去登陆</button>
</div>

3:添加指令directive>head.js

'use strict';
angular.module('app').directive('appHead', [function(cache){
  return {
    restrict: 'A', //A是以属性方式调用指令
    replace: true, //为true时,模板必须要有根元素
    templateUrl: 'view/template/head.html'
  };
}]);

4:添加样式文件style>template>head.less

@import '../variable.less';

.head {
  background-color: @headBgColor;
  .h(40);
  .lh(40);
  padding: 0 7px;
  .text {
    color: @defaultColor;
  }
  .custom {
    background-color: @warnColor;
    border-color: @warnColor;
    color: @defaultColor;
    border-style: dashed;
    .mt(7);
    .pl(15);
    .pr(15);
  }
  .back-btn {
    font-size: 20px;
    width: 1rem;
    left: 0;
  }
}

样式文件需要在index.less中引用进来,我们也可以在index.less中将一些css方法写进去

@import 'template/head.less';

新建variable.less将主题颜色定义

@defaultColor: #fff;
@headBgColor: #12d5b5;
.............

新建property.less将一些具有固定值的css定义

.ta-l {
  text-align: left;
}
.ta-c {
  text-align: center;
}
.ta-r {
  text-align: right;
}
�。。。。。

  

之后我们要在index.html中将css引入进来

  <link rel="stylesheet" href="/css/index.css" media="screen" title="no title" charset="utf-8">

四:搜索页面的开发

1:创建全局变量

在script>config>dict.js

'use strict';
angular.module('app').value('dict', {}).run(['dict', '$http', function(dict, $http){
  $http.get('data/city.json').success(function(resp){
    dict.city = resp;
  });
  $http.get('data/salary.json').success(function(resp){
    dict.salary = resp;
  });
  $http.get('data/scale.json').success(function(resp){
    dict.scale = resp;
  });
}]);

如何使用全局变量:依赖注入并声明:

angular.module('app').controller('searchCtrl', ['dict', '$http', '$scope', function(dict, $http, $scope){

  

2:创建过滤器

新建script>filter>filterByObj.js

'use strict';
angular.module('app').filter('filterByObj', [function(){
  return function(list, obj) {
    var result = [];
    angular.forEach(list, function(item){
      var isEqual = true;
      for(var e in obj){
        if(item[e]!==obj[e]) {
          isEqual = false;
        }
      }
      if(isEqual) {
        result.push(item);
      }
    });
    return result;
  };
}]);

使用:

找到需要使用的页面:

ng-repeat="item in data|filterByObj:filterObj"

这里的data是filterByObj的list参数(被过滤的对象),fliterObj是参数obj(过滤条件)。

五:页面动画切换angular.animate.js

1:安装:

bower install --save angular-animate

2:使用:app.js中注入

angular.module('app', ['ui.router', 'ngCookies', 'validation', 'ngAnimate']);

  

 

项目文件夹:

bower_components:第三方依赖
src:源码
build: 编译后的开发环境代码
dist:压缩后生产环境代码
test:单元测试和集成测试代码
node_modules:node安装依赖包