VueJs学习随笔--插槽和异步组件

插槽

Vue 中提供插槽来让你替换组件中的部分内容, 例如你定义了一个组件 <navigation-link> :

<a v-bind:href="url" class="nav-link">
  <slot></slot>
</a>

这里的 <slot> 就是可以替换的内容部分,如果你这样使用:

<navigation-link url="/profile">
  Your Profile
</navigation-link>

那么上面的 <slot> 就会被替换成 Your Profile, 当然上面的 <slot> 中可以添加默认内容:

<a v-bind:href="url" class="nav-link">
  <slot>Default Value</slot>
</a>

我们也可以使用 html 代码来替换 <slot> :

<navigation-link url="/profile">
  <span class="fa fa-user"></span> Your Profile
</navigation-link>

假设上面的 <navigation-link> 中没有包含 <slot> 标签,则使用替换功能就会替换掉所有内容。

这里需要注意的是,不可以使用组件的数据(因为不在访问作用域中)

<navigation-link url="/profile">
  Logged in as {{ user.name }}
</navigation-link>

父级模板里的所有内容都是在父级作用域中编译的, 子模板里的所有内容都是在子作用域中编译的。

新插槽

上面的方法在 vue 2.6.0 之后已经废弃,而是才用具有 name 的插槽, 下面是 base-layout 组件:

<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>

<slot> 元素有一个特殊的特性:name 。这个特性可以用来定义额外的插槽, 不带 name<slot> 出口会带有隐含的名字 default

可以在一个 <template> 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称:

<base-layout>
  <template v-slot:header>
    <h1>Here might be a page title</h1>
  </template>

  <p>A paragraph for the main content.</p>
  <p>And another one.</p>

  <template v-slot:footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>

前面我们提到插槽内容无法访问到子组件中的数据,但是有时候需要访问,我们可以将该数据绑定到 <slot> 上面:

<span>
  <slot v-bind:user="user">
    {{ user.lastName }}
  </slot>
</span>

绑定在 <slot> 元素上的特性被称为插槽 prop。现在在父级作用域中,我们可以给 v-slot 带一个值来定义我们提供的插槽 prop 的名字:

<current-user>
  <template v-slot:default="slotProps">
    {{ slotProps.user.firstName }}
  </template>
</current-user>

在这个例子中,我们选择将包含所有插槽 prop 的对象命名为 slotProps,但你也可以使用任意你喜欢的名字。

v-on , v-bind 一样, v-slot 也有缩写名 #.

异步组件

在大型应用中,我们可能需要将应用分割成小一些的代码块,并且只在需要的时候才从服务器加载一个模块。为了简化,Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义。Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染。例如:

Vue.component('async-example', function (resolve, reject) {
  setTimeout(function () {
    // 向 `resolve` 回调传递组件定义
    resolve({
      template: '<div>I am async!</div>'
    })
  }, 1000)
})

这个工厂函数会收到一个 resolve 回调,这个回调函数会在你从服务器得到组件定义的时候被调用。你也可以调用 reject(reason) 来表示加载失败。这里的 setTimeout 是为了演示用的,如何获取组件取决于你自己。