组件 语法(组件创建,组件通信)
1、为什么要使用组件
- 就是同一个样式或者功能,实现不同地方的复用,各自独立,便于复用
- 组件四个步骤:
- 1:创建组件
- 2:引入组件
- 3:注册组件
- 4:使用组件
<template>
<div>
//使用组件
<Panel></Panel><hr>
<Panel></Panel><hr>
<Panel></Panel>
</div>
</template>
<script>
//引入组件
import Panel from './components/Panel.vue'
export default{
name:'',
//注册组件
components:{
Panel
},
data () {
return {
}
},
created () {
},
computed:{
},
methods:{
}
}
</script>
<style lang='less' scoped>
</style>
介绍一点注册全局组件的方法: 在main.js中,引入
- import Panel from './components/Panel.vue'
- 注册 Vue.component("Panel",Panel)
2、 组件的scoped的使用和原理
- 什么是scoped
- 在Vue组件内样式,只针对当前组件内标签生效如何做
- style上添加scoped
<style lang='less' scoped> </style>
原理:他做了两件事- 1 scoped给当前组件内标签都被添加了data-v-hash值得属性
- 2:css选择器都被添加了[data-v-hash]的属性选择器。
3、组件的通信
3.1、父向子传递
props
<template>
<div>
<Panel :str='str'></Panel>
</div>
</template>
============父组件
============子组件
<template>
<div>
<h1>{{str}}</h1>
</div>
</template>
<script>
export default{
name:'',
props:{
str:{
type:String,
default:''
}
},
}
</script>
<style lang='less' scoped>
</style>
3.2 、子向父传值
- 使用自定义事件
- 1:在父组件中给子组件绑定自定义事件
- 2:当子组件执行$emit触发父组件事件时,父组件的事件处理函数会执行。
- 注:this.$emit 方法触发父组件绑定的自定义事件,他有两个参数
- 参数1:事件名
- 参数2:要传递过去的参数
============================子组件
<template>
<div>
<h1>{{str}}</h1>
<button @click="btn">点我修改父组件的值</button>
</div>
</template>
<script>
export default{
name:'',
props:{
str:{
type:String,
default:''
}
},
methods:{
btn(){
this.$emit("dome","大河之水天上来")
}
}
}
</script>
<style lang='less' scoped>
</style>
==============================父组件
<template>
<div>
<Panel :str='str' @dome="upDome"></Panel>
<h1>{{str}}</h1>
</div>
</template>
<script>
import Panel from './components/Panel.vue'
export default{
name:'',
components:{
Panel
},
data () {
return {
str:'窗前明月光'
}
},
created () {
},
computed:{
},
methods:{
upDome(str){
this.str=str
}
}
}
</script>
<style lang='less' scoped>
</style>
4、 单向数据流
- 问题:当我们子组件接收到了父组件传过来的值,能不能不用自定义事件来,我们能否在子组件这边直接修改他的值呢,
- 答案就是:不能
- 原理:从父到子的数据流向,叫单向数据,在Vue中规定,不能直接修改父组件的值,原因就是假设在项目中这个值如果在很多子组件都用到了,各个子组件都在改这个值,一旦这个值出了问题就很排查,数据管理起来很混乱。
5 组件的插槽的使用
- 为什么要使用插槽 可以让组件内容自定义,极大的提高组件的灵活性
- 插槽分为
- 匿名插槽
- 具名插槽
- 作用域插槽
5.1、 匿名插槽的使用
<slot></slot> 占位符使用
-
1 在组件内找到需要插槽的地方,使用占位
-
2:在使用组件是,将要自定的标签传入组件中
子组件
<template>
<div>
<h1>李白</h1>
<!-- slot占位符 -->
<slot></slot>
</div>
</template>
<script>
export default{
name:'Panel',
data () {
return {
}
},
created () {
},
computed:{
},
methods:{
}
}
</script>
<style lang='less' scoped>
</style>
父组件
<template>
<div>
<Panel>
<h3>窗前明月光</h3>
<h3>疑是地上</h3>
<h3>举头望明月</h3>
<h3>低头思故乡</h3>
</Panel><hr>
<Panel>
<h3>日照香炉生紫烟</h3>
<h3>遥看瀑布挂前川</h3>
<h3>飞流直下三千尺</h3>
<h3>疑是银河落九天</h3>
</Panel><hr>
<Panel>
<h3>故人西辞黄鹤楼</h3>
<h3>烟花三月下扬州</h3>
<h3>孤帆远影碧空尽</h3>
<h3>唯见长江天际流</h3>
</Panel>
</div>
</template>
<script>
import Panel from './components/Panel.vue'
export default{
name:'',
components:{
Panel
},
data () {
return {
}
},
}
</script>
<style lang='less' scoped>
</style>
5.2、 默认内容
- 什么是默认内容
- 就是使用我组件的人,不给slot传标签,就是把slot标签里面的内容当做默认内容 父组件
<template>
<div>
<Panel>
<h3>窗前明月光</h3>
<h3>疑是地上</h3>
<h3>举头望明月</h3>
<h3>低头思故乡</h3>
</Panel><hr>
<Panel>
<h3>日照香炉生紫烟</h3>
<h3>遥看瀑布挂前川</h3>
<h3>飞流直下三千尺</h3>
<h3>疑是银河落九天</h3>
</Panel><hr>
<Panel>
<h3>故人西辞黄鹤楼</h3>
<h3>烟花三月下扬州</h3>
<h3>孤帆远影碧空尽</h3>
<h3>唯见长江天际流</h3>
</Panel>
<Panel></Panel>
</div>
</template>
<script>
import Panel from './components/Panel.vue'
export default{
name:'',
components:{
Panel
},
data () {
return {
}
},
created () {
},
computed:{
},
methods:{
}
}
</script>
<style lang='less' scoped>
</style>
子组件
<template>
<div>
<h1>李白</h1>
<!-- slot占位符 -->
<slot>
<h1>默认内容</h1>
</slot>
</div>
</template>
<script>
export default{
name:'Panel',
data () {
return {
}
},
created () {
},
computed:{
},
methods:{
}
}
</script>
<style lang='less' scoped>
</style>
5.3、具名插槽的使用
具名插槽的基本使用
1:在组件内给slot设置name属性
2:在使用组件时,通过template包裹不同区域的代码
3:在template标签上使用v-slot名称,来指定name
4:v-slot:可以简写#
父组件
<template>
<div>
<Panel>
<template v-slot:title>
<h1>静夜思---李白</h1>
</template>
<template #content>
<h3>窗前明月光</h3>
<h3>疑是地上</h3>
<h3>举头望明月</h3>
<h3>低头思故乡</h3>
</template>
</Panel><hr>
<Panel>
<template v-slot:title>
<h2>李白---望庐山瀑布</h2>
</template>
<template #content>
<h3>日照香炉生紫烟</h3>
<h3>遥看瀑布挂前川</h3>
<h3>飞流直下三千尺</h3>
<h3>疑是银河落九天</h3>
</template>
</Panel><hr>
<Panel>
<template v-slot:title>
<h2> 李白---黄鹤楼送孟浩然之广陵</h2>
</template>
<template #content>
<h3>故人西辞黄鹤楼</h3>
<h3>烟花三月下扬州</h3>
<h3>孤帆远影碧空尽</h3>
<h3>唯见长江天际流</h3></template>
</Panel>
<Panel></Panel>
</div>
</template>
<script>
import Panel from './components/Panel.vue'
export default{
name:'',
components:{
Panel
},
data () {
return {
}
},
created () {
},
computed:{
},
methods:{
}
}
</script>
<style lang='less' scoped>
</style>
子组件
<template>
<div>
<slot name='title'></slot>
<!-- slot占位符 -->
<slot name="content">
<h1>默认内容</h1>
</slot>
</div>
</template>
<script>
export default{
name:'Panel',
data () {
return {
}
},
created () {
},
computed:{
},
methods:{
}
}
</script>
<style lang='less' scoped>
</style>
5.4、作用域插槽的使用
1:在子组件上,在slot动态绑定一个数据
2:在使用组件时,template标签 v-slot='自定义变量'一般都默认变量为(scope)接收传递过来的数据
3:自定义的变量就是一个对象,会自动收集传递过来的数据,然后使用就可以了 父组件
<template>
<div>
<Panel>
<template v-slot='scope'>
<h1>{{scope.row.name}}</h1>
<h1>{{scope.row.title}}</h1>
<h3>日照香炉生紫烟</h3>
<h3>遥看瀑布挂前川</h3>
<h3>飞流直下三千尺</h3>
<h3>疑是银河落九天</h3></template>
</Panel>
<Panel>
<template v-slot='scope'>
<p>{{scope.row.name}}</p></template>
</Panel>
</div>
</template>
<script>
import Panel from './components/Panel.vue'
export default{
name:'',
components:{
Panel
},
data () {
return {
}
},
created () {
},
computed:{
},
methods:{
}
}
</script>
<style lang='less' scoped>
</style>
子组件
<template>
<div>
<slot :row='obj'></slot>
</div>
</template>
<script>
export default{
name:'Panel',
data () {
return {
obj:{
name:'李白',
title:'望庐山瀑布'
}
}
},
created () {
},
computed:{
},
methods:{
}
}
</script>
<style lang='less' scoped>
</style>