VueJS – document
Contents
1. Template syntax
1.1 Global access
Có một số biến toàn cục mà bạn không thể truy cập trực tiếp trong các biểu thức của template, nhưng bạn có thể định nghĩa chúng một cách rõ ràng bằng cách thêm chúng vào app.config.globalProperties
. Điều này đảm bảo rằng template của bạn chỉ truy cập vào các biến toàn cục mà bạn kiểm soát và đảm bảo an toàn.
app.config.globalProperties.user = window.user; // in template <p>Welcome, {{ user.name }}!</p>
1.2 Syntax
2. Reactivity Fundamentals
2.1 ref
Là deep tracking, nghĩa là tracking thay đổi của những thằng con lòng trong nó luôn.
import { ref } from 'vue' const count = ref(0) // hoặc trong setup function import { ref } from 'vue' export default { // `setup` is a special hook dedicated for the Composition API. setup() { const count = ref(0) // expose the ref to the template return { count } } }
Sử dụng trong script thì .value
import { ref } from 'vue'; const count = ref(0); console.log(count.value)
Khi sử dụng refs thì component cha có thể truy xuất đến các thuộc tính của component mà component con cho phép. Mặc định các hàm và thuộc tính là private ở component con nhưng ta có thể public cho component cha bằng macro: defineExpose
<script setup> import { ref } from 'vue' const a = 1 const b = ref(2) // Compiler macros, such as defineExpose, don't need to be imported defineExpose({ a, b }) </script>
2.2 shallowRef
ShallowRef thì không tracking thay đổi của những thằng con.
const state = shallowRef({ count: 1 })
2.3 nextTick
Chờ cho đến khi DOM được cập nhật xong.
<script setup> import { ref, nextTick } from 'vue' const count = ref(0) async function increment() { count.value++ // DOM not yet updated console.log(document.getElementById('counter').textContent) // 0 await nextTick() // DOM is now updated console.log(document.getElementById('counter').textContent) // 1 } </script> <template> <button id="counter" @click="increment">{{ count }}</button> </template>
2.4 reactive
=> Trả về object proxy
Giới hạn / nhược điểm:
– Chỉ làm việc với object type (object, array, collection, type (Map, Set)), không làm việc với kiểu dữ liệu nguyên thủy string, number,…
– Không thể thay thế object mới.
let state = reactive({ count: 0 }); state = reactive({ count: 1 })
Do sử dụng theo tham chiếu nên khi thay đổi thì làm mất liên kết và sẽ không tự động cập nhật giao diện người dùng được nữa.
– Không thể destructure
let state = reactive({ count: 0 }); let { count } = state;
3. Computed
=> Sử dụng computed cho đến khi cần method
Computed:
– Giống như ref:
+ .value
+ unwrapped in template
– Caching: nó sẽ lưu cache render lần đầu, khi nào thay đổi nữa mới render lại.
– Can use getter and setter, default only getter. Tuy nhiên không nên sử dụng setter.
4. Class and style binding
Can use:
// {} <div :class="{ active: isActive }"></div> // [] const activeClass = ref(true); const errorClass = ref(false); <div :class="[activeClass, errorClass]"></div> // kết hợp 1 và 2 [ {}, ...] <div :class="[{ active: isActive }, errorClass]"></div>
5. Render condition
v-if
v-else-if
v-else
v-show
Support trong template tag: v-if, v-else-if, v-else
Không support trong template tag: v-show
<template v-if="active"></template
v-show cũng như v-if nhưng khác là có render nhưng bị ẩn đi thôi.
Lưu ý:
– v-show chỉ render lần đầu còn v-if sẽ render mỗi lần data thay đổi nên v-if tốn chi phí chuyển đổi hơn (toggle costs)
– Không sử dụng v-if và v-for cùng nhau, vì v-if có độ ưu tiên cao hơn. Do đó, v-for không truy cập được các biến trong phạm vi của nó.
=> có 2 giải pháp là sử dụng computed hoặc v-if xuống thẻ tiếp theo.
– Có thể sử dụng destructering trên v-for luôn.
– v-for sử dụng in hay of gì cũng được, cũng tương tự như nhau
v-for="item in items" // hoặc v-for="item of items"
– v-for object:
+ Tự động sử dụng object.keys để ép sang
+ Có thể sử dụng cả 3 tham số với object (values, key, index) trong bất kỳ object nào.
<div v-for="(item, index) in items"></div> <div v-for="(value, key) in object"></div> <div v-for="(value, name, index) in object"></div>
– v-for cũng sử dụng được trên template tag:
<tempate v-for="(item, index) in items"></template>
– v-for đi với key attribute:
<tempate v-for="(item, index) in items" :key="index"></template>
– Khi cần truyền biến và lấy cả event thì có thể sử dụng 2 cách:
// sử dụng $event warn("abc", $event) // sử dụng arrow function (event) => warn("abc", event)
– Nó có event modifier, tuy nhiên thứ tự khác nhau sẽ tác dụng khác nhau.
+ .stop
+ .prevent
+ .self
+ .capture
+ .once
+ .passive
@click.self.prevent /* khác với */ @click.prevent.self
– Key modifiers:
+ .enter
+ .tab
+ .delete (gồm cả phím delete và backspace)
+ .esc
+ .space
+ .up
+ .left
+ .down
+ .right
@keyup.enter @keyup.page-down
– System modifiers:
+ .ctrl
+ .alt
+ .shift
+ .meta
+ .exact (only press key đó không nhấn phím khác)
– Mouse button modifiers:
+ .left
+ .right
+ .middle
– Model modifiers:
+ v-model.lazy: không thực hiện thay đổi liền mà khi change hoặc enter mới thay đổi giá trị. (onChange thay vì onInput)
+ .number: input tự động convert sang số
+ .trim: input tự động xóa kí tự trắng ở đầu và cuối.
6. Watcher
watch( () => state.someObject, (newValue, oldValue) => { // Note: `newValue` will be equal to `oldValue` here // *unless* state.someObject has been replaced }, { deep: true }, { immediate: true } )
– deep: watch sâu.
– Eager watcher: thực hiện liền mà không đợi data thay đổi thì sử dụng immediate: true
– watchEffect: sử dụng watch không cần khai báo sự phụ thuộc, mặc định enable Eager watcher.
watchEffect(async () => { const response = await fetch( `https://jsonplaceholder.typicode.com/todos/${todoId.value}` ) data.value = await response.json() })
– Mặc định watch sẽ chạy trước component Vue update. Muốn chạy sau thì sử dụng tham số thứ ba { flush: post } hoặc watchPostEffect
watch(source, callback, { flush: 'post' }) watchEffect(callback, { flush: 'post' }) watchPostEffect(() => { /* executed after Vue updates */ })
– Khi muốn dừng watch cho đến khi nào đó thì trả nó về 1 biến và gọi nó khi cần, muốn bật lại thì gán watch lại cho biến đó là được.
<script setup> import {ref, watch} from 'vue' const count = ref(0) let countWatch = watch(count, () => { console.log(count.value); }); const countWatchStart = () => { countWatch = watch(count, () => { console.log(count.value); }); }; </script> <template> <h1>Hello Vue 3</h1> <button @click="count++">Count is: {{ count }}</button> <button @click="countWatch()">Stop</button> <button @click="countWatchStart()">countWatchStart</button> </template> <style scoped> button { font-weight: bold; } </style>
7. Component
7.1 defineProps
Định nghĩa các props (tham số) của component con
<script setup> const props = defineProps(['title']) console.log(props.title) </script> <template> <h4>{{ title }}</h4> </template> // hoặc nếu sử dụng setup function export default { props: ['title'], setup(props) { console.log(props.title) } }
7.2 emit
Truyền event tới component cha.
// child component <template> <div class="blog-post"> <h4>{{ title }}</h4> <button @click="$emit('enlarge-text')">Enlarge text</button> </div> </template> // parent component <BlogPost ... @enlarge-text="postFontSize += 0.1" /> // hoặc sử dụng macro // script setup use macro export default { emits: ['enlarge-text'], setup(props, ctx) { ctx.emit('enlarge-text') } } // script setup use macro <script setup> const emit = defineEmits(['enlarge-text']) emit('enlarge-text') </script>
defineProps, defineEmits is only usable in <script setup> and doesn’t need to be imported.
7.3 slot
Nội dung giữa thẻ vào trong component con
<AlertBox> Something bad happened. </AlertBox> // AlertBox component <template> <div class="alert-box"> <strong>This is an Error for Demo Purposes</strong> <slot /> </div> </template> <style scoped> .alert-box { /* ... */ } </style>
Có thể truyền data từ child component vào slot của component cha, để component cha sử dụng như sau:
// <MyComponent> template <div> <slot :text="greetingMessage" :count="1"></slot> </div> // parent component <MyComponent v-slot="slotProps"> {{ slotProps.text }} {{ slotProps.count }} </MyComponent> // can use destructering <MyComponent v-slot="{ text, count }"> {{ text }} {{ count }} </MyComponent>
Nếu nhiều slot có thể sử dụng slot name
<slot name="header" message="hello"></slot> <MyComponent> <template #header="headerProps"> {{ headerProps }} </template> <template #default="defaultProps"> {{ defaultProps }} </template> <template #footer="footerProps"> {{ footerProps }} </template> </MyComponent>
7.4 Dynamic component
Sử dụng thẻ component, và sử dụng attribute is
<component :is="tabs[currentTab]"></component>
7.5 Fallthrough attributes
fallthrough attributes: những prop không được khai báo nhưng mặc nhiên có khi truyền vào component con (id, class, style,…) và được gán vào root element
using the useAttrs()
API: để lấy các giá trị fallthrough attributes
<script setup> import { useAttrs } from 'vue' const attrs = useAttrs() </script> // hoặc nếu sử dụng setup function export default { setup(props, ctx) { // fallthrough attributes are exposed as ctx.attrs console.log(ctx.attrs) } }
7.6 Renderless component
Renderless Component: Component chỉ chứa logic, còn giao diện do component cha quyết định.
// RenderlessPagination.vue <template> <div> <!-- Render the slot with the required data and methods --> <slot :currentPage="currentPage" :totalPages="totalPages" :nextPage="nextPage" :prevPage="prevPage" ></slot> </div> </template> <script> export default { data() { return { currentPage: 1, totalPages: 0, }; }, methods: { nextPage() { if (this.currentPage < this.totalPages) { this.currentPage++; } }, prevPage() { if (this.currentPage > 1) { this.currentPage--; } }, }, watch: { // Assume the total number of items and itemsPerPage are passed as props totalItems: function (newVal, oldVal) { this.totalPages = Math.ceil(newVal / this.itemsPerPage); }, }, }; </script> // parent component <template> <div> <!-- Use the RenderlessPagination component --> <RenderlessPagination :totalItems="totalItems" :itemsPerPage="itemsPerPage"> <!-- Scoped slot to render the pagination UI --> <template v-slot="{ currentPage, totalPages, nextPage, prevPage }"> <div class="pagination"> <button @click="prevPage" :disabled="currentPage === 1">Previous</button> <span>{{ currentPage }} / {{ totalPages }}</span> <button @click="nextPage" :disabled="currentPage === totalPages">Next</button> </div> </template> </RenderlessPagination> </div> </template> <script> import RenderlessPagination from './RenderlessPagination.vue'; export default { components: { RenderlessPagination, }, data() { return { totalItems: 100, // Total number of items itemsPerPage: 10, // Items per page }; }, }; </script>
7.7 Provide/Inject
Props drilling: component cha truyền đến các component cháu, chắc, … truyền props sẽ khó xử lý.
Provide/Inject: chia sẻ data từ component cha, còn componet cháu, chắc muốn sử dụng chỉ cần inject vào. Không phải xử lý phức tạp như props
<script setup> import { provide } from 'vue' provide(/* key */ 'message', /* value */ 'hello!') </script> // Sử dụng setup function import { provide } from 'vue' export default { setup() { provide(/* key */ 'message', /* value */ 'hello!') } }
Tham số thứ hai của provide là value, có thể truyền bất cứ kiểu dữ liệu gì ngay cả ref.
Có thể sử dụng ở app global khi đăng ký ứng dụng.
import { createApp } from 'vue' const app = createApp({}) app.provide(/* key */ 'message', /* value */ 'hello!')
Inject ở component con:
<script setup> import { inject } from 'vue' const message = inject('message') </script> // Sử dụng setup function import { inject } from 'vue' export default { setup() { const message = inject('message') return { message } } }
Default value khi inject
const value = inject('message', 'default value')
Inject change data component cha
// inside provider component <script setup> import { provide, ref } from 'vue' const location = ref('North Pole') function updateLocation() { location.value = 'South Pole' } provide('location', { location, updateLocation }) </script> // in injector component <script setup> import { inject } from 'vue' const { location, updateLocation } = inject('location') </script> <template> <button @click="updateLocation">{{ location }}</button> </template>
Và tác giả khuyên nên đưa các key ra thành 1 file để dễ quản lý và bảo trì sau này.
// keys.js export const myInjectionKey = Symbol() // in provider component import { provide } from 'vue' import { myInjectionKey } from './keys.js' provide(myInjectionKey, { /* data to provide */ }) // in injector component import { inject } from 'vue' import { myInjectionKey } from './keys.js' const injected = inject(myInjectionKey)
7.8 DefineAsyncComponent
defineAsyncComponent
Sử dụng để khi nào cần mới import không import liền khi component cha khởi tạo, điều này làm cho hiệu suất ứng dụng tốt hơn (ở tab network của chrome devtool sẽ thấy load và không load component). Và cũng không nên lạm dụng quá, tôi nghĩ cái này có thể áp dụng cho popup được. Vì sẽ load khi người dùng cần không load trước.
<script setup> import { defineAsyncComponent } from 'vue' const AdminPage = defineAsyncComponent(() => import('./components/AdminPageComponent.vue') ) </script> <template> <AdminPage /> </template>
Nó có một số tùy chọn khác:
const AsyncComp = defineAsyncComponent({ // the loader function loader: () => import('./Foo.vue'), // A component to use while the async component is loading loadingComponent: LoadingComponent, // Delay before showing the loading component. Default: 200ms. delay: 200, // A component to use if the load fails errorComponent: ErrorComponent, // The error component will be displayed if a timeout is // provided and exceeded. Default: Infinity. timeout: 3000 })
Có thể sử dụng với <Suspense> tag: Suspense cho các component không đồng bộ con bên trong chạy theo 1 Suspense này. Thay vì loading, error mỗi component không đồng bộ có 1 cái thì nó bị hiện lên 3 cái luôn, thì lúc này cần Suspense giải quyết vấn đề này.
<!-- App.vue --> <template> <div> <Suspense> // ComponentA sẽ được xử lý bởi <Suspense>, hiển thị trạng thái loading khi tải <ComponentA /> // ComponentB sẽ không được xử lý bởi <Suspense>, và sẽ kiểm soát trạng thái loading của chính nó <ComponentB :suspensible="false" /> // ComponentC sẽ được xử lý bởi <Suspense> <ComponentC /> </Suspense> </div> </template> <script> import { Suspense } from 'vue'; import ComponentA from './ComponentA.vue'; import ComponentB from './ComponentB.vue'; import ComponentC from './ComponentC.vue'; export default { components: { Suspense, ComponentA, ComponentB, ComponentC } }; </script>
7.9 Composable
Toàn bộ logic đưa ra file js riêng. Với export name have prefix use được gọi là Composables
// mouse.js import { ref, onMounted, onUnmounted } from 'vue' // by convention, composable function names start with "use" export function useMouse() { // state encapsulated and managed by the composable const x = ref(0) const y = ref(0) // a composable can update its managed state over time. function update(event) { x.value = event.pageX y.value = event.pageY } // a composable can also hook into its owner component's // lifecycle to setup and teardown side effects. onMounted(() => window.addEventListener('mousemove', update)) onUnmounted(() => window.removeEventListener('mousemove', update)) // expose managed state as return value return { x, y } }
So sánh Composables với mixins
Mixins có 3 hạn chế hơn so với Composables:
- Khi import nhiều mixins nó sẽ không rõ ràng và khó bảo trì sau này. Còn composable thì import những gì và của cái nào thì nó sẽ rõ ràng hơn.
- Khi import nhiều mixins nó sẽ bị trùng tên nên khó sử dụng nhiều cái cùng lúc, còn composable sử dụng destructering thì khi import có thể đổi tên.
- Mixins các biến data sử dụng được dùng chung key, nên nó liên kết chặt chẽ và làm cho mã trở nên khó hiểu và khó bảo trì. Còn composable các giá trị được trả về từ một composable có thể được truyền vào một composable khác dưới dạng tham số, tương tự như các hàm thông thường, làm cho chúng độc lập, dễ bảo trì.
Tác giả khuyến khích sử dụng composable cho trường hợp chỉ có logic code, còn Renderless Component (slot) cho trường hợp có logic code và giao diện hiển thị.
8. Directive
Trong <script setup> bất kì biến nào viết dạng camelCase có tiền tố là v thì là directive, còn trong setup function thì đăng ký trong directive.
<script setup> // enables v-focus in templates const vFocus = { mounted: (el) => el.focus() } </script> <template> <input v-focus /> </template> // setup function export default { setup() { /*...*/ }, directives: { // enables v-focus in template focus: { /* ... */ } } }
register global
const app = createApp({}) // make v-focus usable in all components app.directive('focus', { /* ... */ })
Directive hook:
const myDirective = { // called before bound element's attributes // or event listeners are applied created(el, binding, vnode, prevVnode) { // see below for details on arguments }, // called right before the element is inserted into the DOM. beforeMount(el, binding, vnode, prevVnode) {}, // called when the bound element's parent component // and all its children are mounted. mounted(el, binding, vnode, prevVnode) {}, // called before the parent component is updated beforeUpdate(el, binding, vnode, prevVnode) {}, // called after the parent component and // all of its children have updated updated(el, binding, vnode, prevVnode) {}, // called before the parent component is unmounted beforeUnmount(el, binding, vnode, prevVnode) {}, // called when the parent component is unmounted unmounted(el, binding, vnode, prevVnode) {} }
el
: the element the directive is bound to. This can be used to directly manipulate the DOM.binding
: an object containing the following properties.value
: The value passed to the directive. For example inv-my-directive="1 + 1"
, the value would be2
.oldValue
: The previous value, only available inbeforeUpdate
andupdated
. It is available whether or not the value has changed.arg
: The argument passed to the directive, if any. For example inv-my-directive:foo
, the arg would be"foo"
.modifiers
: An object containing modifiers, if any. For example inv-my-directive.foo.bar
, the modifiers object would be{ foo: true, bar: true }
.instance
: The instance of the component where the directive is used.dir
: the directive definition object.
vnode
: the underlying VNode representing the bound element.prevNode
: the VNode representing the bound element from the previous render. Only available in thebeforeUpdate
andupdated
hooks.
Example
<div v-example:foo.bar="baz"> // binding: { arg: 'foo', modifiers: { bar: true }, value: /* value of `baz` */, oldValue: /* value of `baz` from previous update */ }
Có thể định nghĩa hàm:
app.directive('color', (el, binding) => { // this will be called for both `mounted` and `updated` el.style.color = binding.value })
9. Plugin
Plugin là mã độc lập thường thêm chức năng cấp ứng dụng vào Vue.
Được định nghĩa bằng hàm install. Có thể sử dụng Provide và Inject.
// plugins/i18n.js export default { install: (app, options) => { app.config.globalProperties.$translate = (key) => { return key.split('.').reduce((o, i) => { if (o) return o[i] }, options) } app.provide('i18n', options) } } <script setup> import { inject } from 'vue' const i18n = inject('i18n') console.log(i18n.greetings.hello) </script>
10. Build-in
10.1 Transition
Transition và TransitionGroup (for list)
<!-- assuming Animate.css is included on the page --> <Transition name="custom-classes" enter-active-class="animate__animated animate__tada" leave-active-class="animate__animated animate__bounceOutRight" > <p v-if="show">hello</p> </Transition>
10.2 KeepAlive
<KeepAlive> cho phép giữ lại data khi chuyển đổi giữa các component.
<KeepAlive> <component :is="activeComponent" /> </KeepAlive>
10.3 Teleport
Teleport dùng để di chuyển 1 dom nào đó đến 1 vị trí cha nào đó, thường sử dụng cho model (popup)
<button @click="open = true">Open Modal</button> <Teleport to="body"> <div v-if="open" class="modal"> <p>Hello from the modal!</p> <button @click="open = false">Close</button> </div> </Teleport>
Code trên sẽ di chuyển nội dung trong Teleport thành con của thẻ body. The to target of <Teleport> expects a CSS selector string
Disable Teleport
<Teleport :disabled="isMobile"> ... </Teleport>
11. Performance and maintain
11.1 Maintain and SEO
Mọi người quan ngại rằng, HTML, CSS, Javascript đang viết cùng file cần phải tách nó ra?
⇒ Câu trả lời là: Việc tách ra hay viết chung không quan trọng, quan trọng là mối quan tâm khả năng bảo trì của ứng dụng. Khi viết cùng nhau nó sẽ dễ hiểu, dễ bảo trì sau này, có cái nhìn tổng quan component có gì, xài gì, giao diện thế nào,…
SSR(Server-Side Rendering): là kỹ thuật giúp hiển thị nội dung trong trang web trên máy chủ trước khi gửi đến trình duyệt của người dùng. Điều này giúp cải thiện thời gian hiển thị nội dung ban đầu và cũng tốt cho SEO.
SSG(Static Site Generation): tạo trước các trang tĩnh trong quá trình xây dựng. Các trang tĩnh được lưu trữ dưới dạng tệp HTML và không thay đổi giữa các triển khai. SSG cung cấp hiệu suất tốt và dễ triển khai hơn SSR
Nếu bạn chỉ cần cải thiện SEO cho một số trang tiếp thị hoặc trang nội dung cụ thể, SSG là lựa chọn tốt hơn SSR.
11.2 Performance
11.2.1 v-once
“v-once” chỉ render 1 lần và đảm bảo rằng nội dung này không bao giờ được cập nhật trong tương lai
<span v-once>{{ user.name }}</span>
11.2.2 v-memo
v-memo làm tối ưu hiệu suất, chỉ re-render trong v-memo khi giá trị trong v-memo được thay đổi (mặc định không sử dụng v-memo thì các thuộc tính khác nó thay đổi thì cũng bị re-render luôn, ví dụ cập nhật name thôi mà age cũng bị re-render). Hãy luôn sử dụng v-memo cho đến khi không cần thiết. Lưu ý: v-memo sử dụng value dạng array.
<script setup> import { ref, reactive } from 'vue' const msg = ref('Hello World!') const state = reactive({ person: { name: "HaoDT", age: 11, } }); </script> <template> <h1>{{ msg }}</h1> <input v-model="msg"> <button @click="state.person.age = 13">abc</button> <div v-memo="[state.person.age]">{{ state.person.age }}</div> </template>
11.3 Security
URL Injection: Thẻ a có thể sử dụng javascript trong đó nên cần validate data người dùng nhập vào url.
<a href="javascript:alert('hello world')"></a
12. API
• createApp(): Tạo instance
• createSSRApp(): Tạo instance dạng server side rendering
• app.mount(): Nạp instance vào DOM HTML
• app.unmount(): Gỡ instance khỏi DOM HTML
• app.component(): Đăng ký component global
• app.directive(): Đăng ký directive global
• app.use(): Cài đặt một plugin nào đó vào Vue instance
• app.mixin(): Đăng ký mixin global
• app.provide(): Đăng ký những biến common cho các thành phần con cháu sử dụng
• app.runWithContext(): Không hiểu
• app.version: lấy thông tin về phiên bản Vue mà ứng dụng đã được tạo ra
• app.config: lấy thông tin về cấu hình của ứng dụng
• app.config.errorHandler: gán một hàm xử lý lỗi (error handler) toàn cục để xử lý các lỗi không xử lý được xuất phát từ bên trong ứng dụng
• app.config.warnHandler: gán một hàm xử lý cảnh báo tùy chỉnh (custom warn handler) để xử lý các cảnh báo runtime từ Vue.
• app.config.performance: theo dõi hiệu suất của các giai đoạn quan trọng trong quá trình tạo, biên dịch, render và patch của các component trong ứng dụng (Thể hiện ở tab performance của F12)
• app.config.compilerOptions: Thay đổi các tùy chọn biên dịch, như thay đổi dấu {{ }} thành gì gì đó, có để comment trong file buid production không, …
• app.config.globalProperties: Đăng ký một biến global
• app.config.optionMergeStrategies: Ghép nối các thành phần gì gì đó. Không hiểu
General:
version : Hiển thị phiên bản hiện tại của Vue.
nextTick(): chờ cho đến khi DOM được cập nhật rồi mới làm tiếp.
defineComponent(): hàm dùng để định nghĩa một component Vue defineAsyncComponent(): hàm dùng để định nghĩa một component Vue bất đồng bộ (async), chỉ được tải lười biếng (lazy load) khi nó được render.
defineCustomElement(): Đăng ký một custom element: <my-custom-element />
setup(): api chính để viết logic cho component
expose(): cung cấp những thứ component cha có thể lấy xài từ component con.
• ref(): tạo các biến reactive và mutable trong Composition API, giúp quản lý trạng thái và sử dụng reactivity trong ứng dụng Vue một cách dễ dàng và hiệu quả. Để truy cập hoặc thay đổi giá trị bên trong, chúng ta sử dụng .value
.
• computed(): tạo các biến computed trong Composition API, giúp tính toán giá trị dựa trên các giá trị reactive khác, đồng thời tự động cập nhật kết quả tính toán khi các giá trị phụ thuộc thay đổi. Có thể được sử dụng để thay đổi giá trị thông qua việc gán giá trị mới cho thuộc tính .value
.
• reactive(): giúp chúng ta tạo ra các đối tượng có tính chất reactive một cách dễ dàng, cho phép quản lý trạng thái ứng dụng một cách hiệu quả. Khi các giá trị bên trong đối tượng reactive thay đổi, Vue sẽ tự động cập nhật các thành phần UI liên quan, giúp duy trì trạng thái ứng dụng và giao diện người dùng đồng bộ.
• readonly(): cho phép chúng ta tạo ra các proxy chỉ đọc cho đối tượng hoặc ref, bảo vệ dữ liệu khỏi việc thay đổi không mong muốn
• watchEffect(): theo dõi các biến mà trong watchEffect sử dụng, nếu có thay đổi thì nó sẽ chạy lại watchEffect. Nó có 2 option flush: ‘post’ và flush: ‘sync’. Giá trị post là default. Với post nó sẽ được chạy sau khi component được render, còn sync thì nó được chạy ngay sau khi một trong biến trong hàm đó thay đổi.
• watchPostEffect(): alias của flush:post
• watchSyncEffect(): alias của flush:sync
• watch(): theo dõi một hoặc nhiều nguồn dữ liệu có tính reactivity, để call function xử lý gì đó.
• isRef(): check là ref object.
• unref(): xài biến ref mà không cần .value
• toRef(): chuyển đổi giá trị, refs, hoặc getters thành các refs.
• toValue(): tương tự như unref(), tuy nhiên nó có một điểm khác biệt quan trọng: nếu đối số là một getter (hàm lấy giá trị), nó sẽ được gọi và giá trị trả về sẽ được trả về.
• toRefs(): parse từng con của reactive thành những cái ref con
• isProxy(): check có phải là proxy được tạo bởi reactive(), readonly(), shallowReactive() or shallowReadonly() không?
• isReactive(): check có phải là reactive không?
• isReadonly(): kiểm tra xem một đối tượng có phải là một đối tượng “readonly” hay không
• shallowRef(): như ref nhưng không reactive sâu mà chỉ ở 1 lớp đầu tiên.
• triggerRef(): Do shalowRef không check sâu, nên muốn force Update thì sử dụng thằng này
• customRef(): custom lại 1 cái ref
• shallowReactive(): như reactive nhưng không reactive sâu mà chỉ ở 1 lớp đầu tiên.
• shallowReadonly(): như readonly nhưng không reactive sâu mà chỉ ở 1 lớp đầu tiên.
• toRaw(): trả về data của biến reactive mà không phải là proxy
• markRaw(): sử dụng để đánh dấu một đối tượng để nó không bao giờ được chuyển đổi thành proxy. Hàm này đảm bảo rằng đối tượng sẽ không tham gia vào hệ thống Reactivity của Vue.
• effectScope(): Không hiểu
• getCurrentScope(): Không hiểu
• onScopeDispose(): Không hiểu
Life cycle hook
• onMounted()
• onUpdated()
• onUnmounted()
• onBeforeMount()
• onBeforeUpdate()
• onBeforeUnmount()
• onErrorCaptured(): sẽ được gọi khi một lỗi từ một component con bắt lấy ở component cha.
• onRenderTracked(): Tracking reative to debug. Không hiểu
• onRenderTriggered(): Tracking render to debug. Không hiểu
• onActivated(): Insert in DOM HTML
• onDeactivated(): Remove in DOME HTML
• onServerPrefetch(): Đăng ký một chức năng không đồng bộ sẽ được giải quyết trước khi phiên bản thành phần được hiển thị trên máy chủ
Option API:
• data
• props
• computed
• methods
• watch
• emits
• expose: Khai báo các thuộc tính mà component cha được truy cập.
• template
• render
• compilerOptions
• slots
• beforeCreate
• created
• beforeMount
• mounted
• beforeUpdate
• updated
• beforeUnmount
• unmounted
• errorCaptured
• renderTracked
• renderTriggered
• activated
• deactivated
• serverPrefetch
Component
• name: Khai báo rõ ràng tên cho component
• inheritAttrs: Kiểm soát việc truyền prop từ component cha xuống con. Không hiểu
• components
• directives
• $data
• $props
• $el: lấy DOM gốc của component
• $options
• $parent: lấy component cha
• $root: get component root
• $slots
• $refs
• $attrs
• $watch()
• $emit()
• $forceUpdate()
• $nextTick()
end option API
Build-in
• v-text
• v-html
• v-show
• v-if
• v-else
• v-else-if
• v-for
• v-on
• v-bind
• v-model
• v-slot
• v-pre
• v-once
• v-memo
• v-cloak: dùng để hiển thị phần tử trong một thời gian cố định, tức là vào trang web sẽ không hiển thị phần tử này ngay mà sau khoảng 1 khoảng time sẽ hiện thị.
• <Transition>
• <TransitionGroup>
• <KeepAlive>
• <Teleport>
• <Suspense>
• <component>
• <slot>
• <template>
• key
• ref
• is: Sử dụng cho dynamic component
• Scoped CSS
• CSS Modules
• v-bind() in CSS: Sử dụng biến javascript của mục script trong mục style
• h(): Tạo các DOM ảo
• mergeProps(): được sử dụng để kết hợp các đối tượng props lại
• cloneVNode(): Clones một virtual node.
• isVNode(): check is virtual node
• resolveComponent(): giải quyết một thành phần đã đăng ký trước đó thông qua việc xác định và trả về thành phần dựa trên tên của nó. Không hiểu
• resolveDirective(): giải quyết một directive đã đăng ký trước đó thông qua việc xác định và trả về directive dựa trên tên của nó. Không hiểu
• withDirectives(): sử dụng để thêm các directive tùy chỉnh vào các vnodes.
• withModifiers(): sử dụng để thêm các built-in v-on modifiers vào một hàm xử lý sự kiện.
Server Side rendering:
• renderToString(): convert template to string
• renderToNodeStream(): Không hiểu
• pipeToNodeWritable(): Không hiểu
• renderToWebStream(): Không hiểu
• pipeToWebWritable(): Không hiểu
• renderToSimpleStream(): Không hiểu
• useSSRContext(): được sử dụng để lấy thông tin context (bối cảnh) được truyền vào cho hàm renderToString() hoặc các API render trên máy chủ (server render APIs) khác.
• createRenderer(): sử dụng để tạo ra một bộ trình điều khiển tùy chỉnh (renderer) cho Vue.js. Renderer là một thành phần trong Vue.js Core Runtime, có trách nhiệm biến đổi cây DOM ảo (virtual DOM tree) thành cây DOM thực tế, dựa trên sự thay đổi trong trạng thái của ứng dụng.