【Vue】自定义事件、动态插槽、异步组件

1. 自定义事件

1.1 事件名

  • 不同于组件和 prop,事件名不会被用作一个 JavaScript 变量名或属性名,所以就没有理由使用 camelCase 或 PascalCase 了。并且 v-on 事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以 v-on:myEvent 将会变成 v-on:myevent——导致 myEvent 不可能被监听到。
//js
this.$emit('myEvent')
//html
<!-- 没有效果 -->
<my-component v-on:my-event="doSomething"></my-component>

必须始终使用 kebab-case 的事件名

1.2 .sync修饰符

<text-document
  v-bind: title="doc.title"
  v-on:update:title="doc.title=$event"
></text-document>

为了方便起见,我们为这种模式提供一个缩写,即 .sync 修饰符

//与上面的代码等价
<text-document v-bind:title.sync="doc.title"></text-document>

2. 插槽

  • A. 假设有一个组件 <navigation-link>,如果 <navigation-link> 的 template 里没有包含一个 <slot> 元素,则任何传入 <navigation-link> 的内容都会被抛弃。
    例如
//没有效果
<navigation-link>
    你好
  </navigation-link>
  • 使用具名插槽 <slot name="xxx'> 可以实现一个组件拥有多个插槽
  • 可以使用 <slot>默认内容</slot> 来指定插槽里的默认内容
  • 通过设置 slot 属性可以设置内容对应的插槽名字
  • 通过设置 slot-scope 属性,可以从子组件中获取数据

在vue.js 2.6.0 中,为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。它取代了 slotslot-scope 这两个目前已被废弃但未被移除且仍在文档中.


3. 动态组件

我们之前通常在一个多标签的界面中使用 is 特性来切换不同的组件:

 <component v-bind:is="currentTabComponent"></component>

当在这些组件之间切换的时候,你有时会想保持这些组件的状态,以避免反复重渲染导致的性能问题。

为了解决这个问题,我们可以用一个 <keep-alive> 元素将其动态组件包裹起来。

<!-- 失活的组件将会被缓存!-->
<keep-alive>
  <component v-bind:is="currentTabComponent"></component>
</keep-alive>

4. 异步组件

异步组件是指,在需要用到它的时候才从服务器加载一个组件

  • 如果项目支持 webpack 2+ 和 ES 2015+,那么可以这样实现异步组件

     Vue.component(
          'async-webpack-example',
          () => import('./my-async-component')
      )
    
  • 如果项目支持 webpack 2+ 和 ES 2015+,那么可以这样实现异步组件

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

5. 处理边界情况

5.1 依赖注入

访问更深层的嵌套组件属性时,$parent属性无法满足,依赖注入提供了两个实例选项provide 和 inject。

//html
<div id="app">
    <component-one>
      <component-two>
        <component-three>

        </component-three>
      </component-two>
    </component-one>

  </div>
//js
Vue.component('component-one', {
  template: `
    <div><slot></slot></div>
  `,
  provide:{
    provide1(){
      console.log('这是component-one提供的函数')
    }
  }
})
Vue.component('component-two', {
  template: `
    <div><slot></slot></div>
  `,

})
Vue.component('component-three', {
  template: `
    <button @click="provide1">Click me</button>
  `,
  inject: ['provide1']
})

var app = new Vue({
  el: '#app',

})

5.2 事件侦听器

  • 可以通过 $on(eventName, eventHandler) 侦听一个事件
  • 可以通过 $once(eventName, eventHandler) 一次性侦听一个事件
  • 可以通过 $off(eventName, eventHandler) 停止侦听一个事件
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容