Web前端开发之VUE05——Vue组件使用、组件通信、回顾

目录

 

组件概念:

vue文件-组件:

scoped作用过程:

 Vue组件通信:

 单向数据流:

 子向父的自定义事件:

跨组件通信:


组件概念:

在学习vue组件的使用之前,我们首先看一下之前的一个折叠板的案例。其中包含less语法样式表。请使用yarn add less less-loader安装匹配版本的less包,并将style中lang改为less以完成代码。

<template>
	<div class="box">
		<div><h1 v-text="title"></h1></div>
		<div class="border btnBar">
			<div>0000000000000</div>
			<button @click.stop="toggleShow">{{isShow===false?'show':'hide'}}</button>
		</div>
		<div class="border" v-show="isShow">
			<ul>
				<li>1111111111111</li>
				<li>2222222222222</li>
				<li>3333333333333</li>
				<li>4444444444444</li>
			</ul>
		</div>
	</div>
</template>

<script>
export default {
	data() {
		return {
			isShow:false,
			title:"Text",
			btnText:"Show"
		}
	},
	methods:{
		toggleShow(){
			this.isShow=!this.isShow
		}
	}
}
</script>

<style lang="less">
.box{
	position: absolute;
	top:10px;
	left: 50%;
	transform: translate(-50%,0);
	text-align: center;
}
.border{
	border: 1px solid black;
	border-radius: 5px;
}
.btnBar{
	width: 300px;
	height: 50px;
	display: flex;
	&>div{
		flex: 9;
		position: relative;
		height: 100%;
		line-height: 50px;
		top: 50%;
		transform: translate(0,-50%);
	};
	&>button{
		flex:1;
		height: 30px;
		position: relative;
		top: 50%;
		transform: translate(0,-50%);
		box-sizing: border-box;
	};
}
ul{
	margin: 0;
	padding: 0;
}
li{
	list-style: none;
}
</style>

根据上面的代码,我们如果想在页面加入多个折叠板,就复制粘贴多个折叠板,但是这样会导致性能低下。那么有没有办法,方便我们多次复制使用一个模板呢?

vue文件-组件:

使用此以复用。具体使用的方法如下:

首先,我们将一个组件以vue文件的方式保存其样式和脚本等。(此处我使用的panel-cp.vue作为组件文件)

其次,我们将其当作模块引入我们需要用到的vue页面script中。

import panelCp from "@/components/tutorialUse/panel-cp";

再次,在script中使用component属性来定义【自定义标签名:标签模板】。

components:{
 panel:panelCp
}

最后,在页面中使用。

scoped作用过程:

 Vue组件通信:

父组件向子组件传值:

 单向数据流:

当我们给一个子组件的值进行操作时,会导致父级数据无法同时更新(vue2)或报错(vue3)。

 子向父的自定义事件:

 

 

 下面运用上面的知识给出一个新闻板的示例代码:

组件代码:

//组件
<template>
  <div class="adv-box">
    <h3>新闻
      <span class="icFont ic-xiajiang"></span>
      <span>{{adv_title}}</span>
    </h3>
    <p>新闻内容:{{adv_content}}</p>
    <div class="tools_bar">
      <input type="text" v-model="authorName">
      <div><span>作者:</span><span class="authorNamePart">{{authorName}}</span></div>
      <button class="btn btn-danger btn-sm" @click.stop="delAdv">删除本新闻</button>
    </div>
  </div>
</template>

<script>
export default {
  props: ['adv_id','adv_title','adv_content','adv_author'],
  data(){
    return{
      authorName:this.adv_author
    }
  },
  methods:{
    delAdv(){
      this.$emit('delAdv',this.adv_id)
    }
  }
}
</script>

<style lang="less" scoped>
@import '//at.alicdn.com/t/font_3273526_hyhg5w33jcv.css';
@import 'bootstrap';
.adv-box {
  display: inline-block;
  width: 300px;
  height: 250px;
  padding: 5px;
  border: 1px solid black;
  border-radius: 5px;
}
p{
  height: 150px;
  overflow: auto;
  word-wrap: break-word;
  word-break: break-all;
}
@tools_bar_height:30px;
.tools_bar{
  display: flex;
  align-content: center;
  height: @tools_bar_height;
  &>button{
    flex: 4;
  }
  &>input[type='text']{
    margin-left: 5px;
    width: 50px;
    flex: 5;
  }
  &>div{
    flex: 5;
    line-height: @tools_bar_height;
    display: flex;
    width: 90px;
    &>span{
      display: inline-block;
      flex: 1;
    }
    &>.authorNamePart{
      overflow: hidden;
    }
  }
}
</style>

app.vue: 

//app.vue
<template>
<adv v-for="item in advDataArr" :adv_author="item.advAuthor" :adv_title="item.advTitle" :adv_content="item.advContent" :adv_id="item.advID" :key="item.advID" @delAdv="deleteAdv"></adv>
</template>

<script>
import adv_struct from "@/components/tutorialUse/adv_struct";
export default {
  data(){
    return{
      advDataArr:[
        {
          advID:1,
          advTitle:'新闻1', advContent:'这是一条很长的新闻,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
          advAuthor:'小李'
        },{
          advID:2,
          advTitle:'新闻2', advContent:'这是一条很长的新闻,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
          advAuthor:'小旺'
        },{
          advID:3,
          advTitle:'新闻3', advContent:'这是一条很长的新闻,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
          advAuthor:'小许'
        },{
          advID:4,
          advTitle:'新闻4', advContent:'这是一条很长的新闻,XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
          advAuthor:'小明'
        }
      ]
    }
  },
  methods:{
    deleteAdv(advID){
      let getIndex=this.advDataArr.findIndex(ele=>ele.advID===advID)
      this.advDataArr.splice(getIndex,1)
    }
  },
  components:{
    adv:adv_struct
  },
  watch:{
    advDataArr:{
      deep:true,
      handler(){
        console.log('changed')
      }
    }
  }
}
</script>

<style lang="less" scoped>

</style>

跨组件通信:

 

 下面给出示例:

//传值vue中,触发事件
watch:{
    authorName(newVal,oldVal){
      eventBus.$emit('getName',newVal,oldVal)
    }
  }
//接收值得vue中,监听事件(created是在生命周期后会说到)
created() {
    eventBus.$on('getName', (changedNameNew, changeNameOld) => {
          this.changed_author = changedNameNew
          this.old_author = changeNameOld
        }
    )
  }

总结:

 

 基础回顾:

 

 

 

 6.在vue3中过滤器已废除,建议使用计算属性。

 

 

  

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

言行物恒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值