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
},
内容:传参、
触发方法:传参
样式:插槽作用域