组件
Vue 的核心就在于组件。组件的作用就是:复用。
小到一个按钮,大到一个页面都可以是组件
组件的三元素
每一个组件都必须包括三元素
template (用来存放 html)
script (用来写 js)
style (用来写 css)
这里千万注意的是组件必须要大写,我这里是因为格式化所以变小写。实际要大写
特别注意的就是组件外面必须有一个包裹层,否则直接报错误
<template>
<div class="login">
<header></header>
<div class="loginbox_wrap">
<main></main>
</div>
<footer></footer>
</div>
</template>
<script>
import Header from '@/pages/common/Header'
import Footer from '@/pages/common/Footer'
import Main from '@/pages/Login/components/Main'
export default {
data() {
return {
message: '登陆'
}
},
components: {
Header,
Footer,
Main
}
}
</script>
<style lang="less" scoped>
/*mobile*/
@media (max-width: 767px) {
.loginbox_wrap {
width: 100%;
min-height: calc(100vh - 200px - 73px);
background: white;
}
}
/*pad*/
@media (min-width: 768px) and (max-width: 1024px) {
.loginbox_wrap {
width: 100%;
min-height: calc(100vh - 108px - 150px - 50px);
background: #f3f3f3;
padding-top: 50px;
}
}
/*desktop*/
@media (min-width: 1025px) {
.loginbox_wrap {
width: 100%;
min-height: calc(100vh - 108px - 150px - 50px);
background: #f3f3f3;
padding-top: 50px;
}
}
</style>
组件的引入必须有三点
第一步:引入组件(import)
第二步: 注册组件(components)
第三步: 使用组件(自定义标签)
这里千万注意的是组件必须要大写,我这里是因为格式化所以变小写。实际要大写
<header>
<div class="login">
<header></header>
<main></main>
<footer></footer>
</div>
</header>
<script>
import Header from '@/pages/common/Header'
import Footer from '@/pages/common/Footer'
import Main from '@/pages/Login/components/Main'
export default {
data() {
return {
message: '登陆'
}
},
components: {
Header,
Footer,
Main
}
}
</script>
<style lang="less" scoped></style>
组件之间的数据传递
组件之间的数据传递有两种
父子组件
Vuex
总线机制
卡槽
父子组件
父子组件传值就两点
传递数据 props
子组件改变数据
父组件
- 通过绑定:来传递数据,这样就把数据传递过去了,监听子组件传过来的事件,来调用父组件的方法改变值
<template>
<div class="login">
<header></header>
<div class="loginbox_wrap">
<main :info="message" :infoflag="flag" @changeflag="switchflag"></main>
</div>
<footer></footer>
</div>
</template>
<script>
import Header from '@/pages/common/Header'
import Footer from '@/pages/common/Footer'
import Main from '@/pages/Login/components/Main'
export default {
data() {
return {
message: '登陆',
flag: false
}
},
components: {
Header,
Footer,
Main
},
methods: {
switchflag(content) {
this.flag = content
}
}
}
</script>
<style lang="less" scoped></style>
子组件
通过 props 接受数据
发射出一个自定义事件来改变父元素的值,然后传递新的值,子组件永远不能直接改变父元素的值
<template>
<div class="login">
{{info}} ----{{infoflag}}
<button @click="changedata"></button>
</div>
</template>
<script>
export default {
props: ['info', 'infoflag'],
data() {
return {
message: '子组件'
}
},
methods: {
changedata() {
this.$emit('changeflag', true)
}
}
}
</script>
<style></style>
也可以有第二种父元素传递过来的值验证
下面的例子说明 两个值必须要传递进来,一个是数字 一个是布尔
<template>
<div class="login">
{{info}} ----{{infoflag}}
<button @click="changedata"></button>
</div>
</template>
<script>
export default {
props: {
info: {
type: Number,
required: true
},
infoflag: {
type: Boolean,
required: true
}
},
data() {
return {
message: '子组件'
}
},
methods: {
changedata() {
this.$emit('changeflag', true)
}
}
}
</script>
<style></style>
Vue 总线机制
- 总线机制主要是用在爷孙组件或者爷穷孙组件,这样省的一层层发射
第一步创建总线 挂载到 bus 属性上
Vue.prototype.bus = new Vue()
第二步 孙子组件发射出去自定义事件
this.bus.$emit('change', '想改变的值')
第三步 爷爷组件监听此事件
let _this = this
this.bus.$on('change', function(content) {
_this.xxx = content
})
卡槽
- 卡槽的作用就是有的时候我们不想只传递数据,还想传递 html 代码
匿名卡槽(只有一个卡槽,直接找默认)
- 父组件 我想把 div 里面的 html 代码传递给子组件
<template>
<div>
<header></header>
{{ message }}
<Chacaoa>
<div class="sloata">
<p>A里面的数据</p>
</div>
</Chacaoa>
</div>
</template>
<script>
import Header from '@/components/common/Header'
import Chacaoa from '@/components/common/Sloata'
export default {
data() {
return {
message: '首页'
}
},
components: {
Header,
Chacaoa
}
}
</script>
<style lang="less" scoped>
.sloata {
width: 300px;
height: 100px;
background: blue;
color: yellow;
}
</style>
- 子组件
<template>
<div>
<slot></slot>
</div>
</template>
<script>
export default {
data() {
return {
message: '子组件',
dataA: 'dataA里面的数据',
dataB: 'dataB里面的数据'
}
}
}
</script>
<style lang="less" scoped></style>
具名卡槽
卡槽不止一个,需要传递多个 html 代码(署名)
父组件
<template>
<div>
<header></header>
{{ message }}
<Chacaoa>
<div class="sloata" slot="kaocaoa">
<p>A里面的内容</p>
</div>
<div class="sloatb" slot="kaocaob">
<p>B里面的内容</p>
</div>
</Chacaoa>
</div>
</template>
<script>
import Header from '@/components/common/Header'
import Chacaoa from '@/components/common/Sloata'
export default {
data() {
return {
message: '首页'
}
},
components: {
Header,
Chacaoa
}
}
</script>
<style lang="less" scoped>
.sloata {
width: 300px;
height: 100px;
background: blue;
color: yellow;
}
.sloatb {
width: 300px;
height: 100px;
background: red;
color: black;
}
</style>
- 子组件
<template>
<div>
<slot name="kaocaoa"></slot>
<slot name="kaocaob"></slot>
</div>
</template>
<script>
export default {
data() {
return {
message: '子组件',
dataA: 'dataA里面的数据',
dataB: 'dataB里面的数据'
}
}
}
</script>
<style lang="less" scoped></style>
卡槽里面子组件想给父组件传值
只有利用 slot-scope
父组件
<template>
<div>
<header></header>
{{ message }}
<Chacaoa>
<div class="sloata" slot="kaocaoa" slot-scope="shuju1">
<p>{{ shuju1.data }}</p>
</div>
<div class="sloatb" slot="kaocaob" slot-scope="shuju2">
<p>{{ shuju2.data }}</p>
</div>
</Chacaoa>
</div>
</template>
<script>
import Header from '@/components/common/Header'
import Chacaoa from '@/components/common/Sloata'
export default {
data() {
return {
message: '首页'
}
},
components: {
Header,
Chacaoa
}
}
</script>
<style lang="less" scoped>
.sloata {
width: 300px;
height: 100px;
background: blue;
color: yellow;
}
.sloatb {
width: 300px;
height: 100px;
background: red;
color: black;
}
</style>
- 子组件
<template>
<div>
<slot name="kaocaoa" :data="dataA"></slot>
<slot name="kaocaob" :data="dataB"></slot>
</div>
</template>
<script>
export default {
data() {
return {
message: '子组件',
dataA: 'dataA里面的数据',
dataB: 'dataB里面的数据'
}
}
}
</script>
<style lang="less" scoped></style>