组件的基本使用
注册组件
注册组件就是利用Vue.component()方法,先传入一个自定义组件的名字,然后传入这个组件的配置。
Vue.component('mycomponent',{ template: `<div>这是一个自定义组件</div>`, data () { return { message: 'hello world' } } })
如上方式,就已经创建了一个自定义组件,然后就可以在Vue实例挂在的DOM元素中使用它。
<div> <mycomponent></mycomponent> <my-component></my-component> </div> <script> var app = new Vue({ el: '#app', data: { }, components: { 'my-component': { template: `<div>这是一个局部的自定义组件,只能在当前Vue实例中使用</div>`, } } }) </script>
直接使用Vue.component()创建的组件,所有的Vue实例都可以使用。还可以在某个Vue实例中注册只有自己能使用的组件。
var app = new Vue({ el: '#app', data: { }, components: { 'my-component': { template: `<div>这是一个局部的自定义组件,只能在当前Vue实例中使用</div>`, } } })
模板的要求注意:组件的模板只能有一个根元素。下面的情况是不允许的。
template: `<div>这是一个局部的自定义组件,只能在当前Vue实例中使用</div> <button>hello</button>`,
组件中的data必须是函数可以看出,注册组件时传入的配置和创建Vue实例差不多,但也有不同,其中一个就是data属性必须是一个函数。
这是因为如果像Vue实例那样,传入一个对象,由于JS中对象类型的变量实际上保存的是对象的引用,所以当存在多个这样的组件时,会共享数据,导致一个组件中数据的改变会引起其他组件数据的改变。
而使用一个返回对象的函数,每次使用组件都会创建一个新的对象,这样就不会出现共享数据的问题来了。
关于DOM模板的解析当使用 DOM 作为模版时 (例如,将 el 选项挂载到一个已存在的元素上), 你会受到 HTML 的一些限制,因为 Vue 只有在浏览器解析和标准化 HTML 后才能获取模板内容。尤其像这些元素 <ul>,<ol>,<table>,<select> 限制了能被它包裹的元素,而一些像 <option> 这样的元素只能出现在某些其它元素内部。
在自定义组件中使用这些受限制的元素时会导致一些问题,例如:
<table> <my-row>...</my-row> </table>
自定义组件 <my-row> 被认为是无效的内容,因此在渲染的时候会导致错误。这时应使用特殊的 is 属性:
<table> <tr is="my-row"></tr> </table>
也就是说,标准HTML中,一些元素中只能放置特定的子元素,另一些元素只能存在于特定的父元素中。比如table中不能放置div,tr的父元素不能div等。所以,当使用自定义标签时,标签名还是那些标签的名字,但是可以在标签的is属性中填写自定义组件的名字。
应当注意,如果您使用来自以下来源之一的字符串模板,这些限制将不适用:
<script type="text/x-template">
JavaScript 内联模版字符串
.vue 组件
其中,前两个模板都不是Vue官方推荐的,所以一般情况下,只有单文件组件.vue可以忽略这种情况。
在html中使用元素,会有一些属性,如class,id,还可以绑定事件,自定义组件也是可以的。当在一个组件中,使用了其他自定义组件时,就会利用子组件的属性和事件来和父组件进行数据交流。
<img src="https://www.jb51.net/assets/images/props-events.png"/>
如上如所示,父子组件之间的通信就是 props down,events up,父组件通过 属性props向下传递数据给子组件,子组件通过 事件events 给父组件发送消息。
比如,子组件需要某个数据,就在内部定义一个prop属性,然后父组件就像给html元素指定特性值一样,把自己的data属性传递给子组件的这个属性。
而当子组件内部发生了什么事情的时候,就通过自定义事件来把这个事情涉及到的数据暴露出来,供父组件处理。
<my-component v-bind:foo="baz" v-on:event-a="doThis(arg1,...arg2)"></my-component>
如上代码,
foo是<my-component>组件内部定义的一个prop属性,baz是父组件的一个data属性,
event-a是子组件定义的一个事件,doThis是父组件的一个方法
过程就是这样:
父组件把baz数据通过prop传递给子组件的foo;
子组件内部得到foo的值,就可以进行相应的操作;
当子组件内部发生了一些变化,希望父组件能知道时,就利用代码触发event-a事件,把一些数据发送出去
父组件把这个事件处理器绑定为doThis方法,子组件发送的数据,就作为doThis方法的参数被传进来
然后父组件就可以根据这些数据,进行相应的操作
Vue组件通过props属性来声明一个自己的属性,然后父组件就可以往里面传递数据。