openks / learn-vue

自定义组件文档
https://openks.github.io/learn-vue
0 stars 0 forks source link

20180911_mintui可输必选项实现方案 #119

Open openks opened 6 years ago

openks commented 6 years ago

在手机端选择很多数据时,做可输必选或者先输入部分数据后点击搜索按钮显示结果 实现方案

  1. 点击要填写字段,出全页的搜索弹层
  2. 在搜索框里输入数据后点击搜索按钮
  3. 页面展示搜索结果(或空结果)
  4. 点击某条搜索出的结果,触发把搜索结果作为参数的搜索结果选择事件,清空输入框,删除搜索结果,关闭弹层
  5. 点击取消,清空输入框,删除搜索结果,关闭弹层

    Q1:如果页面上有很多这样的输入框如何确保数据正确回填

  6. 点击输入框时把能确定该输入框的唯一值保存在data里
  7. 在结果选择事件里根据保存在data里的唯一值回填字段

Q2: 能否一个页面同时打开两个可输必选组件 不能

  1. 由于占用全屏所以界面只会显示一个
  2. 由于数据公用,如果多个会出现数据混乱问题

mint-ui的具体实现方案

  1. search组件没有触发去服务端查询的事件
  2. search组件的取消事件不能自定义 因此需做如下改动
  3. 重写search组件,添加取消事件,添加查询事件
  4. 在slot里修改搜索结果列表并添加搜索结果点击事件
<mt-popup v-model="hopsPopupVisible"
            class="hosPop"
            position="right">
    <m-search v-model="hospValue"
                autofocus
                :result="hospResult"
                @confirm='handerHospConfirm'
                @cancel="handerHospCancel"
                cancel-text="取消"
                placeholder="搜索">
        <mt-cell v-for="item in hospResult"
                    @click.native="handerHospClick(item)"
                    :key='item.id'
                    :title="item.hospitalName">
        </mt-cell>
    </m-search>
</mt-popup>
<script>
export default {
    data(){
        hopsPopupVisible: false,
        hospValue: '',
        hospResult: [],
        fillbackHosp: {
            formName: '',
            index: 0,
            field: "",
        },
    },
        methods: {
        handerHospClick (item) {
            // 回填调用该查询的字段
            let formName = this.fillbackHosp.formName
            let index = this.fillbackHosp.index
            let field = this.fillbackHosp.field
            // console.log('formName', formName, 'index', index, 'field', field)
            this[formName][index][field] = item.hospitalName
            this.handerHospCancel()
        },
        handerHospConfirm (item) {
            // 去服务端获取数据并回填到搜索结果里
            let result=[]
            this.hospResult = result
        },
        handerHospCancel () {
            this.hospValue = ""
            this.hospResult = []
            this.hopsPopupVisible = false
        },
        // 填写能够唯一确定该字段的信息
        showHosPopUp (formName, index, field) {
            this.hopsPopupVisible = true
            this.fillbackHosp = {
                formName: formName,
                index: index,
                field: field,
            }
        },
    }
}
openks commented 6 years ago

修改后的search组件,使用原样式

<template>
  <div class="mint-search">
    <div class="mint-searchbar">
      <div class="mint-searchbar-inner">
        <i class="mintui mintui-search"></i>
        <input ref="input"
               @click="visible = true"
               type="search"
               v-model="currentValue"
               :placeholder="placeholder"
               class="mint-searchbar-core">
      </div>
      <a class="mint-searchbar-cancel confirm"
         @click="handerConfirm"
         v-show="visible"
         v-text="confirmText">
      </a>
      <a class="mint-searchbar-cancel"
         @click="handerCancel"
         v-show="visible"
         v-text="cancelText">
      </a>
    </div>
    <div class="mint-search-list"
         v-show="show || currentValue">
      <div class="mint-search-list-warp">
        <slot>
          <x-cell v-for="(item, index) in result"
                  :key="index"
                  :title="item"></x-cell>
        </slot>
      </div>
    </div>
  </div>
</template>

<script>
import XCell from 'mint-ui/packages/cell/index.js';
if (process.env.NODE_ENV === 'component') {
  require('mint-ui/packages/cell/style.css');
}

/**
 * mt-search
 * @module components/search
 * @desc 搜索框
 * @param {string} value - 绑定值
 * @param {string} [cancel-text=取消] - 取消按钮文字
 * @param {string} [placeholder=取消] - 搜索框占位内容
 * @param {boolean} [autofocus=false] - 自动 focus
 * @param {boolean} [show=false] - 始终显示列表
 * @param {string[]} [result] - 结果列表
 * @param {slot} 结果列表
 *
 * @example
 * <mt-search :value.sync="value" :result.sync="result"></mt-search>
 * <mt-search :value.sync="value">
 *   <mt-cell v-for="item in result" :title="item"></mt-cell>
 * </mt-search>
 */
export default {
  name: 'mt-search',

  data () {
    return {
      visible: false,
      currentValue: this.value
    };
  },

  components: { XCell },

  watch: {
    currentValue (val) {
      this.$emit('input', val);
    },

    value (val) {
      this.currentValue = val;
    }
  },

  props: {
    value: String,
    autofocus: Boolean,
    show: Boolean,
    cancelText: {
      default: '取消'
    },
    confirmText: {
      default: '查询'
    },
    placeholder: {
      default: '搜索'
    },
    result: Array
  },

  methods: {
    handerConfirm () {
      this.visible = false
      this.$emit("confirm", this.currentValue)
    },
    handerCancel () {
      this.visible = false
      this.currentValue = ""
      this.$emit("cancel")
    },
  },

  mounted () {
    this.autofocus && this.$refs.input.focus();
  }
};
</script>