封装组件
需求:
封装一个组件,如果小于999正常显示,大于1000就显示1,000 / 29,088 , 如果是交易金额的话大于10000的时候显示¥1.00万元 / ¥24.32万元
用到的知识:父子传值,计算属性,slot插槽(具名插槽和作用域插槽)
封装的showTitleNumber组件:
<template>
<div class="containier">
<!-- 标题 -->
<div class="title">
<slot name="title"></slot>
</div>
<!-- 数字 -->
<div class="bottom">
<span>
<span class="momeny" v-if="showmoney">
<slot name="momeny" :momeny="momeny"></slot>
</span>
<span v-else></span>
</span>
<span class="number">{{computedNum}}</span>
<span>
<span class="Wanji" v-if="showmoney">
<slot name="Wanji" :Wanji="Wanji"></slot>
</span>
<span v-else></span>
</span>
</div>
</div>
</template>
<script>
export default {
data() {
return {
momeny: "¥",
Wanji: "万元"
};
},
props: { showmoney: Boolean, number: Number },
computed: {
computedNum() {
if (this.number < 1000) {
return this.number;
} else if (this.number >= 1000 && this.number <= 9999) {
return this.number.toLocaleString("en-US");
} else if (this.number >= 10000 && this.showmoney) {
return Math.round((this.number / 10000) * 100) / 100;
} else if (this.number >= 10000) {
return this.number.toLocaleString("en-US");
}
}
},
created() {
console.log(this.showmoney);
}
};
</script>
<style lang="scss" scoped>
.title {
width: 220px;
color: #626262;
font-size: 14px;
line-height: 14px;
text-align: center;
}
.bottom {
text-align: center;
width: 220px;
margin-top: 10px;
.number {
font-weight: 900;
font-size: 30px;
line-height: 30px;
color: #626262;
margin-top: 10px;
}
.momeny {
font-weight: normal;
font-size: 14px;
line-height: 14px;
}
.Wanji {
font-weight: normal;
font-size: 14px;
line-height: 14px;
}
}
</style>
App.vue调用的时候,先引入,在注册,在调用
<showTitleNumber :number="你显示的number是多少" > <!--如果需要显示¥和万元传递 :showmoney="showmoney" 即可-->
<template v-slot:title> <!-- 需要data里面定义一个showmoney:true-->
<div>{{你要显示的title是什么}}</div>
</template>
<template v-slot:momeny="info">
{{info.momeny}}
</template>
<template v-slot:Wanji="info">
{{info.Wanji}}
</template>
</showTitleNumber>
防抖使用
需求:有一个按钮,用户点提交,将数据发送给后端,放了防止用户多次提交用了防抖。
- 首先在utils里,建一个js文件
//防抖函数
export const DebounceBy = (fn, t) => {
let delay = t || 500
let timer
return function () {
let args = arguments;
if (timer) {
clearTimeout(timer)
}
let callNow = !timer
timer = setTimeout(() => {
timer = null
}, delay)
if (callNow) fn.apply(this, args)
}
}
- 在组件里引入
import { DebounceBy } from "../../utils/btn";
- 然后调用
//html
<el-button type="primary" :plain="true" class="btn" @click="savaDataIndicator(form)">保存</el-button> //当我点击的时候触发这个方法
//vue文件
methods: {
//当我点击保存按钮的时候,触发DebounceBy函数,DebounceBy函数接受一个处理函数 和 wait
savaDataIndicator: DebounceBy(function() {
//todosomeing
console.log(arguments)
//如果我两秒以内,一直点击按钮,那么他只会打印一次arguments,
}, 2000)
}
谈一谈用到的知识点:
computed计算属性 和 watch
computed:一个数据受多个数据的影响 //使用场景 购物车总价
watch:一个数据影响多个数据 //使用场景 监听xx变化,变化了我就干嘛干嘛
slot插槽
之前一直迷迷糊糊的,现在用了感觉挺简单的
为什么要用插槽?
比如你封装了一个组件吧,你在app.vue里面调用了这个组件,显示出了你封装好的组件内容。但是你现在想要扩展一下,比如我要加一行字,我不能说去封装好的组件里面加吧,那我每次文字都不一样呢?那么就要在封装好的组件里面写一个插槽,,然后调用这个组件的时候,我们直接在组件里面写我们想要加的字就可以了,当然如果封装的组件不加插槽,那么你在组件里面写的那一行字,也不会显示。就这么简单
再来说说具名插槽吧
为什么要用具名插槽,比如有时候,你要定义两个插槽,显示不同的内容,你就可以用具名插槽,怎么写呢
//伪代码
<slot name="a"></slot>
<slot name="b"></slot>
//你在用的时候
<div>
<template v-slot:a>
<div>我是a内容</div>
</template>
<template v-slot:b>
<div>我是b内容</div>
</template>
</div>
注意 具名插槽需要在slot上面写name属性,然后在template模板上写v-slot:namexx ,他的位置是由slot来定义的,假设我把div里面的内容换了个位置,b放上面 a放下面,那么我显示出来的不是b在上面,a在下面,因为他不是根据这个来定义位置的额,是看slot的位置来定义的。查不多这样吧,但是表诉的有点问题,希望你懂
在来说一说作用域插槽
简单来说就是你在父组件里面,想要显示子组件的数据,那么你直接那是拿不到的。需要在子组件里面写<slot name="a" :data="msg"></slot>
父组件的模板上
<template v-slot:a="info"><!-- 用作用域槽口 直接拿不到msg -->
<div>移动卡1</div> {{info.data}}<!-- info拿到是一个对象,要在组件上绑定一个属性 -->
<div>移动卡2</div>
</template>
这个info可以随意起名字,info是个对象,通过info.data,就可以在父组件里面获取到子组件的数据了。。 msg是子组件数据,将他赋值给了data 。