这次选择了mint-UI,主要是element出品。之前有了解过vue-element-admin,风格和样式相似就选择了这款框架。Mint-UI有较为详细的文档和demo,但是~~~也是有些坑,那么现在,让我总结和回归一下爬坑之旅吧。
项目中使用到的mint-ui组件
组件 | 功能 | 介绍 |
---|---|---|
Toast | 提示信息 | 类似于layer的弹窗信息 |
Field | form表单 | 主要采用了输入项的样式 |
Button | 按钮 | 主要采用了风格样式 |
LoadMore | 移动端加载 | 上拉加载、下拉刷新 |
Action-sheet | 底部弹窗 | - |
picker | 选择器 | 用于模拟原声Html-select功能,像ios日期选择的风格 |
描述:
需要做一个品牌车系的二级联动,第一个想法是用原声的select框,数据请求获取到option的值插入,监听change事件,然后第二个select联动触发。
但是这样的效果和用户体验在移动端感觉不是太好,结合mint-ui提供的组件,我采用了picker和action-sheet结合的办法,展示效果如上图。
下面,用在代码中体现吧
Html部分
import { Popup } from "mint-ui";
export default {
name: "pickerAndSheet",
props: {
postUrl: ""
},
data() {
return {
popupVisible: false,
brandPopupVisible: false,
modelName: "全部",
brandName: "全部",
brandId: "",
modelId: "",
modelsKey: [
//车系
{
flex: 1,
values: [
{
index: 0,
code: "",
name: "全部"
}
],
textAlign: "center",
className: "slot1",
defaultIndex: 0
}
],
brandsKey: [
//品牌
{
flex: 1,
values: [
{
index: 0,
code: "",
name: "全部"
}
],
textAlign: "center",
className: "slot1",
defaultIndex: 0
}
]
};
},
mounted: function() {
//初始化车型库
this.getModelKey();
},
methods: {
//搜索方法
searchInfo() {
var data = {
brand: this.brandId,
model: this.modelId
};
this.$emit("func", data);
},
//点击车型
modelIdClick() {
this.popupVisible = true;
},
//点击品牌
brandIdClick() {
this.brandPopupVisible = true;
},
onValuesChangeOfBrand(picker, values) {
this.brandName = values[0].name;
var data = {
name: "brand",
code: values[0].code
};
this.brandId = values[0].code;
//子组件向父组件传递参数
///this.$emit("func", data);
},
onValuesChangeOfModel(picker, values) {
this.modelName = values[0].name;
var data = {
name: "model",
code: values[0].code
};
this.modelId = values[0].code;
//切换model
var code = values[0].code;
//子组件向父组件传递参数
//this.$emit("func", data);
var url = this.HOME + "/wx/getBrandByModel?modelid=" + code; //HOME变量为已挂载的可跨域域名,这里将其拼接完,成为一个完整路径
this.$axios({
//this代表vue对象,之前在入口文件中把axios挂载到了vue中,所以这里直接用this.$axios调用axios对象
method: "get",
url: url,
data: {}
})
.then(res => {
var arr = res.data.data;
var values = [];
//模型对象中转
for (const item in arr) {
var single = {
index: parseInt(item),
code: arr[item].id,
name: arr[item].name
};
values.push(single);
this.brandsKey[0].values.push(single);
}
//this.$refs.picker.setSlotValues(0, values);
console.log(this.modelsKey);
//this.modelsKey = res.data.modelkey;
})
.catch(err => {
//console.log(err);
Toast(err.data.result.resultDesc);
});
},
getModelKey() {
var url = this.HOME + this.postUrl; //HOME变量为已挂载的可跨域域名,这里将其拼接完,成为一个完整路径
this.$axios({
//this代表vue对象,之前在入口文件中把axios挂载到了vue中,所以这里直接用this.$axios调用axios对象
method: "post",
url: url,
data: {}
})
.then(res => {
var arr = res.data.data.modelkey;
var values = [];
//模型对象中转
for (const item in arr) {
var single = {
index: parseInt(item),
code: arr[item].id,
name: arr[item].name
};
values.push(single);
this.modelsKey[0].values.push(single);
}
//this.$refs.picker.setSlotValues(0, values);
console.log(this.modelsKey);
//this.modelsKey = res.data.modelkey;
})
.catch(err => {
//console.log(err);
Toast(err.data.result.resultDesc);
});
}
}
};
哎呀,代码有点长,不知道该如何解释了。
en ~ 故作深沉的样子~~
第一步:书写一个类似于select的样式框:
{{modelName}}
添加modeIdClick监听事件,点击时更改popupVisible属性,控制sheet显示隐藏。
第二步:给sheet-popup弹窗中添加内容,数据内容是从后台请求而来:
slots是存放数据的数组,数据结构可以参考官方文档了解
value-key="name" 是指定了slots数据结构为键值对形式。类似于select-option:value-label的形式
picker中有value-key=“name”指定了slots结构:
modelsKey: [
//车系
{
flex: 1,
values: [
{
index: 0,
code: "",
name: "全部"
}
],
textAlign: "center",
className: "slot1",
defaultIndex: 0
}
],
主要是values这个属性的数据结构
第三步:change事件绑定
onValuesChangeOfBrand(picker, values) {
this.brandName = values[0].name;
var data = {
name: "brand",
code: values[0].code
};
this.brandId = values[0].code;
//子组件向父组件传递参数
///this.$emit("func", data);
},
在回调参数了可获取到定义的 name值和code值,那么就可以控制显示的内容name和实际像后台传递的参数code。
组件的传值
一开始这些代码都是写在index.vue文件中,后来发现代码有点多。不便于后期的维护,再一个,把这个组件分离出来,可能会在后面的版本升级中复用。那么在写自定义组件过程中就遇到了子父组件之间的传值问题。
子组件在父组件中的使用
html:
引入:
import pickerAndSheet from "./common/pickerAndSheet.vue";
父组件接受子组件传递过来的参数
@func="getModelOrBrand
getModelOrBrand(data) {
data就是子组件传递的数据
}
子组件中接受参数和传递参数
//接受父组件传递的值,可以直接通过this指向并使用
props: {
postUrl: ""
}
//子组件通过emit方式给父组件传递参数
searchInfo() {
var data = {
brand: this.brandId,
model: this.modelId
};
this.$emit("func", data);
}
Loadmore组件
在这个demo例子中使用了上拉加载功能,按照文档说明可以实现功能。
注意:
在下拉过程中,有三种状态pull-drop-loading,但是在开发过程中一直没有找loading状态,文档中也没有说明原因,最后看文档demo发现,loading是在延迟的过程中才会出现。当和后端交互过程中,由于是本地启动的服务,相应速度是相当的快的,是不会出现loading状态的。如果模拟这个状态可以使用settimeout延迟。