DOMTokenList接口的 add() 方法將給定的標記添加到列表中,remove() 方法從 DOMTokenList 中移除指定標記。
添加或者移除class:
document.getElementById('id').classList.add('class');
document.getElementById('id').classList.remove('class');
DOMTokenList 接口的 toggle() 方法從列表中刪除一個給定的標記 并返回 false 。
如果標記 不存在,則添加并且函數返回 true。
或者使用toggle切換一個類(如果存在則刪除,否則添加它):
document.getElementById('id').classList.toggle('class');
面向對象的編程中,class 是用于創建對象的可擴展的程序代碼模版,它為對象提供了狀態(成員變量)的初始值和行為(成員函數或方法)的實現。
Wikipedia
在日常開發中,我們經常需要創建許多相同類型的對象,例如用戶(users)、商品(goods)或者任何其他東西。
正如我們在 構造器和操作符 "new" 一章中已經學到的,new function 可以幫助我們實現這種需求。
但在現代 JavaScript 中,還有一個更高級的“類(class)”構造方式,它引入許多非常棒的新功能,這些功能對于面向對象編程很有用。
基本語法是:
class MyClass {
// class 方法
constructor() { ... }
method1() { ... }
method2() { ... }
method3() { ... }
...
}
然后使用 new MyClass() 來創建具有上述列出的所有方法的新對象。
new 會自動調用 constructor() 方法,因此我們可以在 constructor() 中初始化對象。
例如:
class User {
constructor(name) {
this.name = name;
}
sayHi() {
alert(this.name);
}
}
// 用法:
let user = new User("John");
user.sayHi();
當 new User("John") 被調用:
……然后我們就可以調用對象方法了,例如 user.sayHi。
類的方法之間沒有逗號
對于新手開發人員來說,常見的陷阱是在類的方法之間放置逗號,這會導致語法錯誤。
不要把這里的符號與對象字面量相混淆。在類中,不需要逗號。
所以,class 到底是什么?正如人們可能認為的那樣,這不是一個全新的語言級實體。
讓我們揭開其神秘面紗,看看類究竟是什么。這將有助于我們理解許多復雜的方面。
在 JavaScript 中,類是一種函數。
看看下面這段代碼:
class User {
constructor(name) { this.name = name; }
sayHi() { alert(this.name); }
}
// 佐證:User 是一個函數
alert(typeof User); // function
class User {...} 構造實際上做了如下的事兒:
當 new User 對象被創建后,當我們調用其方法時,它會從原型中獲取對應的方法,正如我們在 F.prototype 一章中所講的那樣。因此,對象 new User 可以訪問類中的方法。
我們可以將 class User 聲明的結果解釋為:
下面這些代碼很好地解釋了它們:
class User {
constructor(name) { this.name = name; }
sayHi() { alert(this.name); }
}
// class 是一個函數
alert(typeof User); // function
// ...或者,更確切地說,是 constructor 方法
alert(User === User.prototype.constructor); // true
// 方法在 User.prototype 中,例如:
alert(User.prototype.sayHi); // alert(this.name);
// 在原型中實際上有兩個方法
alert(Object.getOwnPropertyNames(User.prototype)); // constructor, sayHi
人們常說 class 是一個語法糖(旨在使內容更易閱讀,但不引入任何新內容的語法),因為我們實際上可以在沒有 class 的情況下聲明相同的內容:
// 用純函數重寫 class User
// 1. 創建構造器函數
function User(name) {
this.name = name;
}
// 函數的原型(prototype)默認具有 "constructor" 屬性,
// 所以,我們不需要創建它
// 2. 將方法添加到原型
User.prototype.sayHi = function() {
alert(this.name);
};
// 用法:
let user = new User("John");
user.sayHi();
這個定義的結果與使用類得到的結果基本相同。因此,這確實是將 class 視為一種定義構造器及其原型方法的語法糖的理由。
盡管,它們之間存在著重大差異:
此外,class 語法還帶來了許多其他功能,我們稍后將會探索它們。
就像函數一樣,類可以在另外一個表達式中被定義,被傳遞,被返回,被賦值等。
這是一個類表達式的例子:
let User = class {
sayHi() {
alert("Hello");
}
};
類似于命名函數表達式(Named Function Expressions),類表達式可能也應該有一個名字。
如果類表達式有名字,那么該名字僅在類內部可見:
// “命名類表達式(Named Class Expression)”
// (規范中沒有這樣的術語,但是它和命名函數表達式類似)
let User = class MyClass {
sayHi() {
alert(MyClass); // MyClass 這個名字僅在類內部可見
}
};
new User().sayHi(); // 正常運行,顯示 MyClass 中定義的內容
alert(MyClass); // error,MyClass 在外部不可見
我們甚至可以動態地“按需”創建類,就像這樣:
function makeClass(phrase) {
// 聲明一個類并返回它
return class {
sayHi() {
alert(phrase);
}
};
}
// 創建一個新的類
let User = makeClass("Hello");
new User().sayHi(); // Hello
就像對象字面量,類可能包括 getters/setters,計算屬性(computed properties)等。
這是一個使用 get/set 實現 user.name 的示例:
class User {
constructor(name) {
// 調用 setter
this.name = name;
}
get name() {
return this._name;
}
set name(value) {
if (value.length < 4) {
alert("Name is too short.");
return;
}
this._name = value;
}
}
let user = new User("John");
alert(user.name); // John
user = new User(""); // Name is too short.
從技術上來講,這樣的類聲明可以通過在 User.prototype 中創建 getters 和 setters 來實現。
這里有一個使用中括號 [...] 的計算方法名稱示例:
class User {
['say' + 'Hi']() {
alert("Hello");
}
}
new User().sayHi();
這種特性很容易記住,因為它們和對象字面量類似。
舊的瀏覽器可能需要 polyfill
類字段(field)是最近才添加到語言中的。
之前,我們的類僅具有方法。
“類字段”是一種允許添加任何屬性的語法。
例如,讓我們在 class User 中添加一個 name 屬性:
class User {
name = "John";
sayHi() {
alert(`Hello, ${this.name}!`);
}
}
new User().sayHi(); // Hello, John!
所以,我們就只需在表達式中寫 " = ",就這樣。
類字段重要的不同之處在于,它們會在每個獨立對象中被設好,而不是設在 User.prototype:
class User {
name = "John";
}
let user = new User();
alert(user.name); // John
alert(User.prototype.name); // undefined
我們也可以在賦值時使用更復雜的表達式和函數調用:
class User {
name = prompt("Name, please?", "John");
}
let user = new User();
alert(user.name); // John
正如 函數綁定 一章中所講的,JavaScript 中的函數具有動態的 this。它取決于調用上下文。
因此,如果一個對象方法被傳遞到某處,或者在另一個上下文中被調用,則 this 將不再是對其對象的引用。
例如,此代碼將顯示 undefined:
class Button {
constructor(value) {
this.value = value;
}
click() {
alert(this.value);
}
}
let button = new Button("hello");
setTimeout(button.click, 1000); // undefined
這個問題被稱為“丟失 this”。
我們在 函數綁定 一章中講過,有兩種可以修復它的方式:
類字段提供了另一種非常優雅的語法:
class Button {
constructor(value) {
this.value = value;
}
click = () => {
alert(this.value);
}
}
let button = new Button("hello");
setTimeout(button.click, 1000); // hello
類字段 click = () => {...} 是基于每一個對象被創建的,在這里對于每一個 Button 對象都有一個獨立的方法,在內部都有一個指向此對象的 this。我們可以把 button.click 傳遞到任何地方,而且 this 的值總是正確的。
在瀏覽器環境中,它對于進行事件監聽尤為有用。
基本的類語法看起來像這樣:
class MyClass {
prop = value; // 屬性
constructor(...) { // 構造器
// ...
}
method(...) {} // method
get something(...) {} // getter 方法
set something(...) {} // setter 方法
[Symbol.iterator]() {} // 有計算名稱(computed name)的方法(此處為 symbol)
// ...
}
技術上來說,MyClass 是一個函數(我們提供作為 constructor 的那個),而 methods、getters 和 settors 都被寫入了 MyClass.prototype。
在下一章,我們將會進一步學習類的相關知識,包括繼承和其他功能。
于class和style我們并不陌生,這個在學習css的時候就是家常便飯了,操作元素的 class 列表和內聯樣式是數據綁定的一個常見需求。因為它們都是屬性,所以我們可以用 v-bind 處理它們,只需要通過表達式計算出字符串結果即可。不過,字符串拼接麻煩且易錯。因此,在將 v-bind 用于 class 和 style 時,Vue.js 做了專門的增強。表達式結果的類型除了字符串之外,還可以是對象或數組,所以本章將帶你了解vue中如何綁定class和style。
在Vue中,我們可以將DOM元素通過Vue的綁定機制,實現我們想要的樣式。接下來看style如何實現綁定。
我們先來看個簡單基礎的動畫案例,大家看案例代碼:
例7-1 Demo0701.html
程序的運行結果如下:
圖 7- 1 直接在元素中加入style原生態樣式
通過例7-1中,我們可以像往常一樣直接在元素上添加行內樣式。
在Vue中有屬性綁定,我們也可以通過屬性綁定直接加行內樣式,如下代碼所示:
<div id="app">
<!-- 直接添加原生態的樣式 -->
<h1 style="color:red">原生態的style樣式</h1>
<!-- 通過vue屬性綁定直接添加 -->
<h1 :style="'color:red;font-size:60px;'">屬性綁定添加的style樣式</h1>
</div>
程序的運行結果如下:
圖 7- 2 通過屬性綁定添加樣式
通過以上示例代碼,我們發現通過屬性綁定和直接添加非常像,但是大家認真觀察,屬性綁定必須加雙重引號(雙中加單,單中加雙),這是因為,如果不對樣式規則加引號,則默認會去Vue實例中尋找對應的數據,但是這些并不是Vue實例中的數據而是我們自己頂的規則,所以必須加引號。
剛才使用屬性綁定的是一個普通的文本,一般在Vue中,屬性綁定的是data中的數據,我們來看如下代碼:
<body>
<div id="app">
<!-- 直接添加原生態的樣式 -->
<h1 style="color:red">原生態的style樣式</h1>
<!-- 通過vue屬性綁定直接添加 -->
<h1 :style="'color:red;font-size:60px;background-color:pink;'">屬性綁定添加的style樣式</h1>
<!-- 通過vue的數據對象添加樣式 -->
<h1 :style="styleObj"> 通過vue的數據對象添加樣式</h1>
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
styleObj: "color:green;font-size:80px;background-color:red;",
}
});
</script>
屬性綁定的是data中一個數據,該數據寫的是樣式規則。
也可以綁定一個對象,在該對象中使用js語法控制樣式規則:
示例如下:
<body>
<div id="app">
<!-- 直接添加原生態的樣式 -->
<h1 style="color:red">原生態的style樣式</h1>
<!-- 通過vue屬性綁定直接添加 -->
<h1 :style="'color:red;font-size:60px;background-color:pink;'">屬性綁定添加的style樣式</h1>
<!-- 通過vue的數據對象添加樣式 -->
<h1 :style="styleObj"> 通過vue的數據對象添加樣式</h1>
<!-- 通過vue的對象添加樣式 -->
<h1 :style="testObj"> 通過vue的數據對象添加樣式</h1>
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
styleObj: "color:green;font-size:80px;background-color:red;",
testObj: {
color: 'blue',//注意是對象,對象的各個屬性之間使用逗號隔開,而不是分號
fontSize: '90px',
backgroundColor: 'pink'
}
}
});
</script>
注意:在該示例代碼中,我們使用的是一個object類型的數據來定義樣式,在這必須使用JavaScript操控style的語法規則來定義對象的各個屬性,而且屬性值必須是字符串,使用引號括起來。
在正常的樣式中,一個DOM元素可以同時應用多個樣式規則,在Vue中,也可以綁定到一個數組對像,同時應用多個樣式規則,示例代碼如下:
<body>
<div id="app">
<!-- 直接添加原生態的樣式 -->
<h1 style="color:red">原生態的style樣式</h1>
<!-- 通過vue屬性綁定直接添加 -->
<h1 :style="'color:red;font-size:60px;background-color:pink;'">屬性綁定添加的style樣式</h1>
<!-- 通過vue的數據對象添加樣式 -->
<h1 :style="styleObj"> 通過vue的數據對象添加樣式</h1>
<!-- 通過vue的對象添加樣式 -->
<h1 :style="testObj"> 通過vue的數據對象添加樣式</h1>
<!-- 綁定數組 -->
<h1 :style="[styleObj,testObj]"> 綁定數組</h1>
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
styleObj: "color:green;font-size:80px;background-color:red;",
testObj: {
color: 'blue',//注意是對象,對象的各個屬性之間使用逗號隔開,而不是分號
fontSize: '90px',
backgroundColor: 'pink'
}
}
});
</script>
在綁定數組的時候,數組中的元素來源于data中的數據,所以不需要加引號。
除了進行style行內樣式的綁定,也可以進行class樣式的綁定。
可以直接在DOM元素上加入class屬性,進行定義樣式,示例如下:
<style>
.red {
color: red;
}
.bk {
background-color: pink;
}
</style>
</head>
<body>
<div id="app">
<!-- 直接添加原生態的樣式 -->
<h1 class="red bk">直接添加class樣式</h1>
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
}
});
</script>
直接在DOM元素上通過class屬性添加多個class樣式規則,注意此時class沒有加冒號。
通過Vue的屬性綁定,示例代碼如下:
<style>
.red {
color: red;
}
.bk {
background-color: pink;
}
</style>
</head>
<body>
<div id="app">
<!-- 直接添加原生態的樣式 -->
<h1 class="red bk">直接添加class樣式</h1>
<!-- 屬性綁定添加 -->
<h1 :class="'red bk'">屬性綁定添加</h1>
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
}
});
</script>
程序運行結果如下:
圖 7- 3 原生態和屬性綁定添加
通過屬性綁定添加,后面的class類名要加引號,否則會去data中尋找red和bk這樣的變量,如果加了,則是直接引用這兩個class樣式。
現在我們讓屬性綁定一個data中的數據對象,示例代碼如下:
<style>
.red {
color: red;
}
.bk {
background-color: pink;
}
.fs {
font-size: larger;
font-style: italic;
}
</style>
</head>
<body>
<div id="app">
<!-- 直接添加原生態的樣式 -->
<h1 class="red bk">直接添加class樣式</h1>
<!-- 屬性綁定添加 -->
<h1 :class="'red bk'">屬性綁定添加</h1>
<!-- 對象綁定 -->
<h1 :class="clsobj">對象綁定</h1>
</div>
</body>
<script>
let vm = new Vue({
el: '#app',
data: {
flag: true,
clsobj: {
'red': true,
'bk': true,
'fs': true
}
}
});
</script>
程序運行結果如下:
圖 7- 4 使用Vue對象綁定
使用對象的時候,對象的屬性就是class的類名,值是Boolean類型,如果是true則是啟用這個類樣式,否則則是不使用。
style樣式代碼:
<style>
.red {
color: red;
}
.thin {
font-weight: 200;
}
.italic {
font-style: italic;
}
.active {
letter-spacing: 0.5em;
}
</style>
示例代碼:
<!-- 第一種使用方式,直接傳遞一個數組,注意: 這里的 class 需要使用 v-bind 做數據綁定 -->
<h2 :class="['red','thin']">這是一個很大很大的H2,大到你無法想象!!!</h2>
數組中的元素必須加引號,否則會去Vue實例中尋找對應的變量數據。
示例代碼:
<!-- 第二種使用方式,在數組中使用三元表達式 -->
<h3 :class="['thin', 'italic', flag?'active':'']">這是一個很大很大的H3,大到你無法想象?。?!</h3>
這上面使用的data中的數據flag,如果flag為true,則使用active這個class樣式,否則是空樣式。
示例代碼:
<!-- 第三種使用方式,在數組中使用 對象來代替三元表達式,提高代碼的可讀性 -->
<h4 :class="['thin', 'italic', {active:flag} ]">這是一個很大很大的H4,大到你無法想象!??!</h4>
上述示例數組中第三個元素是個對象,對象的鍵是style中已知存在的類名,值是boolean類型,如果為true,則采用該類樣式,否則則不采用。
總結:設置class樣式需要使用v-bind綁定;
1、使用[]設置樣式,中括號里的樣式必須加引號,否則被識別為變量;
2、可以使用對象表示class樣式,鍵是類名,值是Boolean類型
3、使用對象類名可以不加引號,但是為了區別變量,建議加上;
當在一個自定義組件上使用 class property 時,這些 class 將被添加到該組件的根元素上面。這個元素上已經存在的 class 不會被覆蓋。
例如,如果你聲明了這個組件:
Vue.component('my-component', {
template: '<p class="foo bar">Hi</p>'
})
然后在使用它的時候添加一些 class:
<my-component class="baz boo"></my-component>
HTML 將被渲染為:
<p class="foo bar baz boo">Hi</p>
對于帶數據綁定 class 也同樣適用:
<my-component v-bind:class="{ active: isActive }"></my-component>
當 isActive 為 true時,HTML 將被渲染成為:
<p class="foo bar active">Hi</p>
給第六章的綜合案例,使用本章的知識添加樣式。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。