如今前端界angular react vue三大框架並駕齊驅,其中有一個共同點就是組件化開發,這也符合w3c 推行Web Components的趨勢。現如今不懂組件化開發的前端絕對不是好廚子。跳槽新公司pc端使用angular1.5的Components比較多,趁著入職前幾天自己看一下。 由於ang ...
如今前端界angular react vue三大框架並駕齊驅,其中有一個共同點就是組件化開發,這也符合w3c 推行Web Components的趨勢。現如今不懂組件化開發的前端絕對不是好廚子。跳槽新公司pc端使用angular1.5的Components比較多,趁著入職前幾天自己看一下。
由於angular2.0學習曲線比較陡峭(對於我這種菜雞來說),為了讓開發者平穩的從angular1.x 版本過渡到angular2,所以angular1.5中引入了components,需要註意的是所有components能實現的功能directive都能實現。 順便說一句1.5之前的directive感覺有點混亂,既包括指令又包括組件(我自己感覺指令是不應該有dom結構的,而組件是應該有的)
介紹
angular1.5 Components比較適合組件化編程架構的程式,相比於之前的指令有以下幾個優點。
1.比指令的配置更加簡單
2.自帶預設配置使之符合最佳實踐
3.更適合組件化架構的程式
4.使用Components更符合angular發展的趨勢
當然有些情況下不要使用Components
1.當你想使用compile和pre-link這兩個鉤子時,因為components不包含這兩個鉤子,所以component無法用於操作DOM。
2.當你想作為屬性或者css類名調用時,components只能作為自定義的HTML元素調用
使用
定義一個組件
function HeroDetailController($scope) {
console.log($scope)
// console.log(this.hero)
}
angular.module('heroApp').component('heroDetail', {
templateUrl: './heroDetail.html',
controller:['$scope',HeroDetailController] ,
bindings: {
hero: '='
}
});
調用組件(只能作為自定義的HTML元素調用)
<hero-detail hero="ctrl.hero"></hero-detail>
Components和Directive的主要區別如下
1.directive預設作用域不隔離(scope預設為false),Components預設父子組價作用域隔離
2.directive當設置scope為對象時,屬性有三種首碼標示符可以設置 "@"(單項綁定的首碼標識符,傳字元串用) "="(雙向數據綁定首碼標識符,即父子變化都會互相影響) "&"(綁定函數方法),Components的bindings比directive的scope多了一種"<"(單向數據傳輸,即父組件改變狀態會影響子組件的狀態,字組件改變狀態不會影響父組件的狀態)
3.directive中有link函數,操作dom在link中,而Components沒有link所以不能用於操作dom
Components(生命周期)鉤子函數
angular1.5為每個組件提供了生命周期鉤子函數去響應不同的時刻,有以下幾個鉤子
1.$onInit():此時controller構造函數初始化完畢(包括bindings中的數據),所以controller中初始化的代碼應該放在這裡。
2.$onChanges(changesObj):當bindings單向數據變化時會觸發這個鉤子
3.$doCheck():每次臟檢查會觸發的鉤子
4.$onDestroy():當controller的scope銷毀時會觸發的鉤子
5.$postLink():當組件及其子組件的元素已經被編譯和鏈接觸發的鉤子
註意
雖然bindings父子間數據可以設置為"=",但是最好設置為"<",這樣父組件改變狀態可以影響子組件,反之則不行。如果想子組件觸發父組件狀態的變化,因該傳入父組件的回調函數。如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body ng-app="heroApp">
<script src="./angular.js"></script>
<div ng-controller="MainCtrl as ctrl">
<b>Hero</b>
<br>
<hero-detail age="ctrl.age" modify-age="ctrl.modifyAge()"></hero-detail>
父組件{{ctrl.age}}
<div>{{ctrl.out}}</div>
</div>
<script>
angular.module('heroApp', []).controller('MainCtrl', function MainCtrl($scope) {
this.age = '18'
var that = this
setTimeout(function() {
that.age = '20'
$scope.$apply()
}, 2000);
this.modifyAge=function(){
that.age='22'
$scope.$apply()
}
});
function HeroDetailController($scope) {
var that = this
setTimeout(function() {
that.modifyAge()
}, 4000);
}
angular.module('heroApp').component('heroDetail', {
template: '子組件{{$ctrl.age}}',
controller: ['$scope', HeroDetailController],
bindings: {
age: '<',
modifyAge:'&'
}
});
</script>
</body>
</html>
參考文章
angular1.5 官網
鉤子函數詳解