曹可爱之最可爱-Vue.js入门(十)组件5

开篇废话:组件终于要完结了,充电器忘公司了,乘着电脑还有一点电赶快完成这一篇。

编写可复用组件

在编写组件时,最好考虑好以后是否要进行复用。一次性组件间有紧密的耦合没关系,但是可复用组件应当定义一个清晰的公开接口,同时也不要对其使用的外层数据做出任何假设。

Vue组件的API来自三部分 – prop,事件和插槽:
1.prop允许外部环境传递数据给组件;
2.事件允许从组件内触发外部环境的副作用;
3.插槽允许外部环境将额外的内容组合在组件中。

使用v-bind和v-on的简洁写法,模板的意图会更清楚且简洁:

<my-component
    :foo="baz"
    :bar="qux"
    @event-a="doThis"
    @event-b="doThat"
>
    <img slot="icon" src="...">
    <p slot="main-text">hello!</p>
</my-component>

子组件的引用

尽管有prop和事件,但有时仍然需要在js中直接访问子组件。为此可以使用ref为子组件指定一个引用ID。例如:

<div id="parent">
    <user-profile ref="profile"></user-profile>
</div>
var parent = new Vue({ el: '#parent' }}
// 访问子组件实例
var child = parent.$refs.profile

refs使 refs。(本来还想说卧槽什么黑科技,结果..哎,还是提起裤子吧)


异步组件
在大型应用中,我们可能需要将应用拆分为多个小模块,按需从服务器下载。为了进一步简化,Vue.js允许将组件定义为一个工厂函数,异步地解析组件的定义。Vue.js 只在组件需要渲染时触发工厂函数,并且把结果缓存起来,用于后面的再次渲染。例如:

Vue.compoent('async-example', function(resolve, reject) {
    setTimeout(function () {
        // 将组件定义传入resolve回调函数
        resolve({
            template: '<div>I am async!</div>'
        })
    },1000)
})

工厂函数接收一个resolve回调,在收到从服务器下载的组件定义时调用。也可以调用reject(reason)指示加载失败。推荐配合webpack的代码分割功能来使用:

Vue.component('async-webpack-example', function(resolve) {
    // 这个特殊的require语法告诉webpack
    // 自动将编译后的代码分割成不同的块
    // 这些块将通过 Ajax 请求自动下载
    require(['./my-async-component'],resolve)
})

你可以在工厂函数中返回一个 Promise,所以当使用 webpack 2 + ES2015 的语法时可以这样:

Vue.component(
  'async-webpack-example',
  // 该 `import` 函数返回一个 `Promise` 对象。
  () => import('./my-async-component')
)

当使用局部注册时,也可以直接提供一个返回 Promise 的函数:

new Vue({
  // ...
  components: {
    'my-component': () => import('./my-async-component')
  }
})

高级异步组件
自 2.3.0 起,异步组件的工厂函数也可以返回一个如下的对象:

const AsyncCompo = () => ({
    // 需要加载的组件。应当是一个 Promise
    component: import('./MyComp.vue'),
     // 加载中应当渲染的组件
    loading: LoadingComp,
    // 出错时渲染的组件
    error:ErrorComp,
    // 渲染加载中组件前的等待时间。默认:200ms。
    delay: 200,
    // 最长等待时间。超出此时间则渲染错误组件。默认:Infinity
    timeout: 3000
})

注意,当一个异步组件被作为vue-router的路由组件使用时,这些高级选项都是无效的,因为在路由切换前就会提前加载所需要的异步组件。


组件命名约定
当注册组件 (或者 prop) 时,可以使用 kebab-case (短横线分隔命名)、camelCase (驼峰式命名) 或 PascalCase (单词首字母大写命名)。

// 在组件定义中
components: {
  // 使用 kebab-case 注册
  'kebab-cased-component': { /* ... */ },
  // 使用 camelCase 注册
  'camelCasedComponent': { /* ... */ },
  // 使用 PascalCase 注册
  'PascalCasedComponent': { /* ... */ }
}

在 HTML 模板中,请使用 kebab-case:

<!-- 在 HTML 模板中始终使用 kebab-case -->
<kebab-cased-component></kebab-cased-component>
<camel-cased-component></camel-cased-component>
<pascal-cased-component></pascal-cased-component>

递归组件

组件在它的模版内可以递归的调用自己。不过只有当它有name选项时才可以这么做

name: 'unique-name-of-my-component'

当你利用 Vue.component 全局注册了一个组件,全局的 ID 会被自动设置为组件的 name。

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

确保递归调用有终止条件 (比如递归调用时使用 v-if 并最终解析为 false)。


内联模板
如果子组件有inline-template特性,组件将把它的内容当作它的模板,而不是把它当作分发内容。这让模板写起来更灵活。

<my-component inline-template>
    <div>
        <p> 这些将作为组件自身的模板。</p>
        <p> 而非父组件透传进来的内容。</p>
    </div>
</my-component>

但是 inline-template 让模板的作用域难以理解。使用 template 选项在组件内定义模板或者在 .vue 文件中使用 template 元素才是最佳实践。


对低开销的静态组件使用v-once
尽管在 Vue 中渲染 HTML 很快,不过当组件中包含大量静态内容时,可以考虑使用 v-once 将渲染结果缓存起来,就像这样:

Vue.component('terms-of-service', {
    template: '\
    <div v-once>\
      <h1>Terms of Service</h1>\
      ...很多静态内容...\
    </div>\
  '
})

总结:组件总算全都过了一遍,接下来开始webpack和搭建项目吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值