Vue及Element UI&vue-element-admin简记

文章目录

    • 概念
      • 索引
      • 安装vue
      • API
    • 基本语法
      • 声明式渲染
        • 动态参数
      • 表单输入绑定
      • 数据绑定中进行数据处理
        • 使用JS表达式
        • 计算属性
        • 侦听器
      • Class 与 Style 的数据绑定
        • Class的数据绑定
        • Style的数据绑定
      • 条件与循环
        • 条件渲染
          • v-if指令
          • v-show指令
        • 列表(数组)渲染
      • 数据更新检测
      • 事件监听器
      • 修饰符
        • 事件修饰符
        • 按键修饰符
          • 按键码
        • 系统修饰键
      • 指令的缩写
      • 组件
        • 注册组件
        • 组件名和Prop名
        • 局部注册
        • 在模块系统中局部注册
        • 自动化全局注册
        • Prop
        • 组件的数据
          • v-model
          • .async
          • 插槽
        • 组件的事件
        • is特性和动态组件
        • 异步组件
        • 组件构建应用
      • vue实例
      • 实例生命周期的钩子
      • 模板语法
    • 高级语法
      • 组件相关的边界情况
      • 过渡 & 动画
      • 混入
      • 自定义指令
      • 渲染函数 & JSX
      • 插件
      • 过滤器
      • 工具
        • 单文件组件
        • 单元测试
        • TypeScript 支持
        • 生产环境部署
      • 深入响应式原理
    • 热点问题
      • 风格指南
      • 在 VS Code 中调试
      • 客户端存储
      • Devtools
      • Vue CLI
      • Vue Loader
      • Vue Router
        • 基本介绍
        • 路由匹配
        • 编程式导航
        • 重定向和别名
        • HTML5 History 模式
      • Vuex
      • Vue SSR
    • axios
      • 介绍
      • 发送请求
      • 请求配置
      • 响应结构
      • 错误处理
      • 使用 application/x-www-form-urlencoded format
      • 其他API和功能特性
    • Element
    • vue-element-admin
      • 介绍
        • 模块组成
        • 功能介绍
        • 项目的目录结构
        • 安装
      • 中文
      • 布局
      • 路由和侧边栏
      • 权限验证
      • 快捷导航(标签栏导航)
      • 新增一个页面
      • 样式
      • 和服务端进行交互
      • Mock Data
      • 构建,发布和环境变量
      • 其他
    • 相关概念
      • HTML DOM
      • Node.js
      • NPM
      • Modern JavaScript with ES2015/16
      • AMD规范,commonJS规范,和CMD规范
      • JSX和React
      • Flux和Redux
      • TypeScript
      • webpack
      • Babel
      • REPL
      • SSR
      • Git Hooks
      • Promise

概念

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动。

Vue 不支持 IE8 及以下版本,因为 Vue 使用了 IE8 无法模拟的 ECMAScript 5 特性。但它支持所有兼容 ECMAScript 5 的浏览器。

索引

官网:https://vuejs.org
中文官网:https://cn.vuejs.org
API:https://cn.vuejs.org/v2/api/

安装vue

在线使用:





安装教程:https://cn.vuejs.org/v2/guide/installation.html

可以直接下载并使用

动态参数

从 2.6.0 开始,可以用方括号括起来的 JavaScript 表达式作为一个指令的参数:


 ... 

表单输入绑定

v-model 指令,它能轻松实现表单输入和应用状态之间的双向绑定。

v-model 会忽略所有表单元素的 value、checked、selected 特性的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的 data 选项中声明初始值。

{{ message }}

v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件:

  • text 和 textarea 元素使用 value 属性和 input 事件;
  • checkbox 和 radio 使用 checked 属性和 change 事件;(单个复选框,绑定到布尔值;多个复选框,绑定到同一个数组)
  • select 字段将 value 作为 prop 并将 change 作为事件。

自定义输入组件也可以使用v-model。

model可以使用.lazy,.number,.trim修饰符。









数据绑定中进行数据处理

使用JS表达式

对于所有的数据绑定,Vue.js 都提供了完全的 JavaScript 表达式支持:


{{ number + 1 }}

{{ ok ? 'YES' : 'NO' }}

{{ message.split('').reverse().join('') }}

{{ var a = 1 }} {{ if (ok) { return message } }}

计算属性

模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。对于任何复杂逻辑,你都应当使用计算属性。

Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。然而,通常更好的做法是使用计算属性而不是命令式的 watch 回调。

Original message: "{{ message }}"

Computed reversed message: "{{ reversedMessage }}"

我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。
然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。
相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。

Reversed message: "{{ reversedMessage() }}"

计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter:

computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter,现在再运行 vm.fullName = 'John Doe' 时,setter 会被调用,vm.firstName 和 vm.lastName 也会相应地被更新。
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}

侦听器

虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。

当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。

Ask a yes/no question:

{{ answer }}

Class 与 Style 的数据绑定

在将 v-bind 用于 class 和 style 时,Vue.js 做了专门的增强。表达式结果的类型除了字符串之外,还可以是对象或数组。

Class的数据绑定

  1. 我们可以传给 v-bind:class 一个对象,以动态地切换 class。
  2. 可以在这个对象中传入更多属性来动态切换多个 class。
  3. v-bind:class 指令也可以与普通的 class 属性共存。
  4. 绑定的数据对象不必内联定义在模板里。
  5. 也可以在v-bind:class 指令中绑定一个返回对象的计算属性。
  6. 我们可以把一个数组传给 v-bind:class,以应用一个 class 列表。
  7. 可以在数组中,结合使用对象语法。
  8. 当在一个自定义组件上使用 class 属性时,这些 class 将被添加到该组件的根元素上面。这个元素上已经存在的 class 不会被覆盖。

Style的数据绑定

  1. v-bind:style 的对象语法十分直观——看着非常像 CSS,但其实是一个 JavaScript 对象。
  2. 绑定的数据对象不必内联定义在模板里。
  3. 对象语法常常结合返回对象的计算属性使用。
  4. v-bind:style 的数组语法可以将多个样式对象应用到同一个元素上。
  5. 当 v-bind:style 使用需要添加浏览器引擎前缀的 CSS 属性时,如 transform,Vue.js 会自动侦测并添加相应的前缀。
  6. 从 2.3.0 起你可以为 style 绑定中的属性提供一个包含多个值的数组,常用于提供多个带前缀的值。

条件与循环

条件渲染

v-if指令

条件使用v-if指令:
(注:永远不要把 v-if 和 v-for 同时用在同一个元素上。)

现在你看到我了

因为 v-if 是一个指令,所以必须将它添加到一个元素上。如果想切换多个元素,可以把一个 元素当做不可见的包裹元素,并在上面使用 v-if。最终的渲染结果将不包含 元素。


可以使用 v-else 指令来表示 v-if 的“else 块”。
2.1.0 新增 v-else-if 。

Now you see me
Now you don't

Vue 会尽可能高效地渲染元素,通常会复用已有元素而不是从头开始渲染。
Vue 为你提供了一种方式来表达“这两个元素是完全独立的,不要复用它们”。只需添加一个具有唯一值的 key 属性即可:





v-show指令

v-show:带有 v-show 的元素始终会被渲染并保留在 DOM 中。v-show 只是简单地切换元素的 CSS 属性 display。
v-show 不支持 元素。

Hello!

对比 vi-if:

  1. v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。
  2. v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
  3. v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。

v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

列表(数组)渲染

循环使用v-for指令。
我们可以用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法,其中 items 是源数据数组,而 item 则是被迭代的数组元素的别名。

  1. {{ todo.text }}

v-for 还支持一个可选的第二个参数,即当前项的索引。

  • ...
  • 也可以用 of 替代 in 作为分隔符,因为它更接近 JavaScript 迭代器的语法:

    也可以用 v-for 来遍历一个对象的属性。
    在遍历对象时,会按 Object.keys() 的结果遍历,但是不能保证它的结果在不同的 JavaScript 引擎下都一致。

    • {{ value }}

    建议尽可能在使用 v-for 时提供 key attribute,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素。
    如果不指定key,默认使用“就地更新”的策略。如果数组中数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素。

    我们想要显示一个数组经过过滤或排序后的版本,而不实际改变或重置原始数据。在这种情况下,可以在 v-for 中使用计算属性或者方法。例如:n in computedVar/method()

    v-for 也可以接受整数。在这种情况下,它会把模板重复对应次数。例如:v-for="n in 10"

    可以利用带有 v-for 的 来循环渲染一段包含多个元素的内容。

    在自定义组件上,你可以像在任何普通元素上一样使用 v-for 。2.2.0+ 的版本里,当在组件上使用 v-for 时,key 现在是必须的。
    然而,任何数据都不会被自动传递到组件里,因为组件有自己独立的作用域。为了把迭代数据传递到组件里,我们要使用 prop:

    
    

    数据更新检测

    Vue 将被侦听的数组的变异方法(mutation method,变异方法,顾名思义,会改变调用了这些方法的原始数组,例如:push(), pop(), shift(), splice(), unshift(), sort(), reverse() )进行了包裹,所以它们也将会触发视图更新。
    非变异 (non-mutating method) 方法,例如 filter()、concat() 和 slice() 。它们不会改变原始数组,而总是返回一个新数组。当使用非变异方法时,可以用新数组替换旧数组。Vue 为了使得 DOM 元素得到最大范围的重用而实现了一些智能的启发式方法,所以用一个含有相同元素的数组去替换原来的数组是非常高效的操作。

    注意:当你利用索引直接设置一个数组项时,或者当你修改数组的长度时,Vue 并不能检测到数组的变动:

    var vm = new Vue({
      data: {
        items: ['a', 'b', 'c']
      }
    })
    vm.items[1] = 'x' // 不是响应性的,使用 Vue.set(vm.items, indexOfItem, newValue) 或者 vm.items.splice(indexOfItem, 1, newValue) 代替,也可以使用 vm.$set 实例方法,该方法是全局方法 Vue.set 的一个别名:vm.$set(vm.items, indexOfItem, newValue)
    vm.items.length = 2 // 不是响应性的,使用 vm.items.splice(newLength) 代替
    

    Vue 不能检测对象属性的添加或删除:

    var vm = new Vue({
      data: {
        a: 1,
        userProfile: {
          name: 'Anika'
        }
      }
    })
    // `vm.a` 现在是响应式的
    
    vm.b = 2
    // `vm.b` 不是响应式的
    
    // 对于已经创建的实例,Vue 不允许动态添加根级别的响应式属性,例如上例中的b。但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式属性。
    // 还可以使用 vm.$set 实例方法,它只是全局 Vue.set 的别名:vm.$set(vm.userProfile, 'age', 27)
    Vue.set(vm.userProfile, 'age', 27)
    
    // 为已有对象赋值多个新属性,应该用两个对象的属性创建一个新的对象
    vm.userProfile = Object.assign({}, vm.userProfile, {
      sex: 'female',
      favoriteColor: 'Vue Green'
    })
    

    事件监听器

    用 v-on 指令添加一个事件监听器,通过它调用在 Vue 实例中定义的方法:

    {{ message }}

    所有的 Vue.js 事件处理方法和表达式都严格绑定在当前视图的 ViewModel 上,它不会导致任何维护上的困难。使用 v-on 有几个好处:

    1. 扫一眼 HTML 模板便能轻松定位在 JavaScript 代码里对应的方法。
    2. 因为你无须在 JavaScript 里手动绑定事件,你的 ViewModel 代码可以是非常纯粹的逻辑,和 DOM 完全解耦,更易于测试。
    3. 当一个 ViewModel 被销毁时,所有的事件处理器都会自动被删除。你无须担心如何清理它们。

    修饰符

    修饰符 (modifier) 是以半角句号 . 指明的特殊后缀,用于指出一个指令应该以特殊方式绑定。

    
    
    ...

    事件修饰符

    Vue.js 为 v-on 提供了事件修饰符,专门去处理 DOM 事件细节。
    支持:.stop, .prevent, .capture, .self, .once(2.1.4 新增), .passive(2.3.0 新增)。
    .once 修饰符还能被用到自定义的组件事件上,其它只能对原生的 DOM 事件起作用。

    
    
    
    
    
    ...
    ...
    ...

    按键修饰符

    Vue 允许为 v-on 在监听键盘事件时添加按键修饰符。其中按键名称参见:https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values

    
    
    
    按键码

    为了在必要的情况下支持旧浏览器,Vue 提供了绝大多数常用的按键码的别名:.enter,.tab,.delete (捕获“删除”和“退格”键),.esc,.space,.up,.down,.left,.right。推荐优先使用别名。
    你还可以通过全局 config.keyCodes 对象自定义按键修饰符别名:

    // 可以使用 `v-on:keyup.f1`
    Vue.config.keyCodes.f1 = 112
    

    系统修饰键

    可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器:.ctrl,.alt,.shift,.meta(在 Mac 系统键盘上,meta 对应 command 键 (⌘)。在 Windows 系统键盘 meta 对应 Windows 徽标键 (⊞)。)(前面均为2.1.0 新增),.exact(2.5.0 新增),.left,.right,.middle(2.2.0 新增)

    
    
    
    
    
    Do something

    指令的缩写

    Vue 为 v-bind 和 v-on 这两个最常用的指令,提供了特定简写:

    
    ...
    
    ...
    
    
    ...
    
    ...
    

    组件

    在 Vue 里,一个组件本质上是一个拥有预定义选项的一个 Vue 实例。每用一次组件,就会有一个它的新实例被创建。

    组件系统是 Vue 的另一个重要概念,因为它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用。

    Vue的组件和原生自定义组件并不相同,具体参见:https://cn.vuejs.org/v2/guide/index.html#与自定义元素的关系

    注册组件

    在 Vue 中注册组件很简单:

    为了能在模板中使用,这些组件必须先注册以便 Vue 能够识别。这里有两种组件的注册类型:全局注册和局部注册。
    全局注册的组件可以用在其被注册之后的任何 (通过 new Vue) 新创建的 Vue 根实例,也包括其组件树中的所有子组件的模板中。

    // 全局注册。
    Vue.component('component-a', { /* ... */ })
    Vue.component('component-b', { /* ... */ })
    Vue.component('component-c', { /* ... */ })
    // 其后的vue实例,其对应的组件树
    中所有子组件都可以使用 new Vue({ el: '#app' })

    可以使用 JavaScript 的模板字符串来让多行的模板更易读。
    模板字符串使用反引号 () 来代替普通字符串中的用双引号和单引号。在模版字符串内使用反引号(`)时,需要在它前面加转义符(\)。
    模板字符串在 IE 下并没有被支持,所以如果你需要在不 (经过 Babel 或 TypeScript 之类的工具) 编译的情况下支持 IE,请使用折行转义字符取而代之。

    Vue.component('blog-post', {
      props: ['post'],
      template: `
        

    {{ post.title }}

    ` })

    组件名和Prop名

    组件名,推荐遵循 W3C 规范中的自定义组件名 (字母全小写且必须包含一个连字符)。这会帮助你避免和当前以及未来的 HTML 元素相冲突。

    推荐使用 kebab-case (短横线分隔命名) 定义一个组件,例如
    当使用 PascalCase (首字母大写命名) 定义一个组件时,你在引用这个自定义元素时两种命名法都可以使用。也就是说 都是可接受的。注意,尽管如此,直接在 DOM (即非字符串的模板) 中使用时只有 kebab-case 是有效的。

    Prop名也是一样。HTML 中的特性名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名。

    局部注册

    全局注册所有的组件意味着即便你已经不再使用一个组件了,它仍然会被包含在你最终的构建结果中。这造成了用户下载的 JavaScript 的无谓的增加。

    局部注册方式:

    // 定义组件
    var ComponentA = { /* ... */ }
    var ComponentB = { /* ... */ }
    var ComponentC = { /* ... */ }
    
    new Vue({
      el: '#app',
      components: {
        // 对于 components 对象中的每个属性来说,其属性名就是自定义元素的名字,其属性值就是这个组件的选项对象
        'component-a': ComponentA,
        'component-b': ComponentB
      }
    })
    

    注意,局部注册的组件在其子组件中不可用。

    // 如果希望 ComponentA 在 ComponentB 中可用:
    var ComponentA = { /* ... */ }
    
    var ComponentB = {
      components: {
        'component-a': ComponentA
      },
      // ...
    }
    

    在模块系统中局部注册

    我们推荐创建一个 components 目录,并将每个组件放置在其各自的文件中。然后,在局部注册之前导入每个你想使用的组件。

    // ComponentB.vue 文件
    import ComponentA from './ComponentA'
    import ComponentC from './ComponentC'
    
    export default {
      components: {
        // 让 ComponentA 和 ComponentC 都可以在 ComponentB 的模板中使用:
        ComponentA,
        ComponentC
      },
      // ...
    }
    

    自动化全局注册

    示例代码:

    import Vue from 'vue'
    import upperFirst from 'lodash/upperFirst'
    import camelCase from 'lodash/camelCase'
    
    const requireComponent = require.context(
      // 其组件目录的相对路径
      './components',
      // 是否查询其子目录
      false,
      // 匹配基础组件文件名的正则表达式
      /Base[A-Z]\w+\.(vue|js)$/
    )
    
    requireComponent.keys().forEach(fileName => {
      // 获取组件配置
      const componentConfig = requireComponent(fileName)
    
      // 获取组件的 PascalCase 命名
      const componentName = upperFirst(
        camelCase(
          // 获取和目录深度无关的文件名
          fileName
            .split('/')
            .pop()
            .replace(/\.\w+$/, '')
        )
      )
    
      // 全局注册组件:全局注册的行为必须在根 Vue 实例 (通过 new Vue) 创建之前发生
      Vue.component(
        componentName,
        // 如果这个组件选项是通过 `export default` 导出的,
        // 那么就会优先使用 `.default`,
        // 否则回退到使用模块的根。
        componentConfig.default || componentConfig
      )
    })
    

    Prop

    可以以对象形式列出 prop,这些属性的名称和值分别是 prop 各自的名称和类型:

    props: {
      title: String,
      likes: Number,
      isPublished: Boolean,
      commentIds: Array,
      author: Object,
      callback: Function,
      contactsPromise: Promise // or any other constructor
    }
    

    使用Prop时也可以传入任何类型:

    
    
    
    
    
    
    
    post: {
      id: 1,
      title: 'My Journey with Vue'
    }
    
    
    
    

    所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。
    额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。
    这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。注意,在 JavaScript 中对象和数组是通过引用传入的,所以对于一个数组或对象类型的 prop 来说,在子组件中改变这个对象或数组本身将会影响到父组件的状态。

    如果确实需要在子组件使用父组件的Prop属性,有2个建议的方法:

    // 这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。在这种情况下,最好定义一个本地的 data 属性并将这个 prop 用作其初始值:
    props: ['initialCounter'],
    data: function () {
      return {
        counter: this.initialCounter
      }
    }
    
    // 这个 prop 以一种原始的值传入且需要进行转换。在这种情况下,最好使用这个 prop 的值来定义一个计算属性:
    props: ['size'],
    computed: {
      normalizedSize: function () {
        return this.size.trim().toLowerCase()
      }
    }
    

    可以为组件的 prop 指定验证要求,为了定制 prop 的验证方式,你可以为 props 中的值提供一个带有验证需求的对象,而不是一个字符串数组。
    当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告。

    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
          }
        }
      }
    })
    

    组件可以接受任意的特性,而这些特性会被添加到这个组件的根元素上。
    对于绝大多数特性来说,从外部提供给组件的值会替换掉组件内部设置好的值。
    class 和 style 特性会稍微智能一些,即两边的值会被合并起来:

    
    
    
    
    
    

    如果你不希望组件的根元素继承特性,你可以在组件的选项中设置 inheritAttrs: false。
    注意, inheritAttrs: false 选项不会影响 style 和 class 的绑定。

    Vue.component('base-input', {
      inheritAttrs: false,
      props: ['label', 'value'],
      template: `
        
      `
    })
    

    组件的数据

    一个组件的 data 选项必须是一个函数,因此每个实例可以维护一份被返回对象的独立的拷贝:

    // 定义一个名为 button-counter 的新组件
    Vue.component('button-counter', {
      data: function () {
        return {
          count: 0
        }
      },
      template: ''
    })
    
    v-model

    自定义事件也可以用于创建支持 v-model 的自定义输入组件。需要组件内的满足以下条件:

    • 将其 value 特性绑定到一个名叫 value 的 prop 上
    • 在其 input 事件被触发时,将新的值通过自定义的 input 事件抛出
    
    
    等价于:
    
    
    
    
    等价于:
    
    所以,组件要支持:
    Vue.component('custom-input', {
      props: ['value'],
      template: `
        
      `
    })
    

    一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框、复选框等类型的输入控件可能会将 value 特性用于不同的目的。model 选项可以用来避免这样的冲突:

    Vue.component('base-checkbox', {
      model: {
        // 必须声明 checked 这个 prop
        prop: 'checked',
        event: 'change'
      },
      props: {
        checked: Boolean
      },
      template: `
        
      `
    })
    
    .async

    使用 .sync 修饰符对一个 prop 进行“双向绑定”。类似 v-model,带有 .sync 修饰符的 v-bind 不能和表达式一起使用,只能提供你想要绑定的属性名。

    
    
    
    
    
    
    插槽

    通过插槽方式使用数据,插槽内可以包含任何模板代码,包括 HTML。

    
    
      
      
      Something bad happened.
    
    
    Vue.component('alert-box', {
      template: `
        
    Error!
    ` })

    父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
    插槽跟模板的其它地方一样可以访问相同的实例属性 (也就是相同的“作用域”),而不能访问所属组件的作用域。

    为了让 属性 在父级的插槽内容中可用,我们可以将 该属性 作为 元素的一个特性绑定上去。绑定在 元素上的特性被称为插槽 prop。

    
      Clicking here will send you to: {{ url }}
      
    
    
    
    
      
        {{ user.lastName }}
      
    
    
    
      
      
    
    
    
    
      {{ user.firstName }}
    
    

    通过具名插槽的方式来使用多个插槽。
    v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。例如 v-slot:header 可以被重写为 #header。
    同理,v-slot:default=“slotProps” 可以缩写为 #default=“slotProps”。

    
    

    A paragraph for the main content.

    组件的事件

    子组件可以通过调用内建的 $emit 方法 并传入事件名称来触发一个事件;
    注:事件名不存在任何自动化的大小写转换。而是触发的事件名需要完全匹配监听这个事件所用的名称。并且, v-on 事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以 v-on:myEvent 将会变成 v-on:myevent——导致 myEvent 不可能被监听到。因此,推荐你始终使用 kebab-case 的事件名。
    父级组件可以像处理 native DOM 事件一样通过 v-on 监听子组件实例的任意事件。

    Vue.component('blog-post', {
      props: ['post'],
      template: `
        

    {{ post.title }}

    ` })

    可以使用 $emit 的第二个参数来使用事件抛出一个值;
    当在父级组件监听这个事件的时候,可以通过 $event 访问到被抛出的这个值。

    
    
    
    
    
    
    
    

    想要在一个组件的根元素上直接监听一个原生事件。这时,你可以使用 v-on 的 .native 修饰符:

    
    

    Vue 提供了一个 $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: `
        
      `
    })
    

    is特性和动态组件

    使用is特性可以在不同组件之间进行动态切换:

    
    
    
    
    
    
      
    
    

    有些元素,诸如

  • 、 和