组件

全局注册

  • 要注册一个全局组件,可以使用Vue.component(tagName,options)

    Vue.component('my-component', {
    // 选项
    })

  • 组件注册之后,便可以作为自定义元素`

html



js

// 注册
Vue.component('my-component', {
template: '

A custom component!
'
})

// 创建根实例
new Vue({
el: '#example'
})

渲染为html


A custom component!

局部注册

  • 不必把每个组件都注册全局,可以通过某个vue实例/组件的实例选项components注册仅在其作用域中可用的组件

js

var Child = {
template: '

A custom component!
'
}

new Vue({
// ...
components: {
// 将只在父组件模板中可用
'my-component': Child
}
})

组件组合

  • 在vue中,父子组件的关系可以总结为prop向下传递,事件向上传递。父组件通过prop给子组件下发数据,子组件通过事件给父组件发送消息

prop

字面量语法vs动态语法

hhtml


  • 因为它是一个字面量 prop,它的值是字符串 "1" 而不是一个数值。如果想传递一个真正的 JavaScript 数值,则需要使用 v-bind,从而让它的值被当作 JavaScript 表达式计算:

html


prop验证

  • 要指定验证规则,需要用对象的形式来定义prop,而不能用字符串数组:

js

Vue.component('example', {
props: {
// 基础类型检测 (null 指允许任何类型)
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 value > 10
}
}
}
})

type 可以是下面原生构造器:

  • String
  • Number
  • Boolean
  • Function
  • Object
  • Array
  • Symbol(ES6新增了一种数据类型:Symbol,Symbol是用来定义对象的唯一属性名的不二之选;)

type也可以是一个自定义构造函数,使用instanceof检测

  • 当 prop 验证失败,Vue 会抛出警告 (如果使用的是开发版本)。注意 prop 会在组件实例创建之前进行校验,所以在 default 或 validator 函数里,诸如 data、computed 或 methods 等实例属性还无法使用。

自定义事件

  • 我们知道,父组件使用 prop 传递数据给子组件。但子组件怎么跟父组件通信呢?这个时候 Vue 的自定义事件系统就派得上用场了。

使用v-on绑定自定义事件

每个vue实例都实现了事件接口即:

  • 使用$on(eventName)监听事件
  • 使用$emit(eventName,optionalPayload)触发事件

给组件绑定原生事件

  • 想在某个组件的根元素上监听一个原生事件,可以使用v-on的修饰符.native。

动态组件

  • 通过使用保留的 元素,并对其 is 特性进行动态绑定,你可以在同一个挂载点动态切换多个组件:
    js

    var vm = new Vue({
    el: '#example',
    data: {
    currentView: 'home'
    },
    components: {
    home: { /* ... / },
    posts: { /
    ... / },
    archive: { /
    ... */ }
    }
    })

html



  • 也可以直接绑定到组件对象上:

    var Home = {
    template: '

    Welcome home!

    '
    }

    var vm = new Vue({
    el: '#example',
    data: {
    currentView: Home
    }
    })

编写可复用组件

vue组件的API来自三部分---prop,事件和插槽:

  • Prop允许外部环境传递数据给组件
  • 事件允许从组件内触发外部环境的副作用
  • 插槽允许外部环境将额外的内容组合在组件中

子组件引用

  • 尽管有 prop 和事件,但是有时仍然需要在 JavaScript 中直接访问子组件。为此可以使用 ref 为子组件指定一个引用 ID。例如:

html



js

var parent = new Vue({ el: '#parent' })
// 访问子组件实例
var child = parent.$refs.profile

  • $refs 只在组件渲染完成后才填充,并且它是非响应式的。它仅仅是一个直接操作子组件的应急方案——应当避免在模板或计算属性中使用 $refs。

高级异步组件

  • 自 2.3.0 起,异步组件的工厂函数也可以返回一个如下的对象:

    const AsyncComp = () => ({
    // 需要加载的组件。应当是一个 Promise
    component: import('./MyComp.vue'),
    // 加载中应当渲染的组件
    loading: LoadingComp,
    // 出错时渲染的组件
    error: ErrorComp,
    // 渲染加载中组件前的等待时间。默认:200ms。
    delay: 200,
    // 最长等待时间。超出此时间则渲染错误组件。默认:Infinity
    timeout: 3000
    })

组件命名约定

  • 当注册组件 (或者 prop) 时,可以使用 kebab-case (短横线分隔命名)、camelCase (驼峰式命名) 或 PascalCase (单词首字母大写命名)。

    // 在组件定义中
    components: {
    // 使用 kebab-case 注册
    'kebab-cased-component': { /* ... / },
    // 使用 camelCase 注册
    'camelCasedComponent': { /
    ... / },
    // 使用 PascalCase 注册
    'PascalCasedComponent': { /
    ... */ }
    }

内联模板

  • 如果子组件有inline-template特性,组件将把它的内容当作它的模板,而不是把它当作分发内容。这让模板编写起来更灵活

html



这些将作为组件自身的模板。


而非父组件透传进来的内容。



X-Template

  • 另一种定义模板的方式是在JavaScript标签中使用text/x-template类型,并且指定一个id。

html

js

Vue.component('hello-world', {
template: '#hello-world-template'
})

对滴开销的静态组件使用v-once

  • 尽管在 Vue 中渲染 HTML 很快,不过当组件中包含大量静态内容时,可以考虑使用 v-once 将渲染结果缓存起来,就像这样:

    Vue.component('terms-of-service', {
    template: '


    Terms of Service


    ...很多静态内容...

    '
    })

posted @ 2018-03-14 12:16  不完美的完美  阅读(225)  评论(0)    收藏  举报