什么是组件?
?1、组件注册和使用
1、注册全局组件
?方式一:使用全局的Vue直接注册:Vue.component
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 使用自定义的组件 -->
<my-header></my-header>
<h1>{{name}}</h1>
<my-header></my-header>
<h1>{{name}}</h1>
</div>
<script type="text/javascript">
// 创建一个组件对象
const header = {
// 组件中封装的HTML内容
template:`
<div class="header" style="height:100px;background: #FF0000 ;">
<b>python{{headname}}</b>
<b>java{{age}}</b>
</div>`,
// 组件的data是一个函数,数据写在return返回的对象中
data(){
return{
headname:"headers",
age:18,
sex:'nan'
}
},
methods:{
}
}
// 全局组件的注册
Vue.component('my-header',header)
//实例化vue对象
var vm = new Vue({
el:'#app',
data:{
name:'guaniu'
}
})
</script>
</body>
</html>
2、组件的使用
在template中之间使用组件名的闭合标签使用
<my-header></my-header>
3、组件使用的注意点
????????1、组件中的data必须是一个函数,子组件中的数据是独立的
????????2、组件的模板必须要包含一个根元素
????????3、组件中的模板内容可以是字符串的形式
????????4、组件的命名和使用注意点:
????????????????如果组件使用驼峰式命名规则命名(HelloWorld),在字符串模板中,可以使用驼峰式命名规范(HelloWorld)
????????????????在普通的标签模板中使用时,要使用(hello-world)
4、局部组件注册
使用vue实例的components配置项进行注册 注意点:局部组件只能在注册他的父组件中使用
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 使用自定义的组件 -->
<my-header></my-header>
<h1>{{name}}</h1>
<my-header></my-header>
<h1>{{name}}</h1>
</div>
<script type="text/javascript">
// 创建一个组件对象
const header = {
// 组件中封装的HTML内容
template:`
<div class="header" style="height:100px;background: #FF0000 ;">
<b>python{{headname}}</b>
<b>java{{age}}</b>
</div>`,
// 组件的data是一个函数,数据写在return返回的对象中
data(){
return{
headname:"headers",
age:18,
sex:'nan'
}
},
methods:{
}
}
//实例化vue对象
var vm = new Vue({
el:'#app',
data:{
name:'guaniu'
},
// 注册局部组件
components:{
"my-header":header
}
})
</script>
</body>
</html>
2、父组件往子组件中传数据
实现步骤:
????????1、子组件内部定义props接收传递过来的值
????????2、父组件在使用子组件时通过属性将值传递给子组件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<my-box myname='瓜牛' position='高级测试工程师'></my-box>
<my-box myname='瓜牛1' position='高级测试开发工程师'></my-box>
<my-box myname='瓜牛2' position='高级性能测试工程师'></my-box>
</div>
<script type="text/javascript">
const myBox = {
template: `
<div style="width: 400px;height: 300px; box-shadow: 0 0 5px #00AAFF;">
<h1>名字:{{myname}}</h1>
<h1>职位:{{position}}</h1>
</div>
`,
data(){
return{
}
},
// 给子组件定义属性(父组件中传递)
props:[
'myname','position'
]
}
Vue.component('my-box',myBox)
//实例化vue对象
var vm = new Vue({
el:'#app',
data:{
}
})
</script>
</body>
</html>
props传值的注意点:
? ? ? ? 1、子组件中props可以以驼峰形式规则接收参数(使用MenuTitle接收,使用menu-title传递,)
? ? ? ?2、字符串的模板中可以使用驼峰形式,传递参数
? ? ? ?3、非字符串的模板中(父组件)传递值的时候要使用下划线的命名形式(menu-title)
3、子组件往父组件中传数据
????????1、子组件中自定义一个事件
????????????????通过$emit 触发自定义的事件,并分别传入对应的参数。
????????2、在父组件中监听事件
????????监听子组件中定义的事件,当触发事件时,子组件中传递过来的数据,父组件可以通过$event来接收。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!--
子组件中可以通过$emit触发自定义的事件。
父组件时使用子组件时,可以通过事件绑定的形式,去监听子组件中的事件
-->
<my-box @del='handelDel($event)' @update='handelUpdate'></my-box>
<my-box @del='handelDel' @update='handelUpdate'></my-box>
<h1>父组件中的number:{{number}}</h1>
</div>
<script type="text/javascript">
const myBox = {
template: `
<div style="width: 400px;height: 300px; box-shadow: 0 0 5px #00AAFF;">
<h1>名字:{{myname}}</h1>
<h1>职位:{{position}}</h1>
<button @click="$emit('del',200)">删除</button>
<button @click="$emit('update',300)">修改</button>
</div>
`,
data(){
return{
myname:"瓜牛",
position:"高级测试工程师"
}
}
}
Vue.component('my-box',myBox)
//实例化vue对象
var vm = new Vue({
el:'#app',
data:{
number:500
},
methods:{
handelDel(value){
this.number = value
},
handelUpdate(value){
this.number = value
}
}
})
</script>
</body>
</html>
4、兄弟组件之间传数据
实现步骤:
????????1、创建一个全局事件管理中心
// 定义事件中心
var hub = new Vue();
????????2、监听事件: $on
// 组件A中 监听事件
mounted: function () {
??// 事件中心监听事件
??hub.$on('demo2-event', (val) => {
?this.count += val;
})
}
????????3、触发事件:$emit
// 组件B中,触发兄弟组件监听的事件,并传入对应的值
methods: {
??handle: function () {
?hub.$emit('demo2-event', 10);
?}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<my-box1></my-box1>
<my-box2></my-box2>
</div>
<script type="text/javascript">
// 1、创建一个全局的事件中心
var hub = new Vue()
// 定义组件
var myBox1 = {
template: `
<div style="width: 300px;height: 200px;box-shadow: 0 0 5px #55AA7F;">
<h1>显示数据的组件</h1>
<h2>{{value}}</h2>
<button type="button" @click='handel'>box1Event</button>
</div>
`,
data() {
return {
value: 0
}
},
methods: {
handel() {
hub.$emit('box1Eevnt', 9999)
}
},
// 在组件box1中监听事件中的触发事件
mounted() {
hub.$on('changeValue', (val) => {
// 将事件传递过来的数据保存到当前组件中
this.value = val
})
}
}
var myBox2 = {
template: `
<div style="width: 300px;height: 200px;box-shadow: 0 0 5px #55AA7F;">
<h1>选择数据的组件</h1>
<button type="button" @click='selectValue(1000)'>1000</button>
<button type="button" @click='selectValue(2000)'>2000</button>
<button type="button" @click='selectValue(3000)'>3000</button>
<h2>{{value}}</h2>
</div>
`,
data() {
return {
value: 0
}
},
methods: {
// 在组件box2中 触发事件中心的changeValue事件,并传递参数
selectValue(val) {
hub.$emit('changeValue', val)
}
},
mounted() {
hub.$on('box1Eevnt', (val) => {
// 将事件传递过来的数据保存到当前组件中
this.value = val
})
}
}
// 创建一个vue实例
var vm = new Vue({
el: '#app',
data: {},
// 注册组件
components: {
'my-box1': myBox1,
'my-box2': myBox2
},
})
</script>
</body>
</html>
5、插槽
????????插槽的作用:实现父组件往子组件中传递内容
1、组件插槽
????????定义组件时定义插槽
Vue.component('test-demo1', {
????// 组件的模板
????template: `
????<div>
????<span>slot预留一个插槽</span>
????<slot></slot>
????</div>
????`,
?});
?????使用组件时,可以往插槽中传递内容
<test-demo1>
??<h1>往插槽中插入的内容</h1>
</test-demo1>
2、具名插槽
????????定义插槽时,通过name属性给插槽设置一个名字
Vue.component('test-demo1', {
???// 组件的模板
???template: `
????<div>
??????<div class='box1'>
????????<slot name="demo1"></slot>
??????</div>
??????<div class='box2'>
????????<slot name="demo2"></slot>
??????</div>
????</div>
???`,
?});
????????使用组件时,通过slot指定插槽的名字
????????????????注意点:插入多个标签时,通过template来包裹要插入的内容
<div id="app">
??<test-demo1>
????<template slot="demo1">
??????<h1>demo1中插入的h1标签</h1>
??????<h2>demo1中插入的h1标签</h2>
????</template >
????<p slot="demo2">给demo2插入的数据</p>
??</test-demo1>
</div>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<my-box>
<div slot="title">标题</div>
<p>666666</p>
<p>777777</p>
<p>888888</p>
<div slot="footer">footer部分的内容</div>
</my-box>
</div>
<script type="text/javascript">
const myBox = {
template: `
<div style="width: 300px;height: 500px; box-shadow: 0 0 5px #00AAFF;">
<div style="height: 100px;background: #00FFFF;">title:
<slot name='title'></slot></div>
<div style="height: 100px;background: #00aa7f;">
<slot></slot></div>
<div style="height: 100px;background: #ffaa7f;">footer:
<slot name='footer'></slot></div>
</div>
`,
data(){
return{
}
}
}
Vue.component('my-box',myBox)
//实例化vue对象
var vm = new Vue({
el:'#app',
data:{
number:500
},
methods:{
}
})
</script>
</body>
</html>
未完待续,点个关注,持续更新。。。
|