VueJS: Đăng ký component


Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên

Bài viết này giả định bạn đã đọc Component. Hãy đọc trước nếu bạn chưa quen với component.

Tên cho Component

Khi đăng ký một component thì ta luôn luôn cần có một tên. Ví dụ như trong đăng ký global thì có sẽ có dạng như thế này:

Vue.component('my-component-name', { /* ... */ })

Tên của component là đối số đầu tiên của Vue.component.

Tên của component có thể phụ thuộc vào nơi bạn sử dụng nó. Khi sử dụng component trực tiếp trong DOM (đối nghịch với mẫu chuỗi hoặc single-file component) thì ta cần tuân theo quy chuẩn của W3C dành cho tên thẻ tùy chỉnh (tất cả đều viết bằng chữ thường và phải có dấu gạch nối giưa các từ). Điều này sẽ giúp ta tránh conflict với các phần HTML hiện thời hoặc tương lai.

Đặt tên

Có hai lựa chọn khi đặt tên cho component:

Theo cách kebab-case

Vue.component('my-component-name', { /* ... */ })

Khi đặt tên theo cách thức kebab-case thì ta ta cũng phải sử dụng kebab-case khi tham chiếu tới phần tử tùy chỉnh của nó, chẳng hạn như <my-component-name>.

Theo cách PascalCase

Vue.component('MyComponentName', { /* ... */ })

Khi đặt tên cho component theo cách thức PascalCase thì ta có thể sử dụng tên component theo cả cách thức kebab-case nữa. Có nghĩa là cả <my-component-name> và <MyComponentName> thì đều hợp lệ khi tham chiếu component tương ứng. Tuy nhiên thì chỉ có tên theo kebab-case là hợp lệ trong DOM.

Đăng ký global

So far, we’ve only created components using Vue.component:

Vue.component('my-component-name', {
  // ... các tùy chọn ...
})

Những component này được đăng ký theo dạng global, tức là chúng có thể được dùng trong template của bất kỳ đối tượng Vue root nào (new Vue) được tạo sau khi đăng ký. Ví dụ:

Vue.component('component-a', { /* ... */ })
Vue.component('component-b', { /* ... */ })
Vue.component('component-c', { /* ... */ })

new Vue({ el: '#app' })
<div id="app">
  <component-a></component-a>
  <component-b></component-b>
  <component-c></component-c>
</div>

Cả 3 component con ở trên đều được sử dụng trong nhau.

Đăng ký local

Đăng ký global thường không phải là ý hay. Ví dụ như khi ta dùng một hệ thống build như là Webpack chẳng hạn, thì việc đăng ký global cho tất cả các component sẽ dẫn đến vấn đề là ngay cả khi dừng sử dụng một component nào đó thì nó vẫn có thể được đưa vào build. Điều này là không cần thiết vì sẽ làm tăng lượng JavaScript cần phải download.

Trong trường hợp này thì ta nên định nghĩa component theo hướng local dưới dạng đối tượng JavaScript:

var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }

Sau đó ta sử dụng những component này bằng cách đưa vào tùy chọn components:

new Vue({
  el: '#app'
  components: {
    'component-a': ComponentA,
    'component-b': ComponentB
  }
})

Trong đó, với mỗi thuộc tính trong components thì key là tên do ta tự đặt, còn value chính là tên của component đã được định nghĩa theo cách thức local ở trên.

Nếu you want a local registered component inside another local register component, you can do the follow:

var ComponentA = { /* ... */ }

var ComponentB = {
  components: {
    'component-a': ComponentA
  },
  // ...
}

Or if you use ES6 modules, such as Webpack and Babel, you can do follow:

import ComponentA from './ComponentA.vue'

export default {
  components: {
    ComponentA
  },
  // ...
}

Các hệ thống module

If you are not using module system with import/require, you can skip this section for now. If you are, we have some special instructions and tips as bellow.

Đăng ký local trong hệ thống module

We use components to contain each component. For example, if we have a file ComponentB.vue and we want to use ComponentA and ComponentC in it, we can do following:

import ComponentA from './ComponentA'
import ComponentC from './ComponentC'

export default {
  components: {
    ComponentA,
    ComponentC
  },
  // ...
}

Then, we can use both ComponentA and ComponentC inside the template of ComponentB.

We can apply this way in practice. For example, we can create some base components as Button, Input, Icon, ... Then we include them in a component to use them as bellow:

import Button from './Button.vue'
import Icon from './Icon.vue'
import Input from './Input.vue'

export default {
  components: {
    Button,
    Icon,
    Input
  }
}
<Input
  v-model="searchText"
  @keydown.enter="search"
/>
<Button @click="search">
  <Icon name="search"/>
</Button>

Just to support relatively little markup in a template:

If you're using Webpack (or Vue CLI 3+, which uses Webpack internally), you can use require.context to globally register for only these very common base components. Here is an example to show that we can import globally base components in your app's entry file (i.e. store.js):

import Vue from 'vue'
import upperFirst from 'lodash/upperFirst'
import camelCase from 'lodash/camelCase'

const requireComponent = require.context(
  // The relative path of the components folder
  './components',
  // Whether or not to look in subfolders
  false,
  // The regular expression used to match base component filenames
  /Base[A-Z]\w+\.(vue|js)$/
)

requireComponent.keys().forEach(fileName => {
  // Get component config
  const componentConfig = requireComponent(fileName)

  // Get PascalCase name of component
  const componentName = upperFirst(
    camelCase(
      // Strip the leading `'./` and extension from the filename
      fileName.replace(/^\.\/(.*)\.\w+$/, '$1')
    )
  )

  // Register component globally
  Vue.component(
    componentName,
    // Look for the component options on `.default`, which will
    // exist if the component was exported with `export default`,
    // otherwise fall back to module's root.
    componentConfig.default || componentConfig
  )
})
» Tiếp: Transition cho enter/leave & danh sách
« Trước: Cơ bản về component
Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên
Copied !!!