anjia / blog

博客,积累与沉淀
106 stars 4 forks source link

Vue #42

Open anjia opened 5 years ago

anjia commented 5 years ago

目录

anjia commented 5 years ago

组件通信 Event Bus

/utils/event-bus.js

import Vue from 'vue'
export const EventBus = new Vue()

使用:

import { EventBus } from '@/utils/event-bus'

EventBus.$emit('custom_event_name', this.data)   // 发送事件
EventBus.$on('custom_event_name', (data) => {})  // 监听事件
EventBus.$off('custom_event_name')  // 销毁

注意:

  1. 确保先 $on()$emit()
  2. 结束时,要销毁 $off()。否则会监听到多次

场景 1

路由,从组件 A -> B。使用如下:

// 组件A
beforeDestroy() {
    EventBus.$emit()
}

// 组件 B
beforeCreate() {
    EventBus.$on()
}
beforeDestroy() {
    EventBus.$off()
}

说明:注意它两的生命周期,确保先 $on()$emit()

不适用的情况:

  1. 传 B 页面的初始数据。这样以来会导致,一刷新 B 就空了。因为数据丢了

EventBus 实践

$on 和 $off 配对

https://cn.vuejs.org/v2/api/index.html#实例方法-事件

anjia commented 5 years ago

实例属性

let vm = this

  1. vm.$data 实例观察的数据对象。data
  2. vm.$options 当前 Vue 实例的初始化选项
  3. vm.$props 当前组件接收到的 props 对象
  4. vm.$attrs 包含了父作用域中不作为 prop 被识别的特性绑定,除了classstyle
  5. vm.$listeners 包含了父作用域中的v-on事件监听器

  1. vm.$root 当前组件树的根 Vue 实例
  2. vm.$el Vue 实例使用的根 DOM 元素
  3. vm.$parent 父实例,如果有的话
  4. vm.$children 当前实例的直接子组件。并不保证顺序、也不是响应式的
  5. vm.$refs 注册过ref特性的所有 DOM 元素和组件实例。子组件引用特殊特性-ref

  1. vm.$slots 被插槽分发的内容。这在渲染函数里特别有用。插槽
    • v-slot指令比slotslot-scope更新
      • 写法即,在组件里直接引用<slot></slot>
      • 定义默认值,即<slot>默认值</slot>
      • 此API可用于分发内容,灵感来自Web Components规范草案
    • 具名插槽
      • <slot name="header"></slot>
      • 不带name属性的,默认名字是 default
        • 任何没有被包裹在<template v-slot:xxx>...</template>中的内容都会被视为默认插槽的内容
    • 作用域插槽
      • 为了父级的插槽内容中访问到父组件的变量,可以将此变量绑定到<slot>元素上
        • eg.<slot v-bind:user="user">{{ user.lastName }}<slot>
      • 一旦出现多个插槽,请始终为所有插槽使用完整的基于<template>的语法
      • 当只有一个时,可以简写为<current-user v-slot="slotProps">{{ slotProps.user.firstName }}</current-user>
        • 即将你的插槽内容,包括在一个传入单个参数的函数里
        • v-slot的值,可以是任何的 JS 表达式,eg.可以使用ES2015解构传入具体的插槽 prop
    • 动态插槽名 <template v-slot:[dynamicSlotName]>...</template> eg.动态参数
  2. vm.$scopedSlots 用来访问作用域插槽。这在渲染函数里特别有用。推荐
    • vm.$slots相比,更推荐用vm.$scopedSlots

v-onv-bind 的缩写 #headerv-slot:header 的缩写


  1. vm.$isServer 当前 Vue 实例是否运行于服务器。详见 服务端渲染

https://cn.vuejs.org/v2/api/#示例属性

anjia commented 4 years ago

指令

anjia commented 4 years ago

自定义指令

适用场景:对普通 DOM 元素进行底层操作

Vue.directive(); // 注册一个全局自定义指令 v-xx
Vue.component(); // 注册组件,directives 选项可注册局部指令

钩子函数:

  1. bind:指令第一次绑定到元素时调用,只调用一次(适合一次性的初始化设置)
  2. inserted:被绑元素插入到父元素时调用(插入到父元素,未必被插入到文档中)
  3. update:所在组件的 VNode 更新时(也可能发生在子 VNode 更新之前,VNodes-虚拟 DOM
  4. componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用
  5. unbind:指令与元素解绑时调用,只调用一次

钩子函数的参数:

  1. el:指令所绑的元素,可直接操作 DOM
  2. binding:指令相关的值。详见下方示例
  3. vnode:Vue 编译生成的虚拟节点,VNode API
  4. oldVnode

除了el,其它参数都只读 如要在钩子中间共享数据,可通过元素的dataset

参数说明:

示例:

<div id="hook-arguments-example" v-demo:foo.a.b="message"></div>

<script>
Vue.directive('demo', {
  bind: function (el, binding, vnode) {
    var s = JSON.stringify
    el.innerHTML =
      'name: '       + s(binding.name) + '<br>' +         // demo
      'value: '      + s(binding.value) + '<br>' +        // hello!
      'expression: ' + s(binding.expression) + '<br>' +   // message
      'argument: '   + s(binding.arg) + '<br>' +          // foo
      'modifiers: '  + s(binding.modifiers) + '<br>' +    // {"a":true, "b":true} 包含修饰符的对象
      'vnode keys: ' + Object.keys(vnode).join(', ')      // tag,data,....
  }
})

new Vue({
  el: '#hook-arguments-example',
  data: {
    message: 'hello!'
  }
})
</script>

https://cn.vuejs.org/v2/guide/custom-directive.html