Hôm nay mình sẽ chia sẻ một số hàm, thuộc tính hữu ích trong VueJS mà đôi khi chúng ta không để ý tới.
<ul>
,<ol>
, <table>
và <select>
chỉ cho phép một số thẻ nhất định là thẻ con của nó và một số phần tử như <li>
,<tr>
và <option>
chỉ có thể xuất hiện bên trong một số phần tử khác. Điều này sẽ dẫn đến các vấn đề khi sử dụng các thành phần với các phần tử có các hạn chế như vậy. Ví dụ:<table>
<blog-post-row></blog-post-row>
</table>
is
sinh ra để giải quyết vấn đề này. Đoạn code trên sẽ được sửa như sau<table>
<tr is="blog-post-row"></tr>
</table>
is
kết hợp với element <component/>
. Ví dụ ta có component: <my-button/>
: là một button custom component và một số các icon component như:// <download-icon />:
<template>
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect width="24" height="24" fill="#E3F2FD" fill-opacity="0.01" />
<path d="M7 10L12 15L17 10" stroke="#6200EA" stroke-width="2" />
</svg>
</template>
Để hiển thị icon bên trong button, ta làm như sau:
<my-button icon="download-icon"> Button </my-button>
<button >
<template v-if="icon">
<component :is="icon" />
</template>
<slot />
</button>
<button >
<download-icon />
<slot />
</button>
<input v-model="message">
<p>Message is: {{ message }}</p>
message
và khi thay đổi ô input state message
của được thay đổi theo. Nó tương đương với việc thêm vào input 2 phần: 1 là v-bind, 2 là event onchange Dựa vào tính chất này, ta có thể viết lại các component input. Ví dụ:Vue.component('custom-checkbox', {
model: {
prop: 'checked',
event: 'change'
},
props: {
checked: Boolean
},
template: `
<input
type="checkbox"
v-bind:checked="checked"
v-on:change="$emit('change', $event.target.checked)"
>
`
})
<base-checkbox v-model="lovingVue"></base-checkbox>
const example = Vue.component('example', {
template: '<p>{{ message }}</p>',
data: function () {
return {
message: 'not updated'
}
},
mounted () {
this.message = 'updated'
console.log(
'outside nextTick callback:', this.$el.textContent
) // => 'not updated'
this.$nextTick(() => {
console.log(
'inside nextTick callback:', this.$el.textContent
) // => 'updated'
})
}
})
new Vue({
el: '#app',
render: h => h(example)
})
Kết quả là:
"outside nextTick callback:" "not updated"
"inside nextTick callback:" "updated"
Điều này dẫn đến tình trạng ở một số trường hợp, đoạn code của chúng ta sẽ không khoạt động theo ý mình muốn
const example = Vue.component('example', {
template:`
<div>
<input id="demo" v-if="isShow" type="text">
<button @click="onClick">Click Me!</button>
</div>
`,
data: function () {
return {
isShow: false
}
},
methods: {
onClick(event) {
this.isShow = !this.isShow;
if(this.isShow) {
document.getelementbyid("demo').focus() //focus vào ô input
}
}
}
})
new Vue({
el: '#app',
render: h => h(example)
})
Error in v-on handler: 'TypeError: Cannot read properties of null (reading 'focus')'
Để đoạn code trên có thể chạy được ta sửa như sau
Cách 1: dùng setTimeout
onClick(event) {
this.isShow = !this.isShow;
if(this.isShow) {
setTimeout(() => {
document.getElementById('demo').focus();
}, 0);
}
}
Cách 2: dùng nextTick
onClick(event) {
this.isShow = !this.isShow;
if(this.isShow) {
this.$nextTick(() => {
document.getElementById('demo').focus();
})
}
}
Ở cách thứ nhất, khi sử dụng setTimeout, ta có thể gặp nhiều rủi ro nếu không biết quản lý setTimeout một cách hợp lý. Vì vậy mình khuyên mọi người nên dùng cách 2
Mình vừa trình bày 3 tip trong Vue mà mình cảm thấy thú vị. Nếu có đóng góp xin vui lòng để lại dưới comment. Cảm ơn các bạn vì đã đọc. Hẹn gặp các bạn trong các bài viết tiếp theo.