1.组件的注册 也分为全局和局部注册, .app也是组件,组件也有父子关系 模板内容 可以用模板字符串`` 1.简单使用: <div id="example"> <!-- 2、 组件使用 组件名称 是以HTML标签的形式使用 --> <my-component></my-component> </div> <script> // 注册组件 // 1、 my-component 就是组件中自定义的标签名 Vue.component('my-component', { template: '<div>A custom component!</div>' }) // 创建根实例 new Vue({ el: '#example' }) </script> ···········注意事项······· 1.组件参数的data值必须是函数同时这个函数要求返回一个对象 data一定是函数,这样就可以形成一个闭包的数据 2.组件模板必须是单个根元素 模板必须是单个根元素如:template :'<button @click="handle">点击了{{count}}次</button>', 3.组件模板的内容可以是模板字符串 但是如果想要两个button标签的话可以加个div,如这样template :'<div><button @click="handle">点击了{{count}}次</button><button>测试</button></div>', 4.命名方式: Vue.component('my-component' OR 'MyComponent', { /* ... */ }) '-'短横线 'hello-world'和驼峰式(大写)'HelloWorld'但是驼峰式只能在字符串模板中`<HelloWorld></HelloWorld>`使用,在普通的标签模板中是错的(即不能在外面直接<HelloWorld></HelloWorld>) 但是驼峰式的标签HelloWorld,可以直接使用短横线式的来调用<hello-world></hello-world>,反之不行 -------------所以最好还是短横线吧---------------------- 2.局部组件的注册 <div id="app"> <my-component></my-component> </div> <script> // 定义组件的模板 var Child = { template: '<div>A custom component!</div>' } new Vue({ //局部注册组件 components: { // <my-component> 将只在父模板可用 一定要在实例上注册了才能在html文件中使用 'my-component': Child } }) </script> 2.工具调试 3.组件间数据交互 1.属性名规则 在props中使用驼峰形式,模板中需要使用短横线的形式 字符串形式的模板中没有这个限制 Vue.component(‘menu-item', { // 在 JavaScript 中是驼峰式的 props: [‘menuTitle'], template: '<div>{{ menuTitle }}</div>' }) <!– 在html中是短横线方式的 --> <menu-item menu-title=“nihao"></menu-item> 2.属性类型 1.字符串 2.数字 传入的时候参数名前要加: 不然传入类型就是string 3.布尔值 同上 4.数组 同上 5.对象 同上 3.父子 props - 父组件发送的形式是以属性的形式绑定值到子组件身上。 - 然后子组件用属性props接收 - 在props中使用驼峰形式,模板中需要使用短横线的形式字符串形式的模板中没有这个限制 静态:<menu-item title="来自父组件的数据"></menu-item> 动态:<menu-item :title="title"></menu-item> 区别在这个':' 经常忘了,气死了!!!! props传递数据原则:单向数据流 只能父--->子 但是子组件能修改和操作父组件传递过来的参数 但是子组件也能向父组件传递信息(父组件中的模板):----->$emit, 触发事件: 子: <button @click='$emit("enlarge-text")'>扩大父组件中字体大小</button> 父: <menu-item :parr='parr' @enlarge-text='fontSize += 5'></menu-item> 父: <menu-item :parr='parr' @enlarge-text='handle'></menu-item> 也可以是方法 传值: $event 子:<button @click='$emit("enlarge-text",0.1)'>扩大父组件中字体大小</button> 父: <menu-item :parr='parr' @enlarge-text='fontSize += $event'></menu-item> 父: <menu-item :parr='parr' @enlarge-text='handle($event)'></menu-item> 也可以是方法 4.兄弟 组件A (监听)<=====>(触发) 事件中心 (触发)<=====>(监听)组件B 1.单独的事件中心管理组件的通信 var eventHub = new Vue() 2. 监听事件与销毁事件 eventHub.$on('add-todo', addTodo) eventHub.$off('add-todo') 3. 触发事件 eventHub.$emit(‘add-todo', id) 5.组件插槽的作用 1. 插槽位置 Vue.component('alert-box', { template: ` <div class="demo-alert-box"> <strong>Error!</strong> <slot></slot> </div> ` }) 2. 插槽内容 <alert-box>Something bad happened.</alert-box> 6.具名插槽用法 1. 插槽定义 <div class="container"> <header> <slot name="header"></slot> <slot name="header"></slot> </header> <main> <slot></slot> </main> <footer> <slot name="footer"></slot> </footer> </div> 2. 插槽内容 <base-layout> <h1 slot="header">标题内容</h1> <p>主要内容1</p> <p>主要内容2</p> <p slot="footer">底部内容</p> </base-layout> 7.作用域插槽 应用场景:父组件对子组件的内容进行加工处理 1. 插槽定义 <ul> <li v-for= "item in list" v-bind:key= "item.id" > <slot v-bind:item="item"> {{item.name}} </slot> </li> </ul> 2. 插槽内容 <fruit-list v-bind:list= "list"> <template slot-scope="slotProps"> <strong v-if="slotProps.item.current"> {{ slotProps.item.text }} </strong> </template> </fruit-list> 9.组件插槽 1.普通插槽 在模板中设定 Vue.component('alert-box',)template=`<slot></slot>` 然后在父组件中使用<alert-box>插入内容</alert-box> 内容就会传到slot中,如果内容带标签也会把对应标签展示出来 <slot>默认内容</slot>中可以有默认内容,如果父组件使用<alert-box>却没插入内容,就会在父组件中显示默认内容 2.具名插槽 插槽定义: Vue.component('base-layout', { template: ` <div> <header> <slot name='header'></slot> </header> <main> <slot></slot> </main> <footer> <slot name='footer'></slot> </footer> </div> ` }); 内容:1. <base-layout> <p slot='header'>标题信息</p> <p>主要内容1</p> <p>主要内容2</p> <p slot='footer'>底部信息信息</p> </base-layout> 2.如果想往同一个name中插入比较多的数据,可以用template <base-layout> <template slot='header'> <p>标题信息1</p> <p>标题信息2</p> </template> <p>主要内容1</p> <p>主要内容2</p> <template slot='footer'> <p>底部信息信息1</p> <p>底部信息信息2</p> </template> </base-layout> 结果就是:标签和内容都会过去 <div> <header> <p>标题信息</p> </header> <main> <p>主要内容1</p> <p>主要内容2</p> </main> <footer> <p>底部信息信息</p> </footer> </div> 3. 插槽作用域 父组件堆子组件的内容进行加工处理,样式也可以 插槽模板:子 Vue.component('fruit-list', { props: ['list'], template: ` <div> <li :key='item.id' v-for='item in list'> <slot :info='item'> {{item.name}} </slot> </li> </div> ` }); 插槽内容:父 <fruit-list :list='list'> <template slot-scope='slotProps'> <strong v-if='slotProps.info.id==2'>{{slotProps.info.name}}</strong> <span v-else>{{slotProps.info.name}}</span> </template> </fruit-list> 案列:购物车 1.event <input type="text" :value='item.num' @blur='change(item.id, $event)'/> 函数可以通过可以通过event来获得Input栏的值 changeNum: function(id, event){ num=event.target.value }, 内容:传参、 触发方法:传参 样式:插槽作用域