Skip to content
On this page

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ả classstyle đề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 classstyle. 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)
js
data() {
  return {
    isActive: true,
    hasError: 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
})
js
data() {
  return {
    classObject: {
      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'
}))
js
data() {
  return {
    isActive: true,
    error: null
  }
},
computed: {
  classObject() {
    return {
      active: this.isActive && !this.error,
      'text-danger': this.error && this.error.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')
js
data() {
  return {
    activeClass: 'active',
    errorClass: '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)
js
data() {
  return {
    activeColor: 'red',
    fontSize: 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'
})
js
data() {
  return {
    styleObject: {
      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.

Class và Style Bindings has loaded