Component is expanded from a Vue.js
component and provides parameter input capabilities that are equivalent to the Vue
component. It provides Decorator
styles for class
during code writing.
Code import
import { Component, Watch } from '@ali/kylin-framework';
Structure of component declarations
A component can contain peer configurations of the options
of Vue
, such as data, JSX rendering functions, templates, mounting elements, methods, and life cycles. Component declarations include the following parts, which are separately packaged by using the @Component
and @Watch
decorators.
Declarations of classes, which are packaged by using the
@Component
decorator.Decorations of class members, which are packaged without using a decorator.
Declarations of class member methods, which are packaged usually without using a decorator unless the method needs to
watch
another declared variable
The following example shows you how to develop a simple component. For information about specific declaration parameters, see Component API.
*.vue single file component
<!-- Hello.vue -->
<template>
<div>hello {{name}}
<Child></Child>
</div>
</template>
<style>
/* put style here */
</style>
<component default="Child" src="./child.vue" />
<script>
import { Component } from '@ali/kylin-framework';
@Component
class Hello {
data = {
name: 'world'
}
}
export default Hello;
</script>
For information about the label-style component dependencies in the <component>
format, see Component API.
Component API
Similar to Vue, the definition of a component is written in the .vue
file. The following code shows a simple example:
<template>
<div>
<AButton @click="onClick">Click</AButton>
</div>
</template>
<style lang="less" rel="stylesheet/less">
/* less */
</style>
<dependency component="{ AButton }" src="@alipay/antui-vue" lazy/>
<script type="text/javascript">
import { Component } from '@ali/kylin-framework';
@Component
export default class IndexView {
props = {}
data = {}
get comput() { return this.data.c * 2 }
onClick() {}
mounted() {}
}
</script>
The preceding example contains four top-level labels including <template>
, <style>
, and <script>
, which are similar to those in Vue, and <dependency>
.
The following sections describe the usage of the four labels. The definitions of the <template>
and <style>
labels are the same as those in Vue
.
Script
Class structure
Define a Component. Based on the code structure, use Decorators of the class. Available decorators are @Component
and @Watch
, which can be imported as shown in the following code:
import { Component, Watch } from '@ali/kylin-framework';
@Component
export default class Hello {
}
Method type
The Component is declared as a class, and the class must be decorated with a Decorator. Inside a class, member variables are automatically processed by the babel
plug-in during the building process. Member functions usually do not require a decorator unless @Watch
is used. The following table describes the properties that the @Component
decorator can process.
Member type | Name | Usage |
get/set property | * | Used to convert into the |
beforeCreate | Life cycle | The life cycle method, which is equivalent to that in |
created | Life cycle | The life cycle method, which is equivalent to that in |
beforeMount | Life cycle | The life cycle method, which is equivalent to that in |
mounted | Life cycle | The life cycle method, which is equivalent to that in |
beforeUpdate | Life cycle | The life cycle method, which is equivalent to that in |
updated | Life cycle | The life cycle method, which is equivalent to that in |
beforeDestroy | Life cycle | The life cycle method, which is equivalent to that in |
destroyed | Life cycle | The life cycle method, which is equivalent to that in |
method | * | A regular member method that is used to convert into the method list |
getter/setter property
@Component
export default class Hello {
get computName() {
// to sth
}
}
The preceding getter
declaration is equivalent to the following Vue configuration:
HelloOption = {
computed: {
computName: {
get: computName() {
// to sth
}
}
}
}
Likewise, setter
is also extracted. If both getter
and setter
exist, they are extracted together.
Life cycle functions
@Component
export default class Hello {
created() {}
mounted() {}
}
The preceding life cycle functions created
and mounted
are extracted as arrays.
TestOption = {
created: [function created(){}],
mounted: [function mounted(){}],
}
The following life cycle methods are supported: beforeCreate
, created
, beforeMount
, mounted
, beforeUpdate
, updated
, beforeDestroy
, and destroyed
.
Watch
This decorator exists because watch
requires the following elements:
The variables to listen to
Listening options
Trigger function
Usage
The following table describes all the parameters for the @Watch
decorator.
function Watch( key: string [, option: Object = {} ] ): PropertyDecorator
Parameter | Type | Usage | |
key | string | The name of the parameter that is listened to. Valid values: | |
option | deep | boolean | Specifies whether an inner data change is triggered when a complex object is listened. Default value: |
immediate | boolean | Specifies whether to immediately trigger a callback by using the current value of the expression. Default value: |
Example
For a member function that is decorated by
@Watch
, you can configure listening of multiple variables for the member function. In the following sample code, changes to thea
andc
parameters are listened. A change to either of the parameters will trigger the member methodOnChangeA
.OnChangeA
is a member method in nature and is extracted to themethods
block together with other member methods. Therefore, make sure that the name of this member method is unique.If there are additional configuration items for Watch, import them by using the
@Watch('a', {deep: false})
method. For more information about configuration items, see Watch configuration items.
@Component
class WTest {
data = {
a: {
b: 2
},
c: 3
}
@Watch('c')
@Watch('a', {deep: false})
OnChangeA(newVal, oldVal) {
}
}
Note: The listener for data.a
is converted. If the deep: true
option is disabled, the OnChangeA
method is not triggered when data.a.b
is changed.
Property types
The build tool automatically applies the @Component.Property
decorator to member variables. The final merging strategy depends on the identifier name of the decorated member variable
. The following table describes some members that are built in the framework. Members that are not in the following table are passed through to the options
object of VueComponent
.
Member type | Name | Usage |
Property | props | The props property of Vue. |
Property | data | The data property of Vue. This property is converted into a function and supports the this method. Do not use |
Property | * | Other unknown properties, which are copied to the corresponding properties in the |
props
@Component
export default class Hello {
props = {
name: {
type: String,
default: 'haha'
},
num: Number
}
}
The preceding definition of the member variable props
is converted into the corresponding props
property in the options
object.
HelloOption = {
props: {
name: {
type: String,
default: 'haha'
},
num: Number
}
}
For information about the complete definition structure, see the API-props topic in the Vue documentation.
data
@Component
export default class Hello {
props = {
name: {
type: Number,
default: 1
},
}
data = {
hello: this.props.name + 2
}
}
The preceding definition of the member variable data
is converted into a data function. You do not need to manually write a data function.
TestOption = {
props: {
name: {
type: Number,
default: 1
},
},
data: function data() {
return {
hello: this.props.name + 2
}
}
}
dependency
In the preceding example, the definition of <script>
does not describe how to use component dependencies. We recommend that you use the <dependency>
label to mark component dependencies in the .vue
file. In the following example, the ./child.vue
component is referenced.
<template>
<child></child>
</template>
<dependency component="Child" src="./child.vue" />
Label properties
default import
The following table describes the properties that are used for introducing the default
export of ES6 Module
or the export of the commonjs Module
object.
Parameter | Type | Default value | Remarks |
component | string | Required | The identifier name to be imported to |
src | string | Required | The source of the component. The value of this property is the same as the result of the |
lazy | boolean | false | Specifies whether to enable lazy loading for the component. If lazy loading is enabled, a module of the component is loaded only when |
style | string | undefined | By default, this property is not used. If you set a string for this property, the system loads the corresponding style file of the component by using the |
The following code shows an example:
<dependency component="name" src="source" lazy />
member import
The following table describes the properties that are used for introducing the export of ES6 module
names.
Parameter | Type | Default value | Remarks |
component | string | Required | The multiple naming identifiers to be imported to |
src | string | Required | The source of the component. The value of this property is the same as the result of the |
lazy | boolean | false | Specifies whether to enable lazy loading for the component. If lazy loading is enabled, a module of the component is loaded only when |
The following code shows an example:
<dependency component="{ List, ListItem, AButton }" src="@alipay/antui-vue" lazy />
By default, on-demand babel-plugin-import
loading is supported for the @alipay/antui-vue
component library.
template
The template content structure is consistent with that of Vue.
<template>
<div>Hello World</div>
</template>
style
<style lang="less" rel="stylesheet/less">
/* less */
</style>
You can add the property tag scoped
, so that the style takes effect only for the current component.
<style lang="less" rel="stylesheet/less" scoped>
/* less */
</style>
Status injection
We recommend that you use the following connect
mechanisms to pass through $store
data:
Use one of the following methods to pass through data:
If you need to use the properties of Store
in Kylin components, we recommend that you do not use calculation properties to pass through the properties of the $store
object. We recommend that you use the following method:
@Component
class Hello {
// Associate the status in the store by using calculation properties.
get hello() {
return this.$store.state.hello
}
}
API declaration
@Component({
mapStateToProps: Object|Array,
mapActionsToMethods: Object|Array,
mapMethods: Array|Boolean,
mapEvents: Array
})
class Hello {
}
mapStateToProps
This function is used to map specific key values in state
to those in the props
property of the current component. This function accepts parameter in the same way as the auxiliary function that is provided by Veux
.
You can use one of the following methods to implement this feature:
Function-based method
The following code maps the data named bbb
in $store.state
to the props
property of aaa
.
{
mapStateToProps: {
aaa: (state, getters) => state.bbb
}
}
String key-value pair-based method
The following code maps the data named bbb
in $store.state
to the props
property of aaa
.
{
mapStateToProps: {
aaa: 'bbb'
}
}
String array-based method
The code below performs the following operation:
Map the data named
aaa
in$store.state
to theprops
property ofaaa
.Map the data named
bbb
in$store.state
to theprops
property ofbbb
.
{
mapStateToProps: ['aaa', 'bbb']
}
mapActionsToMethods
Similar to the input parameters of the mapActions
function in Vuex
, this function allows you to inject the actions
property in the global $state
object into the methods
of the current component. You can complete the injection based on the name mapping of objects or based on the names of arrays.
@Component({
mapActionsToMethods: ['a', 'b']
})
class IndexView {
async doSomeAction() {
const ret = await this.a(123);
// Equivalent to a call.
// const ret = await this.$store.dispatch('a', 123);
}
}
mapMethods
Implement the connect
mechanism by adding a middle layer component between a parent component and a child component. When the parent component calls a specific method
in the child component, the parent component connects to the middle layer component instead of the child component. Use the following configurations to implement the required access:
@Component({
mapMethods: true
})
export default class Child {
a() {}
}
<template>
<div>
this is parent
<child ref="child"></child>
</div>
</template>
<script>
@Component
export default class Parent {
b() {
// Access is enabled here.
this.$refs.child.a();
}
}
</script>