前言
程序员有个信条叫做“不要重复你自己(Don’t repeat yourself, DRY)”
在开发中,为了实现代码的复用,减少冗余。使用公共js工具类方法,公共样式,封装公共组件。
除此之外,还有比较常用的混入mixin功能。
css预加载处理器的混入mixin
使用css预加载处理器,譬如scss,可以通过定义变量和样式混入。
示例
定义变量 variable.scss文件
$blue: #409EFF;
$shadowBg: #f8f8f8;
样式混入 mixin.scss 文件
@mixin clearfix {
&:after {
content: "";
display: table;
clear: both;
}
}
@mixin border-shadow{
border-radius: 4px;
border: 1px solid #ebeef5;
-webkit-box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
}
@mixin flex{
display: flex;
justify-content: center;
align-items: center;
}
然后在vue组件中,引入这些公共样式,即可实现代码的复用
<template>
<div>
<div class="select-role-wrapper">
<div class="base">
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
@import "@/assets/scss/mixin.scss";
@import "@/assets/scss/variable.scss";
.base {
@include border-shadow;
.title {
@include flex;
height: 100px;
background: $blue;
justify-content: flex-start;
text-align: left;
padding: 0 20px;
border-radius: 4px 4px 0 0;
font-size: 18px;
}
}
</style>
Vue中的mixins
Vue官网,关于可复用性&组合的章节,也提到了混入mixin
基础
混入(mixin)提供了一种非常灵活的方式,来分发Vue组件中的可复用功能。
一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。
选项合并
当组件和混入对象含有同名选项时,这些选项将以恰当的方式进行“合并”。
比如,数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先。
同名钩子函数将合并为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用。
除了公用数据,template布局也可以混入。但是,如果已经有了template就会替换mixins中的template布局。
页面逻辑都差不多的时候,引入混入mixins可以少写很多都没,可以根据项目要求引入。
详情请见官方文档
Vue的文档看起来真是赏心悦目。
以实际项目为例:
一些常用的请求接口的方法,和文件流下载方法,点击事件,就可以放在混入mixins文件中
OperateMixin.js文件
import { parseTime } from "@/utils/common";
import { deleteColor } from "@/utils/common";
export const OperateMixin = {
data() {
return {
deleteColor,
}
},
created() {
},
methods: {
// 点击操作按钮的方法
btnClick(item) {
let length = this.table.selection.length;
let msg = "";
if (length == 0 && item.alert) {
msg = item.alert;
}
if (msg) {
this.$sweetAlert.warnWithTimer(msg);
return;
}
let ids = this.table.selection.map((item) => item.ID).join(",");
this.operate(ids, item.value);
},
operateBeforeConfirm(ids, type, msg, callback) {
this.$confirm(msg, "操作提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
callback(ids, type);
})
.catch(() => { });
},
interfaceRequest(httpurl, formData, method, callback) {
this.$api.httpAction(httpurl, formData, method).then((res) => {
if (res.code == 200) {
this.$sweetAlert.successWithTimer(res.msg);
callback();
} else {
this.$sweetAlert.errorWithTimer(res.msg);
}
});
},
downloadByFileStream(httpurl, formData, name, format) {
let fileName = name || parseTime(new Date(), "{y}-{m}-{d}");
let formatName = format || 'zip';
formatName = '.' + formatName;
this.$api.downFile(httpurl, formData).then((data) => {
if (!data) {
this.$sweetAlert.errorWithTimer("文件下载失败!");
return;
}
if (typeof window.navigator.msSaveBlob !== "undefined") {
window.navigator.msSaveBlob(new Blob([data]), fileName + formatName);
} else {
const url = window.URL.createObjectURL(new Blob([data]));
const link = document.createElement("a");
link.style.display = "none";
link.href = url;
link.setAttribute("download", fileName + formatName);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(url);
}
});
}
}
}
然后在组件中引入
<template>
<div class="wrapper">InfoList</div>
</template>
<script>
import { OperateMixin } from "@/mixins/OperateMixin";
export default {
name: "InfoList",
mixins: [OperateMixin],
components: {},
props: {},
data() {
return {};
},
watch: {},
computed: {},
methods: {},
created() {},
mounted() {},
};
</script>
<style scoped>
.wrapper {
}
</style>