vue构建小项目-mint-UI(三)

这次选择了mint-UI,主要是element出品。之前有了解过vue-element-admin,风格和样式相似就选择了这款框架。Mint-UI有较为详细的文档和demo,但是~~~也是有些坑,那么现在,让我总结和回归一下爬坑之旅吧。

项目中使用到的mint-ui组件

组件 功能 介绍
Toast 提示信息 类似于layer的弹窗信息
Field form表单 主要采用了输入项的样式
Button 按钮 主要采用了风格样式
LoadMore 移动端加载 上拉加载、下拉刷新
Action-sheet 底部弹窗 -
picker 选择器 用于模拟原声Html-select功能,像ios日期选择的风格
list.jpg

描述:

需要做一个品牌车系的二级联动,第一个想法是用原声的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延迟。

你可能感兴趣的:(vue构建小项目-mint-UI(三))