Appearance
Class và Style Bindings
Một nhu cầu phổ biến khi sử dụng data binding là điều khiển danh sách lớp và kiểu trực tiếp (inline) của một phần tử. Vì cả class
và style
đều là thuộc tính, chúng ta có thể sử dụng v-bind
để đặt giá trị của chúng một cách động, tương tự như với các thuộc tính khác. Tuy nhiên, việc tạo giá trị này bằng cách nối chuỗi có thể làm phiền và dễ gây lỗi. Vì lý do này, Vue cung cấp các cải tiến đặc biệt khi v-bind
được sử dụng với class
và style
. Ngoài chuỗi, các biểu thức cũng có thể đánh giá thành các đối tượng hoặc mảng.
Gán Lớp HTML
Gán vào Đối Tượng
Chúng ta có thể truyền một đối tượng vào :class
(viết tắt của v-bind:class
) để chuyển đổi động các lớp:
template
<div :class="{ active: isActive }"></div>
Cú pháp trên có nghĩa là sự tồn tại của lớp active
sẽ phụ thuộc vào truthiness của thuộc tính dữ liệu isActive
.
Bạn có thể có nhiều lớp được chuyển đổi bằng cách thêm nhiều trường trong đối tượng. Ngoài ra, chỉ thị :class
cũng có thể tồn tại cùng với thuộc tính class
thông thường. Cho trạng thái sau:
js
const isActive = ref(true)
const hasError = ref(false)
Và template sau đây:
template
<div
class="static"
:class="{ active: isActive, 'text-danger': hasError }"
></div>
Sẽ hiển thị:
template
<div class="static active"></div>
Khi isActive
hoặc hasError
thay đổi, danh sách lớp sẽ được cập nhật tương ứng. Ví dụ, nếu hasError
trở thành true
, danh sách lớp sẽ trở thành "static active text-danger"
.
Đối tượng được gán không nhất thiết phải là nằm trong dòng:
js
const classObject = reactive({
active: true,
'text-danger': false
})
template
<div :class="classObject"></div>
Điều này sẽ hiển thị:
template
<div class="active"></div>
Chúng ta cũng có thể gán vào một computed property trả về một đối tượng. Điều này là một mẫu thường xuyên và mạnh mẽ:
js
const isActive = ref(true)
const error = ref(null)
const classObject = computed(() => ({
active: isActive.value && !error.value,
'text-danger': error.value && error.value.type === 'fatal'
}))
template
<div :class="classObject"></div>
Gán vào Mảng
Chúng ta có thể gán :class
vào một mảng để áp dụng một danh sách các lớp:
js
const activeClass = ref('active')
const errorClass = ref('text-danger')
template
<div :class="[activeClass, errorClass]"></div>
Điều này sẽ hiển thị:
template
<div class="active text-danger"></div>
Nếu bạn muốn chuyển đổi một lớp trong danh sách theo điều kiện, bạn có thể làm điều này với biểu thức ba ngôi:
template
<div :class="[isActive ? activeClass : '', errorClass]"></div>
Điều này luôn áp dụng errorClass
, nhưng activeClass
chỉ được áp dụng khi isActive
là đúng.
Tuy nhiên, điều này có thể làm phức tạp một chút nếu bạn có nhiều lớp có điều kiện. Đó là lý do tại sao cũng có thể sử dụng cú pháp đối tượng bên trong cú pháp mảng:
template
<div :class="[{ active: isActive }, errorClass]"></div>
Với Components
Phần này giả sử bạn đã biết về Components. Hãy thoải mái bỏ qua và quay lại sau.
Khi bạn sử dụng thuộc tính class
trên một component với một phần tử gốc duy nhất, các lớp này sẽ được thêm vào phần tử gốc của component và kết hợp với bất kỳ lớp nào đang tồn tại trước đó.
Ví dụ, nếu chúng ta có một component có tên MyComponent
với template sau:
template
<!-- Mẫu của component con -->
<p class="foo bar">Hi!</p>
Sau đó thêm một số lớp khi sử dụng nó:
template
<!-- Khi sử dụng component -->
<MyComponent class="baz boo" />
HTML được hiển thị sẽ là:
template
<p class="foo bar baz boo">Hi!</p>
Điều tương tự cũng đúng cho việc gán lớp:
template
<MyComponent :class="{ active: isActive }" />
Khi isActive
là đúng, HTML được hiển thị sẽ là:
template
<p class="foo bar active">Hi!</p>
Nếu component của bạn có nhiều phần tử gốc, bạn cần xác định rõ phần tử nào sẽ nhận lớp này. Bạn có thể làm điều này bằng cách sử dụng thuộc tính $attrs
của component:
template
<!-- Mẫu MyComponent sử dụng $attrs -->
<p :class="$attrs.class">Hi!</p>
<span>This is a child component</span>
template
<MyComponent class="baz" />
Sẽ hiển thị:
html
<p class="baz">Hi!</p>
<span>This is a child component</span>
Bạn có thể tìm hiểu thêm về kế thừa thuộc tính của component trong phần Thuộc Tính Kế Thừa.
Gán Kiểu Trực Tiếp (Inline Styles)
Gán vào Đối Tượng
:style
hỗ trợ gán vào các giá trị đối tượng JavaScript - nó tương ứng với thuộc tính style của phần tử HTML:
js
const activeColor = ref('red')
const fontSize = ref(30)
template
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
Mặc dù khuyến khích sử dụng chìa khóa camelCase, :style
cũng hỗ trợ chìa khóa kiểu kebab-case của thuộc tính CSS (tương ứng với cách chúng được sử dụng trong CSS thực tế) - ví dụ:
template
<div :style="{ 'font-size': fontSize + 'px' }"></div>
Thường thì việc gán trực tiếp vào một đối tượng style là một ý tưởng tốt để template trở nên sạch sẽ:
js
const styleObject = reactive({
color: 'red',
fontSize: '13px'
})
template
<div :style="styleObject"></div>
Một lần nữa, việc gán đối tượng style thường được sử dụng kết hợp với computed properties trả về đối tượng.
Gán vào Mảng
Chúng ta có thể gán :style
vào một mảng chứa nhiều đối tượng style. Các đối tượng này sẽ được hợp nhất và áp dụng vào cùng một phần tử:
template
<div :style="[baseStyles, overridingStyles]"></div>
Tự động thêm Tiền Tố
Khi bạn sử dụng một thuộc tính CSS yêu cầu một tiền tố của nhà sản xuất trong :style
, Vue sẽ tự động thêm tiền tố phù hợp. Vue thực hiện điều này bằng cách kiểm tra tại thời điểm chạy để xem các thuộc tính style nào được hỗ trợ trong trình duyệt hiện tại. Nếu trình duyệt không hỗ trợ một thuộc tính cụ thể, các biến thể có tiền tố sẽ được thử nghiệm để tìm một biến thể nào được hỗ trợ.
Nhiều Giá Trị
Bạn có thể cung cấp một mảng chứa nhiều giá trị (đã có tiền tố) cho một thuộc tính style, ví dụ:
template
<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>
Điều này chỉ hiển thị giá trị cuối cùng trong mảng mà trình duyệt hỗ trợ. Trong ví dụ này, nó sẽ hiển thị display: flex
dành cho các trình duyệt hỗ trợ phiên bản chưa được sửa lỗi của flexbox.