Vue笔记------ 组件(二)

来源:互联网 发布:软件汉化工具 编辑:程序博客网 时间:2024/06/06 21:39

组件

要注册一个全局组件,你可以使用 Vue.component(tagName, options)。例如:

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

** 注意,对于自定义标签的名称,Vue 不强制要求遵循 W3C 规则(全部小写,必须包含连字符(-)),但是尽量遵循 W3C 规则的约定是比较推荐的做法。


组件在注册过之后,就可以在实例的模板中,以自定义元素 <my-component></my-component> 的方式使用。要确保在 Vue 根实例(root Vue instance)实例化之前,就已经将组件注册完成。

<div id="example">    <my-component></my-component></div>//注册Vue.component('my-component',{    template:"<div>hello!</div>"})//创建一个实例new Vue({    el:"example"})

局部注册

没有必要将每个组件都注册在全局。你可以通过实例的 components 选项,将组件注册在局部,可以使组件只能从其他实例/组件的作用域范围中访问到。

var Child = {    template:"<div>A component!</div>"}new Vue({    // ...    components: {        // 只能在父级模板中使用 <my-component>        'my-component': Child    }})

DOM模板解析说明

当使用 DOM 作为模板时(例如,使用 el 选项,将现有内容挂载到一个元素上),你会受到一些源自 HTML 运行机制的限制,因为 Vue 只有在浏览器解析和标准化 HTML 之后,才可以获取到模板内容。尤其是像 <ul>, <ol>, <table><select> 这样的元素,限制了出现在其中的元素,而像 <option> 这样的元素,只能出现在相应的元素中。

<table>  <my-row>...</my-row></table>

自定义组件 <my-row> 将会被当作无效内容,提升到 table 之外,从而导致最终渲染输出后的错误。解决方案是使用特殊的 is 属性:

<table>  <tr is="my-row"></tr></table>

data必须是一个函数

在组件中,多数的组件选项可以传递给 Vue 构造函数,然后共享于多个组件实例,然而有一个特例:data 必须是一个函数。
因为组件可复用,若不是函数,则变化一个data值会导致其他地方的引用值也跟着变化。

props

在 Vue 中,父子组件之间的关系可以概述为:props 向下,events 向上。父组件通过 props 向下传递数据给子组件,子组件通过 events 发送消息给父组件。让我们来看下它们是如何运行的。

#使用-Props-传递数据
每个组件实例都有自己的孤立隔离作用域。也就是说,不能(也不应该)直接在子组件模板中引用父组件数据。要想在子组件模板中引用父组件数据,可以使用 props 将数据向下传递到子组件。

Vue.component('child', {  // 声明 props  props: ['message'],  // 就像 data 一样,prop 可以在组件模板内部使用,  // 并且,还可以在 vm 实例中通过 this.message 访问  template: '<span>{{ message }}</span>'})<child message="hello!"></child>
  • HTML标签不区分大小写,所以不采用驼峰式命名。串式命名或者连字符分隔。

动态props

类似于将一个普通属性绑定到一个表达式,我们还可以使用 v-bind 将 props 属性动态地绑定到父组件中的数据。无论父组件何时更新数据,都可以将数据向下流入到子组件中:

<div>  <input v-model="parentMsg">  <br>  <child v-bind:my-message="parentMsg"></child></div>

#单向数据流-One-Way-Data-Flow

所有的 props 都是在子组件属性和父组件属性之间绑定的,按照自上而下单向流动方式构成:当父组件属性更新,数据就会向下流动到子组件,但是反过来却并非如此。这种机制可以防止子组件意外地修改了父组件的状态,会造成应用程序的数据流动变得难于推断。

此外,每次父组件更新时,子组件中所有的 props 都会更新为最新值。也就是说,你不应该试图在子组件内部修改 prop。如果你这么做,Vue 就会在控制台给出警告。

诱使我们修改 prop 的原因,通常有两种:

1.prop 只是用于传递初始值,之后子组件想要直接将 prop 作为一个局部数据的属性;
2.prop 作为一个需要转换的原始值传入。

这些场景中,比较合适的应对方式是:
1.定义一个局部数据的属性,将 prop 属性的初始值作为局部属性的初始值:

props: ['initialCounter'],data: function () {    return { counter: this.initialCounter }}

2.定义一个计算属性,从 prop 传入的值来取值:

props: ['size'],computed: {    normalizedSize: function () {        return this.size.trim().toLowerCase()    }}

注意,在 JavaScript 中对象和数组会作为引用类型传入,因此,如果 prop 是一个对象或数组,在子组件内部修改对象或数组自身,将会影响父组件的状态。

prop验证

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

自定义事件

使用 $on(eventName) 监听一个事件

使用 $emit(eventName) 触发一个事件

<div id="counter-event-example">  <p>{{ total }}</p>  <button-counter v-on:increment="incrementTotal"></button-counter>  <button-counter v-on:increment="incrementTotal"></button-counter></div>Vue.component('button-counter', {  template: '<button v-on:click="incrementCounter">{{ counter }}</button>',  data: function () {    return {      counter: 0    }  },  methods: {    incrementCounter: function () {      this.counter += 1      this.$emit('increment')    }  },})new Vue({  el: '#counter-event-example',  data: {    total: 0  },  methods: {    incrementTotal: function () {      this.total += 1    }  }})

为组件绑定原生事件(Binding Native Events to Components)

有时候,你可能希望某个组件的根元素能够监听到原生事件。在这种场景中,你可以在 v-on 后面添加 .native 修饰符。例如:

<my-component v-on:click.native="doTheThing"></my-component>
原创粉丝点击