Vue 从入门到进阶

编写简单的 Vue 组件

2018-03-09  本文已影响65人  yibuyisheng

既然 Vue 是基于组件去构造视图的,那么最重要的事情当然是要掌握组件的知识点了。

Vue 为了极大简化组件的开发,把组件的书写形式精炼为配置的形式,一个组件使用一个 js 对象来描述,然后利用该 js 描述对象可以生成多个该组件实例。

打开 vue/types/index.d.ts 文件,可以看到四个与组件相关的类型:

此处主要关注 AsyncComponentComponentOptionsFunctionalComponentOptions ,分别对应异步组件普通组件函数组件

ComponentOptions

vue/types/options.d.ts 中可以看到 ComponentOptions 的声明,重点关注如下属性声明:

以上是构造普通组件的最基础属性,那么定义一个简单普通组件就可以这样写:

import Vue, { ComponentOptions } from 'vue';

const MyComponent: ComponentOptions<Vue> = {
    props: {
        name: String,
        age: number
    },
    data() {
        return {
            counter: 0
        };
    },
    created() {
        this.setTimer();
    },
    methods: {
        setTimer() {
            setInterval(() => this.counter++, 1000);    
        }
    },
    template: '<div class="my-component">{{ name }} {{ age > 18 ? 'old' : 'young' }} {{ counter }}</div>'
};

Vue.component('MyComponent', MyComponent);

在上述组件定义中,有若干知识点:

上述组件配置通过 Vue.component 方法注册到 Vue 的全局空间中去,其中,第一个参数指定该组件在全局空间中的名字为 MyComponent ,在需要使用该组件的地方通过名字调用就行了:

import Vue, { ComponentOptions } from 'vue';

const App: ComponentOptions<Vue> = {
    el: 'app',
    data() {
        return {
            age: 27
        };
    },
    template: '<MyComponent name="yibuyisheng" :age="age"></MyComponent>'
};

Vue.component('MyComponent', MyComponent);

对于 props 属性,直接通过标签属性(比如 name="yibuyisheng")的形式传递给组件。

在执行上述示例的时候,可以发现,{{ counter }} 表达式部分的输出会一秒加一。实际上, data 里面事先声明的数据都是响应式的,改变 data 中声明的数据,模板中相应部分就会发生变化。

FunctionalComponentOptions

函数式组件的主要特点在于没有本地状态 data ,不会生成组件实例,组件需要的一切信息都从上下文参数中获取。

函数式组件配置项非常少:

编写一个简单的函数式组件:

import Vue, { FunctionalComponentOptions } from 'vue';

const MyFunctionalComponent: FunctionalComponentOptions<Record<string, any>, string[]> = {
    props: ['name'],
    functional: true,
    render(createElement, context) {
        return createElement('div', context.data, ['name: ' + context.props.name]);
    }
};
Vue.component<string>('MyFunctionalComponent', MyFunctionalComponent);

说明:

  • createElement 方法用于创建一个 VNode 节点,详细内容将会在后续文章介绍,目前只需要知道 createElement('div', ...) 会在 DOM 树中生成一个 div 元素节点。
  • 通过 context.props 访问函数式组件外部传入的 props 数据。

AsyncComponent

在开发一些大型( SPA )应用的时候,可能会存在大量前端组件代码,对首屏进入可交互状态造成一定的延迟。

实际上,渲染页面1的时候,最好不要去加载页面2的组件,直到用户点击进入页面2的时候,才去加载页面2相关的组件。

为了实现这个功能, Vue 组件支持异步写法:

import Vue, { AsyncComponent } from 'vue';

const MyAsyncComponent: AsyncComponent = function (resolve) {
    setTimeout(function () {
        resolve({
            template: '<div>async component.</div>'
        });
    }, 1000);
};
Vue.component('MyAsyncComponent', MyAsyncComponent);

在一秒后,组件加载完成,相应界面得到渲染。

预告

下一篇文章将会深入介绍 Vue 内部的响应式原理。

上一篇下一篇

猜你喜欢

热点阅读