vue文档组件篇杂项阅读

可复用的组件

在编写组件时,对于可复用的组件,要定义清晰接口(API),同时也不要对外部使用的数据做出任何假设方便复用。

Vue 组件的 API 来自三部分——prop、事件和插槽:

  • props 外部环境传递给组件的数据
  • 事件 从组件内部触发的外部环境的副作用
  • 插槽 外部环境将额外的内容组合在组件中

    上面时官网的定义,也就是说当我们考虑组件的复用时要自觉地考虑这三部分,同时在看别人写好的组件时也要自觉看别人如何定义的。

// todo 这里事件部分需要再加强理解
<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 和事件,但是有时仍然需要在 JavaScript 中直接访问子组件。为此可以使用 ref 为子组件指定一个引用 ID。例如:

首先是在js中直接访问子组件,相当于给子组件指定ref属性值,在父组件的$refs 中有存有各子组件的引用。这里先不管具体应用场景,先记住。

<!-- 当 ref 和 v-for 一起使用时,获取到的引用会是一个数组,包含和循环数据源对应的子组件。 -->
<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 只在组件需要渲染时触发工厂函数,并且把结果缓存起来,用于后面的再次渲染。

原来组件使用步骤是:

//user.js
export default {
  template: '<div>A custom component!</div>'
}

// 引入,并注册
const User = import('user')

{
  components: User //原来组件是个对象,或者是个渲染函数
}

在异步组件中,组件是一个工厂函数,异步解析组件的定义。这里既然是个函数,免不了要调用。而这里是需要使用的时候再调用。

Vue.js 只在组件需要渲染时触发工厂函数,并且把结果缓存起来,用于后面的再次渲染。

为什么叫工厂函数,理解为产生组件的生产工厂。因此结构什么的应该是统一的,不看工厂函数的实现,这个函数返回的应该是我们实际的组件。相当于是这样方式

// 一般的异步加载某件东西的操作
{
   components: function(){
      // 异步获取并返回
      ajax.getComponents('user',function(data){
        return data.User
      })
   }
}

// 因此我觉得Vue组件内部判断是一个函数的,应该也是上面那种操作,作者帮我们做了一层封装, 并没有看源码,自己猜的,便于理解,然而目的就是一个异步加载数据。
Vue.component('async-example', function (resolve, reject) {
  setTimeout(function () {
    // 将组件定义传入 resolve 回调函数
    resolve({
      template: '<div>I am async!</div>'
    })
  }, 1000)
})

这里使用 setTimeout 只是为了演示,实际上如何获取组件完全由你决定。同时关于resolve的作用应该就是将异步获取的组件给返回出去。类似return的作用

异步加载已经实现,因为是个函数所以也会自动调用,现在问题是设置webpack的代码分割,把我们需要异步加载的组件给分出去,不用我们自己再操心如何加载,如何划分的事。

推荐配合 webpack 的代码分割功能 来使用:

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

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

// promise方式,使用promise目的之一就是统一异步流程
{
   components: function(){
     return new Promise((resolve,reject){
        ajax.getComponents('user',function(data){
          if('成功') resolve(data.User)
          else reject(data.error)
        })
     })
   }
}

这里import函数的实现应该就是我上面promise实现方式的写法,而之前的方式应该resolve表示的应该是return的意思

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

高级异步组件

// 自 2.3.0 起,异步组件的工厂函数也可以返回一个如下的对象:
const AsyncComp = () => ({
  // 需要加载的组件。应当是一个 Promise
  component: import('./MyComp.vue'),
  // 加载中应当渲染的组件
  loading: LoadingComp,
  // 出错时渲染的组件
  error: ErrorComp,
  // 渲染加载中组件前的等待时间。默认:200ms。
  delay: 200,
  // 最长等待时间。超出此时间则渲染错误组件。默认:Infinity
  timeout: 3000
})

注意,当一个异步组件被作为 vue-router 的路由组件使用时,这些高级选项都是无效的,因为在路由切换前就会提前加载所需要的异步组件。另外,如果你要在路由组件中使用上述写法,需要使用 vue-router 2.4.0 以上的版本。

上面加粗的还不是太理解,随着使用再来填坑。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值