那么什么是 vue 组件呢? 它是 vue.js 最强大的功能之一, 是可扩展的 html 元素, 是封装可重用的代码, 同时也是 Vue 实例, 可以接受相同的选项对象(除了一些根级特有的选项) 并提供相同的生命周期钩子. 这么说我相信很多人都理解了.
组件系统是 Vue.JS 其中一个重要的概念, 它提供了一种抽象, 让我们可以使用独立可复用的小组件来构建大型应用, 任意类型的应用界面都可以抽象为一个组件树:
那么什么是组件呢?
组件可以扩展 HTML 元素, 封装可重用的 HTML 代码, 我们可以将组件看作自定义的 HTML 元素.
使用组件的好处?
提高开发效率
方便重复使用
简化调试步骤
提升整个项目的可维护性
便于多人协同开发
如何注册组件?
需要使用 Vue.extend 方法创建一个组件, 然后使用 Vue.component 方法注册组件. Vue.extend 方法格式如下
- var MyComponent = Vue.extend({
- // 选项... 后面再介绍
- })
如果想要其他地方使用这个创建的组件, 还得个组件命个名:
Vue.component('my-component', MyComponent)
命名之后即可在 HTML 标签中使用这个组件名称, 像使用 DOM 元素一样. 下面来看看一个完整的组件注册和使用例子.
- //HTML 代码:
- <div id="example">
- <my-component></my-component>
- </div>
- //JS 代码:
- // 定义
- var MyComponent = Vue.extend({
- template: '<div>A custom component!</div>'
- })
- // 注册
- Vue.component('my-component', MyComponent)
- // 创建根实例
- new Vue({
- el: '#example'
- })
输出结果为:
- <div id="example">
- <div>A custom component!</div>
- </div
组件之间的通信
父组件要给子组件传递数据,
子组件需要将它内部发生的事情告诉父组件(利用事件的订阅发布模式)
1. 给子组件的 template 上的元素绑定事件(如 click), 执行子组件的方法(如 changeData), 子组件的方法中发射一个事件(如 s), 传一个数据(如 lalala);
2. 父组件中, 定义一个方法 (如 getData) 用来拿到子组件的数据.
3. 在自定义的组件上绑定子组件传过去的事件 (s), 执行事件(s) 执行的是 getData 函数, getData 函数中拿到数据 (data, 就是子组件传过去的 lalala) 数据同步
- <div id="app">
- <parent></parent>
- </div>
- <template id="parent">
- <div>
- <h1 > 父组件 <mark>{{msg.name}}</mark></h1>
- <children :n="msg"></children>
- </div>
- </template>
- <template id="children">
- <h2 @click="changeData">子组件 {{n.name}}</h2>
- </template>
- <script>
- // 数据同步的核心: 父组件给子组件传递 "引用数据类型的数据";
- var App=new Vue({
- el:'#app',
- components:{
- parent:{
- template:'#parent',
- data(){
- return {msg:{name:'hahha'}}
- },
- components:{
- children:{
- props:['n'],
- template:'#children',
- methods:{
- changeData(){
- this.n.name='lallala'
- },
- }
- }
- }
- }
- }
- })
- </script>//
数据不同步(不直接使用父组件传的值, 用 data 属性再自己的组件内做一个中间变量, 防止报错)
- <parent></parent>
- </div>
- <template id="parent">
- <div>
- <h1 > 父组件 <mark>{{msg}}</mark></h1>
- <children :n="msg"></children>
- </div>
- </template>
- <script>
- // 数据不同步的核心: 中间变量接收避免报错;
- var App=new Vue({
- el:'#app',
- components:{
- parent:{
- template:'#parent',
- data(){
- return {msg:'hahha'}
- },
- components:{
- children:{
- props:['n'],
- template:'<h2 @click="changeData">子组件 {{b}}</h2>',
- data(){
- return {b:this.n}
- },
- methods:{
- changeData(){
- this.b='lallala'
- },
- }
- }
- }
- }
- }
- })// 欢迎加入全栈开发交流群一起学习交流: 864305860
- </script>
组件中的 data 必须是函数
每个组件都是互相独立的, 如果它们共用一个对象,
在更改一个组件数据的时候, 会影响其它组件, 如果是函数的话,
每个组件都有都是又自己独立的数据, 互相不会影响.
受限制的元素
Vue 在浏览器解析和标准化 HTML 后才能获取模板内容,
所以有些元素限制了能被它包裹的元素.
例如: ul 中只能放 li;select 中只能放 option
某些元素中放入了自定义元素,
不符合 W3C 标准, 最终会解析错误.
关于 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 可以忽略这种情况.
结语
来源: http://www.qdfuns.com/article/51117/c9c35f77a45bcad256a332d7297c57c3.html