Angular请求数据

Angular请求数据

$http

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
angular.module('myApp',['ngSanitize'])
.controller('demoCtrl',['$scope','$http',function($scope,$http){
/*$.ajax({
url:'',
type:'',
data:{},
success:function(){},
error:function(){}
})*/
/*$http({
url:'./tpl/a.html',// 请求地址
method:'get', // 请求方式
// get请求需要传递的参数
params:{
a:1,
b:2
},
// post请求需要传递的参数
data:{
c:3,
d:4
}
}).then(function(res){
// 成功回调函数
console.log(res.data)
},function(){
// 失败回调函数
});*/
// 如果只有一个回调函数 代表成功
/*$http.get('./tpl/a.html',{ params:{a:1,b:2} }).then(function(res){
console.log(res.data)
})*/
$http.post('./tpl/a.html',{ c:3,d:4 }).then(function(res){
$scope.msg = res.data;
});
}])

配置白名单JSONP

由于angular认为跨域是不安全的所以必须配置白名单

1
2
3
4
5
6
7
8
9
10
11
12
13
angular.module('myApp', []).config(function($sceDelegateProvider) {
$sceDelegateProvider.resourceUrlWhitelist([ // 白名单
// Allow same origin resource loads.
'self',
// Allow loading from our assets domain. Notice the difference between * and **.
'http://srv*.assets.example.com/**' // 请求的地址
]);
// The blacklist overrides the whitelist so the open redirect here is blocked.
$sceDelegateProvider.resourceUrlBlacklist([
'http://myapp.example.com/clickThru**' // 黑名单
]);
});

angular API地址

angularJS

Angular自定义过滤器

Angular自定义过滤器

语法

1
2
3
4
5
6
7
模块对象.filter('自定义过滤器名字',[function(){
return function(要处理的数据,滤过器参数1,滤过器参数2,...){
// 具体处理数据的代码
return 处理后的数据;
}
}])

例子

电话号码以及首字母大写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
angular.module('myApp',[])
.filter('phoneStar',[function(){
return function(value){
var front = value.substr(0,3);
var last = value.substr(7);
// 在处理完数据以后 一定要return出去
return front + '****' + last;
}
}])
.filter('firstUpper',[function(){
return function(value,arg1,arg2,arg3){
console.log(arg1,arg2,arg3);
return value.substr(0,1).toUpperCase() + value.substr(1)
}
}])
.controller('demoCtrl',['$scope',function($scope){
$scope.phone = "18598787657";
$scope.word = "angular";
}])

Angular自定义指令

Angular自定义指令

语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
模块对象.directive('指令名称',[function(){
// 固定语法
return {
// angular提供的专门用来写DOM操作的地方
link : function(scope,element,attributes){
// 形参的名字 是可以改的
// element 指令所在的元素 jqLite对象
// attributes 指令所在元素身上的 属性集合
}
}
}])
js - > myDir
html -> my-dir
指令在页面中没有被使用 那么指令将不会被执行
指令在页面中被使用了多少次 那么指令将会被调用多少次
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
angular.module('myApp',[])
.directive('myDir',[function(){
return {
link:function(scope,element,attributes){
element.css('background','red');
console.log(attributes)
}
}
}])
.controller('demoCtrl',['$scope',function($scope){
}])

angularjqLite

语法

1
2
3
4
5
6
$('#div1')
$(document.getElementById('div1')).css()
angular.element( 原生JS对象 ) 把原生JS对象转换成JQLite对象 可以使用jq的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
angular.module('myApp',[])
.controller('demoCtrl',['$scope',function($scope){
var oDiv = angular.element( document.getElementById('div1') );
console.log(oDiv);
oDiv.css({
background:'green'
}).addClass('class1')
}])

指令的配置参数介绍

  • restrict 自定义指令分类

    • 属性指令 A attribute
  • 元素指令 E element
  • 样式指令 C class
  • 注释指令 M comment
  • 默认值是:’AE’

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <!-- 属性指令 -->
    <div my-dir></div>
    <!-- 标签指令 -->
    <my-dir></my-dir>
    <!-- 类名指令 -->
    <div class="my-dir"></div>
    <!-- 注释指令 -->
    <!-- directive:my-dir --> 通常配合 replace使用
  • template和templateUrl使用方法

    • template 模板字符串
    • templateUrl 定义angular模板
  • link函数的作用及参数说明

    • 作用:写DOM操作的地方
    • 有三个参数 scope element attributes
    • scope:类似于$scope 作用范围不同 只针对当前指令生效
    • element:当前指令所要操作的元素
    • attributes:当前指令所在标签的属性结合 对象类型
  • replace的作用

    • 将当前指令所在的标签替换掉
    • 布尔类型的值 默认是是false 不替换
  • transclude的作用

    • 如果指令所在标签内部有内容 会将内容保存到ng-transclude中
    • 然后在模板内将ng-transclude保存的内容写在想要显示的位置即可
    • 默认值是false 不保存原有内容 也就是直接用模板内容替换原有内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
angular.module('myApp',[])
.directive('myDir',[function(){
return { // 有几个地方用到了指令,那么这个就会被调用几次
scope:true, // 让每个指令所在的元素有单独的作用域
transclude:true,// 把指定所在标签内的内容保存 配合ng-transclude使用 配合一个标签放内容
replace:true, // 去掉指令所在的标签,保留模板内容,如果模板有多标签需要一个根标签包裹
template:"<span ng-transclude></span>"
link:function(scope,element,attributes){
element.css('background','red');
console.log(attributes)
}
}
}])
.controller('demoCtrl',['$scope',function($scope){
}])

Angular控制器

Angular控制器

语法

1
2
angular.module('模块名称',['要依赖的模块名字1','要依赖的模块名字2'),是用来创建模块的 如果没有依赖 第二个参数要写一个空数组
模块对象.controller('控制器名称',function(){}) 是用来创建控制器的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/*
myApp变量 是创建模块返回的模块对象
myApp字符串 是创建的模块的名字
ng-app指令里面写的是 模块的名字
*/
var myApp = angular.module('myApp',[])
myApp.controller('demoCtrlA',function($scope){
// $scope 名字不能改 是对象类型的
// 专门用来向控制器控制的区域 暴露数据
$scope.msg = '我是demoCtrlA里面的MSG';
$scope.val = "我是通过控制器赋的初始值";
$scope.clickFn = function(){
alert('就点你了,怎么地吧')
}
});
myApp.controller('demoCtrlB',function($scope){
$scope.msg = "我是demoCtrlB里面的MSG";
});

模块化的依赖

1
2
3
4
5
6
7
8
9
10
/*
依赖的某一个模块就相当于 拥有了这个模块的功能
1.将被依赖的模块通过 script 标签引入
2.将被依赖的模块 名字 写在主模块的第二个参数中
*/
angular.module('myApp',['lunbotuModule']);

模块第二个参数不写的区别

1
2
3
4
5
6
7
8
9
/*
加第二个参数 是 创建模块
不加第二个参数 是 获取模块
*/
// var myApp = angular.module('myApp',[]);
// console.log( myApp == angular.module('myApp') );
angular.module('myApp');

面向对象的方式创建控制器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<body ng-app="myApp" ng-controller="demoCtrl as hello">
<p>{{hello.name}}</p>
<p>{{age}}</p>
<script src="node_modules/angular/angular.min.js"></script>
<script>
angular.module('myApp', [])
/*
1.angular内部会帮我们new控制器处理函数
2.demoCtrl as hello 这个hello就是new出来的对象
3.在视图中我们就可以使用hello.属性的方式取到hello对象中的值
4.面向对象的方式和$scope可以同时使用
*/
.controller('demoCtrl', ['$scope', function($scope) {
this.name = '我是孙悟空';
$scope.age = '我今年500岁';
}])
</script>
</body>

angular

Angular介绍

SPA

单页面的特点:

  1. 页面不发生传统的意义跳转,通过ajax局部刷新来打到视觉上的跳转
  2. 整个网站只有一个页面,公共部分只加载一次,不会发生页面跳转白屏的现象
  3. 锚点值与页面是一一对应的关系

框架与库:

  • 无论是angular还是jQuery都是用原生JS封装的
  • 库:
    • 对代码进行封装 调用封装的方法 简化操作
      • jquery 针对DOM操作
      • requirejs js模块化
  • 框架:
    • 虽然也是调用封装的方法
    • 但是更多的框架会提供代码书写的规则
    • 我们要按照规则去写代码 框架会帮我们实现相应的功能
  • 框架与库区别:
    • 范围不同:库仅仅针对某一个方面,框架包含的范围比较广
    • 库只是调用封装好的方法,框架会提供代码书写规则

Angular核心思想

  • write less do more
  • 其核心是通过指令扩展了HTML,通过表达式绑定数据到HTML。
  • Angular不推崇DOM操作,也就是说在NG中几乎找不到任何的DOM操作
  • 一切操作以数据为中心,用数据驱动DOM

Angular常用过滤器

Angular常用过滤器

语法

1
{{ 数据 | 过滤器的名字:参数1:参数2 }}

currency 货币过滤器

1
2
<h4>货币过滤器</h4>
<p>{{ money | currency:'¥' }}</p>

date 日期过滤器

1
2
<h4>日期过滤器</h4>
<p> {{ date | date:'yyyy年MM月dd日 HH时mm分ss秒' }} </p>

filter 过滤器

可以按照某种规则对数据进行筛选

1
2
3
4
5
6
7
8
9
模糊匹配
在循环数据的过程中 去数据中的 [每一个字段中去查找] 看字段对应的值中 [是否包含] 过滤的关键字 如果包含 留下 如果不包含 过滤掉
<h4>filter 过滤器 模糊匹配</h4>
<ul>
<li ng-repeat="item in persons | filter:'李四' ">
{{ item.id }} {{ item.name }} {{ item.age }}
</li>
</ul>
1
2
3
4
5
6
7
8
9
精确匹配
在循环数据的过程中 去数据中的 [指定的字段中去查找] 看字段对应的值中 [是否包含] 过滤的关键字 如果包含 留下 如果不包含 过滤掉
<h4>filter 过滤器 精确匹配</h4>
<ul>
<li ng-repeat="item in persons | filter:{ name:'赵六' } ">
{{ item.id }} {{ item.name }} {{ item.age }}
</li>
</ul>

limitTo 限制过滤器

  • 第一个参数:limit 限制的数量,可以为负数,从后往前开始限制
  • 第二个参数:begin 从第几个开始限制
1
2
3
4
5
6
7
<h4>limitTo过滤器</h4>
<p>{{ word | limitTo:2:2}}</p>
<ul>
<li ng-repeat="item in persons | limitTo:2:1">
{{ item.id }} {{ item.name }} {{ item.age }}
</li>
</ul>

orderBy 排序过滤器

可以按照某一个字段进行排序 升序或者 降序

1
2
3
4
5
6
<h4>orderBy过滤器</h4>
<ul>
<li ng-repeat="item in persons | orderBy:'-age' "> 负号代表降序
{{ item.id }} {{ item.name }} {{ item.age }}
</li>
</ul>

json 过滤器

可以将数据以良好的格式显示在页面中,需要配合pre标签使用

1
2
3
4
<h4>json过滤器</h4>
<p>
<pre>{{ persons | json:spacing}}</pre>
</p>

大小写过滤器

1
<div> {{ msg | uppercase }} </div>

数字过滤器

1
2
3
<p>
{{ number | number:2 }} 参数代表小数点的个数
</p>

上面过滤器的参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
angular.module('myApp',[])
.controller('demoCtrl',['$scope',function($scope){
$scope.money = 998.011;
$scope.date = new Date();
$scope.persons = [
{
id:1,
name:'张三',
age:20
},
{
id:2,
name:'李四',
age:30
},
{
id:3,
name:'王五',
age:10
},
{
id:4,
name:'赵六',
age:50
}
]
$scope.word = '我爱祖国';
$scope.msg = 'angular';
$scope.number = 123477777777777755;
}])

Angular服务

Angular服务

抽象公共代码的

语法

1
2
3
4
5
6
7
8
9
10
11
服务的作用:是用来抽象公共代码的
模块对象.service('服务名称',[function(){
this.name = '张三';
this.say = function(){
alert(this.name);
}
}])
是用来创建服务的
angular 会将服务的回掉函数当作构造器来new
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
angular.module('myApp',[])
.service('myService',[function(){
this.name = '张三';
this.say = function(){
alert(this.name);
}
}])
.controller('demoCtrlA',['$scope','myService',function($scope,myService){
myService.name = '李四';
}])
.controller('demoCtrlB',['$scope','myService',function($scope,myService){
myService.say();
}])

Angular普通指令

Angular普通指令

ng-app

  • 告诉angular它在页面中所要控制的范围
  • 页面加载完成angular会自动在页面中查找这个指令
  • 如果页面中没有这个指令,angular将不会启动
  • 告诉angular当前页面由哪一个模块来管理
1
<body ng-app="module">

ng-model

实现双向数据绑定(获取表单元素中的值)

1
<input type="" value="11" ng-model="val">

双向绑定原理

脏检查机制

angular在页面加载完成之后会在页面中查找ng-agg指令,如果找到会在js中创建一个对象来存储页面中的数据,当html页面中文本框的值改变之后,angular会取到文本框的值然后赋给创建出对象里的变量,对象变量发生改变的时候,angular会在页面中找哪一个地方使用到了这个变量,找到之后将变量更新成最新的值,这个过程叫数据双向数据绑定

1
ng-model="变量"

实现双向数据绑定的条件

  • 必须是表单元素
  • 在表单元素身上写 ng-model指令

ng-init

初始化变量的值

1
ng-init="变量1=值1;变量2=值2"

ng-click

点击事件(和原生JS中的onclick事件作用一样)

ng-repeat

遍历数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<body ng-app="myApp" ng-controller="demoCtrl">
<h4>遍历 一维数组</h4>
<ul>
<!--
ng-repeat 遍历数据 类似于for in 循环
in 是固定写法
in 后面加上要遍历的数据
item 是遍历的当前项(item这个词可以随意写)
这个指令可以加在任何标签上
-->
<li ng-repeat="item in data">
{{item}}
</li>
</ul>
<hr />
<h4>遍历 数组中混合对象</h4>
<p ng-repeat="item in person">{{item.name}} {{item.age}}</p>
<hr />
<h4>遍历 对象</h4>
<!--
key代表对象的键值
val代表对象键值对应的值
-->
<div ng-repeat="(key,val) in obj">
{{key}} {{val}}
</div>
<script src="node_modules/angular/angular.min.js"></script>
<script>
angular.module('myApp',[])
.controller('demoCtrl',['$scope',function($scope){
// 一维数组
$scope.data = ['小明','小红','小黑','小琴'];
// 数组中混合对象(最常用的形式)
$scope.person = [
{name:'小明',age:18},
{name:'小红',age:28},
{name:'小红',age:28},
{name:'小黑',age:38},
{name:'小琴',age:48}
]
// 对象
$scope.obj = {
name:'小明',
age:35,
hobby : '吃饭'
}
}])
</script>
</body>

ng-repeat中所用到的索引

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$index : 遍历过程中的索引
$first : 布尔类型的值 当前是否是第一项 是返回true 不是返回false
$last : 布尔类型的值 当前是否是最后一项 是返回true 不是返回false
$middle : 布尔类型的值 第一项和最后一项返回false 其余返回true
$even : 偶数项返回true 否则返回false
$odd : 奇数项返回true 否则返回false
利用这些值在循环的过程中做各种判断 达到我们想要的目的
<ul>
<li ng-repeat="item in person" class="{{$first ? 'first' : ''}} {{ $last ? 'last' : ''}}">
<p>名字:{{item.name}}</p>
<p>年龄:{{item.age}}</p>
<p>索引:{{$index}}</p>
<p>是否是第一项:{{$first}}</p>
<p>是否是最后一项:{{$last}}</p>
<p>是否是中间项:{{$middle}}</p>
<p>是否偶数项:{{$even}}</p>
<p>是否奇数项:{{$odd}}</p>
</li>
</ul>

遍历中不能有重复类型的值(基本数据类型)

在遍历的数据后面写上track by 一个唯一(不重复)的值 一般会写$index

1
2
3
4
5
6
7
<div ng-repeat="item in data track by $index">
{{item}}
</div>
<hr />
<div ng-repeat="(key,val) in data track by key">
{{val}}
</div>

ng-class

操作类名

1-指令的值以对象的形式存在

2-对象的属性值转化为布尔值是true时,将当前的属性名作为类名添加到class属性中

3-对象的属性值转化为布尔值是false时,将当前的属性名从class属性中删除掉

4-属性值可以是数据模型,也可以是JS表达式

1
2
3
4
5
.color{
background: red;
}
-----------------------------------------
<div ng-class={color:true}> 你好么</div>

注意:angular不推崇DOM操作,在当前例子中并没有直接操作类名的JS语句, 而是通过数据模型isGreen的值是true还是false来确定添加哪个颜色的类名,至于如何添加到class属性中,由angular替我们完成。

数据绑定

页面中闪烁的问题

ng-bind

1
ng-bind="变量"

ng-bind-template

1
ng-bind-template=" {{ 变量1 }} {{ 变量2 }}"

ng-cloak

angular会隐藏有ng-cloak指令或样式的元素,在做完解析之后又会移除元素身上的ng-cloak样式和指令,从而解决表达式闪烁的问题

但是!angular在页面的最后才被引用进来,所以不能很好的解决这个问题需要我们手动在页面顶部加上隐藏元素的样式

1
2
3
4
5
6
7
<style>
.ng-cloak,[ng-cloak]{display:none;}
</style>
-----------------------------------------
<div class="ng-cloak">
{{msg2}}
</div>

ng-non-bindable

不让angular解析其中的代码

ng-show(ng-hide)

控制元素显示隐藏(通样式的方式 display:none),当值为true时 元素显示,当值为false时 元素隐藏

ng-if

控制元素显示隐藏

区别是ng-if是通过DOM节点的添加和删除使得元素显示和隐藏

ng-switch、ng-switch-when

ng-switch ng-switch-when 是一对指令类,似于JS中 switch case 语句, 匹配到哪项 哪项就显示 其他项就隐藏,常用于 做多个选项卡的显示和隐藏

1
2
3
4
5
6
7
8
9
10
11
<body ng-app ng-init="showNum=1">
<div ng-switch="showNum">
<button ng-click="showNum=1">显示1</button>
<button ng-click="showNum=2">显示2</button>
<button ng-click="showNum=3">显示3</button>
<div ng-switch-when="1">1</div>
<div ng-switch-when="2">2</div>
<div ng-switch-when="3">3</div>
</div>
<script src="node_modules/angular/angular.min.js"></script>
</body>

ng-options

生成select下拉列表 需要配合ng-model指令使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
ng-options 用于生成下拉列表 需要和ng-model指令一起使用 否则报错
<select ng-options="item.value as item.name for item in balls"></select>
item.name for for是固定语法 angular会将name字段对应的值 放在option标签内
item.value as as是固定语法 angular会将value字段对应的值 放在option标签的value属性上
--------------------------------------------------------------------------------
<select ng-model="likeBall" ng-options="item.value as item.name for item in balls"></select>
{{likeBall}}
<script src="node_modules/angular/angular.min.js"></script>
<script>
angular.module('myApp',[])
.controller('demoCtrl',['$scope',function($scope){
// 给下拉列表设置默认值 和options标签value属性的值对应
$scope.likeBall = "001";
// 下拉列表的数据源
$scope.balls = [
{
name:'足球',
value:'001'
},
{
name:'篮球',
value:'002'
},
{
name:'橄榄球',
value:'003'
},
{
name:'排球',
value:'004'
},
{
name:'乒乓球',
value:'005'
}
];
}])
</script>
</body>

ng-style

添加样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<span ng-style="{'width':'100px','height':'100px'}"></span>
<span style="width:100px;height:100px;"></span>
scope.style = {
background:'skyblue',
width:'100px',
height:'100px',
position:'fixed',
lineHeight:'100px',
fontSize:'40px',
textAlign:'center',
right:'10px',
bottom:'10px',
cursor:'pointer'
};

ng-bind-html

1
ng-bind-html="变量" 能够正常解析数据中的HTML标签

事件指令

ng-click

ng-dblclick

ng-blur

ng-focus

ng-change

其他指令

ng-href

ng-src

表达式

  • 双大括号的形式称之为插值表达式
  • 在表达式中可以写ng中的变量
  • 可以显示字符串
  • 在表达式中可以进行计算
  • 可以在表达式中写三目运算符
  • 执行angular函数

前端模块化

前端模块化

模块化

对js代码的管理,将指定内容的功能分为一个一个模块,这些模块在引用的时候被调用进来,具有复用性,并且代码分门别类,易于维护和管理

模块化的标准

CommonJS 模块标准化

CommonJS 主要用在Node.js当中 代表Node.js 适用于后端

AMD 模块化标准

Async Module Definition 适用于前端开发, 代表 Require.js

所有的模块尽可能早的会被加载进来!!

Require.js

它是帮我们实现前端模块化的工具,他遵循的标准AMD

定义模块

requirejs提供了一个全局的函数,来定义模块,一个模块通常都会单独保存成一个文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//形式 define(funciton(){ /* 模块自己的代码 */})
define(["./moduleC.js"],function(){
console.log("我是B中的模块")
});
//当模块要提供内容给别人使用的时候,需要使用return语句将内容进行返回
define(["./moduleB.js"],function(){
console.log("我是A中的模块");
var obj = {
sayHello:function(){
console.log("我是调用的结果")
}
}
return obj;
});
//当模块依赖于别的模块的时候,需要给当前模块添加依赖项
//define(["依赖项", "依赖项"], function(依赖项的返回值){ })
引用模块

requirejs提供了一个全局的函数。来引用模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//require(["模块的名称(不需要.js后缀)"]) 新版本有.js后缀也没关系
require(["./moduleA"]);
//第二参数的函数,为 模块加载完毕之后的回调函数
require(["./moduleA"],function(){});
//如果引用的模块有产出内容,在引用的模块内通过return返回了东西
//我们可以通过在回调函数中添加形参,来接收前面的模块的返回内容
//形参和模块是一一对应的
//在某个js文件定义一个模块 具有返回值的模块
define(["./moduleA"],function(){
console.log("我是A中的模块");
var obj = {
sayHello:function(){
console.log("我是调用的结果")
}
}
return obj;
});
------------------------------------------------------------------------
require(["./moduleA"], function(obj){
obj.sayHello();
console.log(obj);
});
data-main

在请求requirejs的script标签中添加一个data-main属性,指向一个js文件

在引用requirejs的script表里面加一个data-main, 当requirejs加载完毕之后,会请求加载data-main指向的文件,并执行里面的内容(这个文件的加载是异步的!!)

data-main所指的文件是异步加载的,所以如果在下面有依赖于data-main文件中实现的功能的代码,那么,很可能出错

1
2
3
4
5
6
7
8
9
//main.js里的代码
var input = document.createElement("input");
div.id = "txt";
document.body.appendChild(input);
----------------------------------------------------------
<script src="require.js" data-main="main.js"></script>
<script>
document.getElementById("txt").value = "123";
</script>
模块路径的研究
  1. 当直接使用require来引用一个模块的时候,那么模块的路径会以当前调用require方法的html页面为基础来查找
  2. 如果使用data-main属性,那么路径的查找,会以这个data-main所指的文件为基础来查找!
  3. 如果通过config方法指定了 baseUrl 那么所有的模块查找都会以baseUrl中设置的路径为基础(常用)

注意: 在设置了baseUrl之后,文件会首先按照baseUrl作为基础去查找,如果找到了,就直接使用,如果没有找到,按照引用模块的文件本身作为基础再去查找!

模块的应用路径可以写两种(都有效),一种按照baseUrl作为基础来写,另外一种就是按照当前文件路径来写

require.config
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//config方法可以用来对requirejs进行配置
//传的参数是一个对象
require.config({
//如果使用baseUrl来设置了基本路径,那么所有的模块查找都会以该路径作为基础
//如果按照baseUrl找文件找不到,那么requirejs还会以引用模块的代码所在文件为基础再查找一次
baseUrl: "/",
//paths中可以为模块路径设置一个别名(id)
//以后在使用模块的时候,直接用别名即可!
//paths中只需要添加 特别常用的内容即可
paths: {
//属性名:别名(id)
//属性值:别名代表的模块路径!!!
"a": "modules/a/b/c/moduleA",
"b": "modules/a/b/c/moduleB",
"c": "modules/a/b/c/moduleC",
}
shim: {
//做第三方模块的加载配置 可以配置依赖项 也可以配置导出项(返回值)
"要配置的模块的别名id": {
deps: ["模块的依赖项"],
exports: "模块要返回的内容(是一个字符串,requirejs会在模块中找和字符串相同的全局变量,将其值作为当前模块的返回值!)"
}
}
});
require(["a"]);
require.js引入第三方模块

支持引入第三方模块 \b define\b

1
2
3
require(["jquery"],function($){
console.log($("body"));
});

不支持第三方模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
shim: {
//要设置哪个模块
animate: {
//对象中包含这个第三方内容的配置信息
//1、配置模块的输出项
//exports就是用来设置这个模块的输出项的 ,就类似于给这个模块中添加了返回值!
//这个属性值是一个字符串, require会自动去这个模块中找和字符串同名的全局变量
//将这个全局变量设置为 模块的返回值
exports: "obj"
},
bigger: {
//配置当前模块的依赖项
deps: ["jquery"]
}

CMD 模块化标准

Common Module Definition 适用于前端开发 代表 sea.js

as lazy as possible
只有在需要的时候,才去加载!!

require.js 没有明显的bug, sea.js明显没有bug

模块定义

模块定义

commonjs

amd

umd

cmd

ES6 模块

  • import 导入
  • export 导出

import export

默认导出导出

  • import 变量名 from './xx.js'
  • export default 对象;
  • 声明式
    • import {固定的导出key} from './xxx.js';
    • export let 固定的导出key = 'xxx';
    • 或者两步导出
      • var 固定的导出key = 'xxxx';,
      • export {固定的导出key};
  • 全体导入
    • import * as 变量名 from './xxx.js';
    • 该对象 具备不同的key + default属性
  • import 和 export 只能在顶级作用域中使用,不能再{} 块级或者函数中使用