Vue 组件学习
1.注册组件
1.1 两种注册方法:全局注册和局部注册
局部注册:在父组件文件中import引入组件,只能在父组件内使用
<template>
<div id='app'>
<h1>组件的使用</h1>
<!-- 3.使用组件 -->
<com1 />
</div>
</template>
<script>
//1.引入模板文件
import com1 from './components/comp1/component1'
export default {
name: 'App',
//2.挂载在app.vue上
components: {
com1,
},
}
</script>
<style>
</style>
全局注册:在main.js文件中import引入组件,可全局使用
import { createApp } from 'vue'
import App from './App1.vue'
//引入全局组件
import com3 from './components/comp1/component3'
let app = createApp(App)
//在挂载主模板之前注册组件com3
app.component('com3', com3)
app.mount('#app')
1.2 两种加载方法:同步加载和异步加载
同步加载:直接import引入组件
import keep1 from './components/comp2/keep1'
export default {
name: 'App',
components: {
keep1,
},
}
异步加载:import引入vue中的defineAsyncComponent在components中挂载组件
//vue3.x
defineAsyncComponent(() =>import('./components/comp2/keep2')),
//vue2.x
() =>import('./components/comp2/keep2')
import { defineAsyncComponent } from 'vue'
export default {
name: 'App',
components: {
keep2: defineAsyncComponent(() => import('./components/comp2/keep2')),
},
}
1.3 在模块系统中局部注册
2.切换组件
2.1 component标签切换
<template>
<div id='app'>
<h1>组件的使用</h1>
<input type="button"
value='button'
@click='change'>
<!-- 动态缓存keep-alive标签 -->
<keep-alive>
<!-- component标签(绑定is属性通过组件名称实现切换) -->
<component :is='name'>
</component>
</keep-alive>
</div>
</template>
<script>
import com1 from './components/comp1/component1'
import com2 from './components/comp1/component2'
export default {
name: 'App',
components: {
com1,
com2,
},
methods: {
//切换组件的方法
change() {
this.flag = !this.flag
this.name = this.flag ? 'com1' : 'com2'
},
},
data() {
return {
name: 'com1',
flag: true,
}
},
}
</script>
<style>
</style>
2.2 v-if指令切换
<template>
<div id='app'>
<h1>组件的使用</h1>
<input type="button"
value='button'
@click='change'>
<com1 v-if='flag' />
<com2 v-else />
</div>
</template>
<script>
import com1 from './components/comp1/component1'
import com2 from './components/comp1/component2'
export default {
name: 'App',
components: {
com1,
com2,
},
methods: {
change() {
this.flag = !this.flag
},
},
data() {
return {
name: 'com1',
flag: true,
}
},
}
</script>
<style>
</style>
3.组件传值
3.1 父给子传值
1.子组件元素标签通过v-bind
绑定父组件数据,定义子组件数据名称,属性值为传递给子组件的值
2.子组件通过props
接收数据(props只读,数据名称为字符串)
3.2 子给父传值
1.父组件元素标签绑定自定义事件
2.子组件内创建方法,让子组件内元素执行该方法
3.通过 this.$emit
在子组件内执行父组件自定义事件
this.$emit
参数一:方法名(字符串)
参数二…:传递参数…
// 父组件
<template>
<div id='par'>
父亲组件
{{info}}
<!-- 绑定自定义事件和属性 -->
<child :msg='msg'
@func='send' />
</div>
</template>
<script>
import child from './child'
export default {
name: 'par',
components: {
child,
},
data() {
return {
msg: '父给子传值',
info: '',
}
},
methods: {
send(data) {
this.info = data
},
},
}
</script>
<style>
</style>
//子组件
<template>
<div id='child'>
孩子组件
<input type="text"
v-model='h'>
<!-- 绑定事件 -->
<input type="button"
value='按钮'
@click='send'>
<h3>{{msg}}</h3>
</div>
</template>
<script>
export default {
name: 'child',
//通过props来接收父组件传递的数据
props: ['msg'],
methods: {
send() {
//通过this.$emit执行父组件挂载到子组件标签的自定义方法(func)传递数据
this.$emit('func', this.h)
},
},
data() {
return {
h: '子给父传值',
}
},
}
</script>
<style>
</style>
3.3 props
简单写法
//数据简单接收
props:['title']
复杂写法
//对象复杂接收(限制数据类型)
props: {
// 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
propA: Number,
// 多个可能的类型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
// 带有默认值的数字
propD: {
type: Number,
default: 100
},
// 带有默认值的对象
propE: {
type: Object,
// 对象或数组默认值必须从一个工厂函数获取
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
// 这个值必须匹配下列字符串中的一个
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
3.4 非子父组件传值
1.事件车通信
a.安装event
npm i -S event
b.创建event.js文件
let event = require("events");
let eventEmitter = new event.EventEmitter();
export default eventEmitter
c.main.js引用event.js
//vue3.0中没有app.prototype,添加新的方法使用app.config.globalProperties
import event from './Event/event'
let app = createApp(App)
app.config.globalProperties = {
$events: event
}
d.在同级组件中写入执行代码
emit自动执行并且传递数据
on接收数据
两个方法绑定同一个函数send
来事件非父子组件通信
//传递数据组件
methods: {
sendinfo() {
this.$events.emit('send', this.title)
},
},
//接收数据组件
mounted(){
this.$events.on('send',(args)=>{
this.title=args
})
}
4.插槽(slot)
4.1不具名插槽 (slot1)
4.2具名插槽 v-slot指令的使用(slot2)
4.3 插槽传值(slot3)
//子组件slot1
<template>
<div id='slot1'>
插槽1
<slot>
</slot>
</div>
</template>
<script>
export default {
name: 'slot1',
}
</script>
<style>
</style>
//子组件slot2
<template>
<div id='slot2'>
插槽2
<!-- 绑定name属性 -->
<slot name='comp1'>
</slot>
</div>
</template>
<script>
export default {
name: 'slot2',
}
</script>
<style>
</style>
//子组件slot3
<template>
<div id='slot3'>
插槽3
<ul>
<li
v-for='(item,index) in list'
:key=index>
{{index+1+"."}}
<!-- 绑定item属性 -->
<slot :item='item' name='list'>
</slot>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'slot3',
data() {
return {
list: ['1', '2', '3'],
}
},
}
</script>
<style>
</style>
//父组件
<template>
<div id='app'>
<h1>插槽使用</h1>
<slot1>
<h3>这里是不具名插槽</h3>
</slot1>
<slot2>
<template #comp1>
<h3>这里是具名插槽</h3>
</template>
</slot2>
<slot3>
<template
#list='DataFrom'>
<a
href="#">{{DataFrom.item}}</a>
</template>
</slot3>
</div>
</template>
<script>
import slot1 from './components/comp4/slot1'
import slot2 from './components/comp4/slot2'
import slot3 from './components/comp4/slot3'
export default {
name: 'App',
components: {
slot1,
slot2,
slot3,
},
}
</script>
<style>
</style>