组件名
 Vue.component('my-component-name', { /* ... */ })my-component-name就是组件名,组件名的取法可以参考指南
kebab-case写法(-连接单词) 推荐的写法
定义:
  Vue.component('my-component-name', { /* ... */ })用法:
  <my-component-name></my-component-name>PascalCase写法(单词首字母大写)
  Vue.component('MyComponentName', { /* ... */ })全局注册
  Vue.component('my-component-name', { /* ... */ })局部注册
先用一个普通的 JavaScript 对象来定义组件:
  var ComponentA = { /* ... */ }
  var ComponentB = { /* ... */ }然后在 components 选项中定义你想要使用的组件:
  new Vue({
  el: '#app',
  components: {
      'component-a': ComponentA,
      'component-b': ComponentB
  }
  })对于 components 对象中的每个属性来说,其属性名就是自定义元素的名字,其属性值就是这个组件的选项对象。
注意局部注册的组件在其子组件中不可用。例如,如果你希望 ComponentA 在 ComponentB 中可用,则你需要这样写:
  var ComponentA = { /* ... */ }
  var ComponentB = {
  components: {
      'component-a': ComponentA
  },
  // ...
  }或者如果你通过 Babel 和 webpack 使用 ES2015 模块,那么代码看起来更像:
  import ComponentA from './ComponentA.vue'
  export default {
  components: {
      ComponentA
  },
  // ...
  }import/require 使用一个模块系统
  import ComponentA from './ComponentA'
  import ComponentC from './ComponentC'
  export default {
  components: {
      ComponentA,
      ComponentC
  },
  // ...
  }prop大小写(camelCase vs kebab-case)
HTML 中的特性(属性)名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名:
  Vue.component('blog-post', {
  // 在 JavaScript 中是 camelCase 的
  props: ['postTitle'],
  template: '<h3>{{ postTitle }}</h3>'
  })  <!-- 在 HTML 中是 kebab-case 的 -->
  <blog-post post-title="hello!"></blog-post>强烈建议用kebab-case写法。prop 类型
通常,以字符串数组形式列出 prop:
  props: ['title', 'likes', 'isPublished', 'commentIds', 'author']但是,通常你希望每个 prop 都有指定的值类型。这时,你可以以对象形式列出 prop,这些属性的名称和值分别是 prop 各自的名称和类型:
  props: {
      title: String,
      likes: Number,
      isPublished: Boolean,
      commentIds: Array,
      author: Object,
      callback: Function,
      contactsPromise: Promise // or any other constructor
  }传递静态或动态prop
传递静态值:
  <blog-post title="My journey with Vue"></blog-post>传递动态值
  <!-- 动态赋予一个变量的值 -->
  <blog-post v-bind:title="post.title"></blog-post>
  <!-- 动态赋予一个复杂表达式的值 -->
  <blog-post
  v-bind:title="post.title + ' by ' + post.author.name"
  ></blog-post>实际上,能传递的值包括:字符串、数字、布尔值、数组、对象、对象所有属性。
单向数据流
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。
prop验证
  Vue.component('my-component', {
      props: {
          // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
          propA: Number,
          // 多个可能的类型
          propB: [String, Number],
          // 必填的字符串
          propC: {
              type: String,
              required: true
          },
          // 带有默认值的数字
          propD: {
              type: Number,
              default: 100
          },
          // 带有默认值的对象
          propE: {
          type: Object,
          // 对象或数组默认值必须从一个工厂函数获取
              default: function () {
                  return { message: 'hello' }
              }
          },
          // 自定义验证函数
          propF: {
          validator: function (value) {
              // 这个值必须匹配下列字符串中的一个
              return ['success', 'warning', 'danger'].indexOf(value) !== -1
          }
      }
      }
  })上面的type可以是原生构造函数的一个:String,Number,Boolean,Array,Object,Date,Function,Symbol。
class 和 style 特性会稍微智能一些,即两边的值会被合并起来。禁用特性继承
组件的选项中设置 inheritAttrs: false ,适合配合实例的 $attrs 属性使用:
  Vue.component('base-input', {
    inheritAttrs: false,
    props: ['label', 'value'],
    template: `
        <label>
        {{ label }}
        <input
            v-bind="$attrs"
            v-bind:value="value"
            v-on:input="$emit('input', $event.target.value)"
        >
        </label>
    `
    })事件名
不同于组件和 prop,事件名不存在任何自动化的大小写转换。而是触发的事件名需要完全匹配监听这个事件所用的名称:
  this.$emit('myEvent')则监听这个名字的 kebab-case 版本是不会有任何效果的:
  <!-- 没有效果 -->
  <my-component v-on:my-event="doSomething"></my-component>始终使用 kebab-case 的事件名自定义组件的 v-model
  Vue.component('base-checkbox', {
  model: {
      prop: 'checked',
      event: 'change'
  },
  props: {
      checked: Boolean
  },
  template: `
      <input
      type="checkbox"
      v-bind:checked="checked"
      v-on:change="$emit('change', $event.target.checked)"
      >
  `
  })  <base-checkbox v-model="lovingVue"></base-checkbox>将原生事件绑定到组件
使用 v-on 的 .native 修饰符:
  <base-input v-on:focus.native="onFocus"></base-input>Vue 提供了一个 $listeners 属性,它是一个对象,里面包含了作用在这个组件上的所有监听器。可以配合 v-on="$listeners" 将所有的事件监听器指向这个组件的某个特定的子元素。
  Vue.component('base-input', {
  inheritAttrs: false,
  props: ['label', 'value'],
  computed: {
      inputListeners: function () {
      var vm = this
      // `Object.assign` 将所有的对象合并为一个新对象
      return Object.assign({},
          // 我们从父级添加所有的监听器
          this.$listeners,
          // 然后我们添加自定义监听器,
          // 或覆写一些监听器的行为
          {
          // 这里确保组件配合 `v-model` 的工作
          input: function (event) {
              vm.$emit('input', event.target.value)
          }
          }
      )
      }
  },
  template: `
      <label>
      {{ label }}
      <input
          v-bind="$attrs"
          v-bind:value="value"
          v-on="inputListeners"
      >
      </label>
  `
  }).sync 修饰符
以 update:myPropName 的模式触发事件
  this.$emit('update:title', newTitle)  <text-document
  v-bind:title="doc.title"
  v-on:update:title="doc.title = $event"
  ></text-document>缩写:
  <text-document v-bind:title.sync="doc.title"></text-document>同时设置多个 prop :
  <text-document v-bind.sync="doc"></text-document>插槽内容
 <navigation-link url="/profile">
  Your Profile
  </navigation-link><navigation-link> 的模板中:
  <a v-bind:href="url" class="nav-link">
  <slot></slot>
  </a>则Your Profile会替换<slot></slot>部分。Your Profile可以是HTML代码或者其他插件。
编译作用域
父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
  <navigation-link url="/profile">
  Clicking here will send you to: {{ url }}
  <!--
  这里的 `url` 会是 undefined,因为 "/profile" 是
  _传递给_ <navigation-link> 的而不是
  在 <navigation-link> 组件内部定义的。
  -->
  </navigation-link>后备内容(默认值)
  <button type="submit">
    <slot>Submit</slot>
  </button>这里的Submit就是默认值。
具名插槽
<slot> 元素有一个特殊的特性:name。这个特性可以用来定义额外的插槽:
  <div class="container">
  <header>
      <slot name="header"></slot>
  </header>
  <main>
      <slot></slot>
  </main>
  <footer>
      <slot name="footer"></slot>
  </footer>
  </div>一个不带 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> 元素上的特性被称为插槽 prop。现在在父级作用域中,我们可以给 v-slot 带一个值来定义我们提供的插槽 prop 的名字:
  <current-user>
  <template v-slot:default="slotProps">
      {{ slotProps.user.firstName }}
  </template>
  </current-user>独占默认插槽的缩写语法
  <current-user v-slot:default="slotProps">
    {{ slotProps.user.firstName }}
  </current-user>解构插槽 Prop
  <current-user v-slot="{ user }">
    {{ user.firstName }}
  </current-user>动态插槽名
  <base-layout>
  <template v-slot:[dynamicSlotName]>
      ...
  </template>
  </base-layout>具名插槽的缩写
(v-slot:) 替换为字符 # :
其它示例(略)
在动态组件上使用 keep-alive
曾经在一个多标签的界面中使用 is 特性来切换不同的组件:
  <component v-bind:is="currentTabComponent"></component>可以用一个 <keep-alive> 元素将其动态组件包裹起来,避免切换的时候重新渲染:
  <!-- 失活的组件将会被缓存!-->
  <keep-alive>
  <component v-bind:is="currentTabComponent"></component>
  </keep-alive>异步组件(略)
这些特殊场景和危险情况需要留心~
$root属性$parent属性ref特性provide 和 inject。$on(eventName, eventHandler) 侦听一个事件$once(eventName, eventHandler) 一次性侦听一个事件$off(eventName, eventHandler) 停止侦听一个事件$forceUpdatev-once 创建低开销的静态组件原文:https://www.cnblogs.com/huangmengke/p/11656632.html