目录
组件概念:
在学习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中过滤器已废除,建议使用计算属性。