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