0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

DrillDown Pt.4

Last updated at Posted at 2022-02-12

Continuation from pt.3

Implementation

3. components/DrillDown.vue

Create files

touch components/DrillDown.vue
mkdir -p __mock__/api/drillDown
touch __mock__/api/drillDown/dummy.json
touch __mock__/api/drillDown/GET.js
touch store/drillDown.js

Set form data to DrillDown.vue in DrillDownSearch.vue

vim pages/DrillDownSearch.vue

// pages/DrillDownSearch.vue
<template>
  <v-app>
    <div>
      <v-btn @click="open" block>
        Components Button
      </v-btn>
      <ConfirmDialog ref="confirm">
        <DrillDown :firstItems="firstItems" :initial-item="initialItem"></DrillDown>
      </ConfirmDialog>
    </div>
  </v-app>
</template>

<script>
  // ...
  import DrillDown from '../components/DrillDown.vue'
  export default {
    components: { Button, ConfirmDialog, DrillDown },
    data() {
      return {
        firstItems: [1, 2, 3],
        initialItem: {
          option1: 1,
          option2: '',
          option3: ''
        },
        isDialogOpened: false
      }
    },
    // ...
  }
</script>

vim components/DrillDown.vue

// components/DrillDown.vue
<template>
  <div>
    <v-container fluid>
      <v-select v-for="(value, key) in initialItem"
        :key="key"
        :value="value"
        :items="getOption(key)"
        :label="key"
        outlined
      ></v-select>
    </v-container>
  </div>
</template>
<script>
  export default {
    props: {
      initialItem: {
        type: Object,
        default: {}
      },
      firstItems: {
        type: Array,
        default: []
      }
    },
    computed: {
      option1() {
        if (this.firstItems.length === 0) return []
        return [{ text: '選択してください', value: ''}, ...this.firstItems]
      },
      option2() {
        return [{ text: '選択してください', value: ''}]
      },
      option3() {
        return [{ text: '選択してください', value: ''}]
      }
    },
    methods: {
      getOption(key) {
        switch (key) {
          case 'option1':
            return this.option1
          case 'option2':
            return this.option2
          case 'option3':
            return this.option3
        }
      }
    }
  }
</script>

Prepare dummy data

vim __mock__/api/drillDown/dummy.json

// __mock__/api/drillDown/dummy.json
{
  "1": [
    {"text": "1-1"},
    {"text": "1-2"},
    {"text": "1-3"}
  ],
  "1-1": [
    {"text": "1-1-1"},
    {"text": "1-1-2"},
    {"text": "1-1-3"}
  ],
  "1-2": [
    {"text": "1-2-1"},
    {"text": "1-2-2"},
    {"text": "1-2-3"}
  ],
  "1-3": [
    {"text": "1-3-1"},
    {"text": "1-3-2"},
    {"text": "1-3-3"}
  ],
  "2": [
    {"text": "2-1"},
    {"text": "2-2"},
    {"text": "2-3"}
  ],
  "2-1": [
    {"text": "2-1-1"},
    {"text": "2-1-2"},
    {"text": "2-1-3"}
  ],
  "2-2": [
    {"text": "2-2-1"},
    {"text": "2-2-2"},
    {"text": "2-2-3"}
  ],
  "2-3": [
    {"text": "2-3-1"},
    {"text": "2-3-2"},
    {"text": "2-3-3"}
  ],
  "3": [
    {"text": "3-1"},
    {"text": "3-2"},
    {"text": "3-3"}
  ],
  "3-1": [
    {"text": "3-1-1"},
    {"text": "3-1-2"},
    {"text": "3-1-3"}
  ],
  "3-2": [
    {"text": "3-2-1"},
    {"text": "3-2-2"},
    {"text": "3-2-3"}
  ],
  "3-3": [
    {"text": "3-3-1"},
    {"text": "3-3-2"},
    {"text": "3-3-3"}
  ]
}

Prepare get function (just return dummy data)

vim __mock__/api/drillDown/GET.js

// __mock__/api/drillDown/GET.js
const dummyData = require('./dummy.json')
function get(request, response) {
  return response.json({
    http_status: 200,
    success: true,
    dummyData
  })
}
module.exports = get

Prepare action function (just fetch dummy data)

vim store/drillDown.js

// store/drillDown.js
export const actions = {
  async fetch() {
    const path = `/drillDown`
    return this.$axios.$get(path)
      .then(res => {
        const { drillDown } = res
      })
  }
}

Use action in DrillDown.vue

vim pages/DrillDownSearch.vue

// pages/DrillDownSearch.vue
<template>
  <v-app>
    <div>
      <v-btn @click="open" block>
        Components Button
      </v-btn>
      <ConfirmDialog ref="confirm">
        <DrillDown :firstItems="firstItems" :initial-item="initialItem" :path="path"></DrillDown>
      </ConfirmDialog>
    </div>
  </v-app>
</template>

<script>
  const PATH = 'drillDown/fetch'
  // ...
  export default {
  // ...
    data() {
      return {
        // ...
        isDialogOpened: false,
        path: PATH
      }
    },
    // ...
  }
</script>

vim components/DrillDown.vue

// components/DrillDown.vue
// ...
<script>
  export default {
    props: {
      // ...
      firstItems: {
        type: Array,
        default: []
      },
      path: {
        type: String,
        default: ''
      }
    },
    computed: {
      // ...
    },
    mounted() {
      this.prepareOption()
    },
    methods: {
      async prepareOption() {
        await this.$store.dispatch(this.path, {
          option1: this.initialItem.option1
        })
      },
      // ...
    }
  }
</script>

Return options according to post data

vim components/DrillDown.vue

// components/DrillDown.vue
// ...
<script>
  export default {
    // ...
    methods: {
      async prepareOption() {
      	// ...
        await this.$store.dispatch(this.path, {
          option1: this.initialItem.option1,
          option2: this.initialItem.option2
        })
      },
      // ...
    }
  }
</script>

vim store/drillDown.js

// store/drillDown.js
export const actions = {
  async fetch({ commit }, params) {
    const path = `/drillDown`
    return this.$axios.$get(path, {params: params})
      .then(res => {
        const { drillDown } = res
      })
  }
}

vim __mock__/api/drillDown/GET.js

// __mock__/api/drillDown/GET.js
// ...
function get(request, response) {
  const drillDown = makeResDataBy(request.query)
  return response.json({
    // ...
    drillDown
  })
}
function makeResDataBy(params) {
  const res = {
    option2: null,
    option3: null
  }
  const reqKeys = Object.keys(params)
  const resKeys = Object.keys(res)
  const reqLength = Object.keys(params).length
  const reqKey = reqKeys[reqLength - 1]
  const resKey = resKeys[reqLength - 1]
  const reqValue = params[reqKey]
  res[resKey] = dummyData[reqValue]

  return res
}
module.exports = get

Store fetch data

vim store/drillDown.js

// store/drillDown.js
export const state = () => ({
  option2: null,
  option3: null
})

export const mutations = {
  SET(state, obj) {
    const keys = Object.keys(obj)
    for (let i = 0; i < keys.length; i++) {
      if (obj[keys[i]]) {
        state[keys[i]] = obj[keys[i]]
        break
      }
    }
  }
}

export const actions = {
   async fetch({ commit }, params) {
    // ...
    return this.$axios.$get(path, {params: params})
      .then(res => {
        // ...
        commit('SET', drillDown)
      })
  }
}

Set initial option and value

vim components/DrillDown.vue

// components/DrillDown.vue
<template>
  <div>
    <v-container fluid>
      <v-select v-for="(value, key) in initialItem"
        :key="key"
        :value="value"
        :items="getOption(key)"
        :label="key"
        :disabled="isDisabled(key)"
        outlined
      ></v-select>
    </v-container>
  </div>
</template>
<script>
  export default {
    // ...
    data: () => ({
      item1: '',
      item2: '',
      item3: '',
      canSelect: {
        option1: true,
        option2: false,
        option3: false,
      },
      isSetInitialOption: false
    }),
    computed: {
      // ...
      option2() {
        if (!this.$store.state.drillDown) return []
        const option = this.$store.state.drillDown.option2
        return option
          ? [{ text: '選択してください', value: ''}, ...option]
          : [{ text: '選択してください', value: ''}]
      },
      option3() {
        if (!this.$store.state.drillDown) return []
        const option = this.$store.state.drillDown.option3
        return option
          ? [{ text: '選択してください', value: ''}, ...option]
          : [{ text: '選択してください', value: ''}]
      }
    },
    methods: {
      async prepareOption() {
        // ...
        this.$nextTick(() => {
          this.setInitialValue()
        })
      },
      setInitialValue() {
        this.item1 = this.initialItem.option1 ? this.initialItem.option1 : ''
        this.item2 = this.initialItem.option2 ? this.initialItem.option2 : ''
        this.item3 = this.initialItem.option3 ? this.initialItem.option3 : ''
        this.$nextTick(() => {
          this.isSetInitialOption = true
        })
      },
      // ...
      isDisabled(key) {
        return !this.canSelect[key]
      }
    }
  }
</script>

Watch items and Update item according to new value

vim components/DrillDown.vue

// components/DrillDown.vue
<template>
  <div>
    <v-container fluid>
      <v-select v-for="(value, key) in initialItem"
        :key="key"
        :value="value"
        :items="getOption(key)"
        :label="key"
        :disabled="isDisabled(key)"
        @input="newv => updateItem(newv, value, key)"
        outlined
      ></v-select>
    </v-container>
  </div>
</template>
<script>
  export default {
    // ...
    methods: {
      // ...
      updateItem(newv, value, key) {
        switch (key) {
          case 'option1':
            this.item1 = newv
            break
          case 'option2':
            this.item2 = newv
            break
          case 'option3':
            this.item3 = newv
            break
        }
      },
      // ...
    },
    watch: {
      item1(newv) {
        if (!this.isSetInitialOption) return
        this.canSelect['option3'] = false
        this.item2 = ''
        this.item3 = ''
        if (newv === '') {
          this.canSelect['option2'] = false
          return
        } 
        this.$store.dispatch(this.path, {
          option1: newv
        })
          .then(() => {
            if (this.$store.state.drillDown.option2) {
              this.canSelect['option2'] = true
            } else {
              this.canSelect['option2'] = false
            }
          })
          .catch(err => {
            console.log('/drillDown: ', err)
            this.isError = true
          })
      },
      item2(newv) {
        if (!this.isSetInitialOption) return
        this.item3 = ''
        if (newv === '') {
          this.canSelect['option3'] = false
          return
        }
        this.$store.dispatch(this.path, {
          option1: this.item1,
          option2: newv
        })
          .then(() => {
            if (this.$store.state.drillDown.option3) {
              this.canSelect['option3'] = true
            } else {
              this.canSelect['option3'] = false
            }
          })
          .catch(err => {
            console.log('/drillDown: ', err)
            this.isError = true
          })
      }
    }
</script>

vim pages/DrillDownSearch.vue

// pages/DrillDownSearch.vue
// ...
<script>
// ...
  export default {
    // ...
    data() {
      return {
      	// ...
        isResoleved: false,
        // ...
      }
    },
    computed: {
      item1() {
        return this.isResoleved ? this.$refs.drillDown.item1 : this.initialItem.option1
      },
      item2() {
        return this.isResoleved ? this.$refs.drillDown.item2 : this.initialItem.option2
      },
      item3() {
        return this.isResoleved ? this.$refs.drillDown.item3 : this.initialItem.option3
      }
    },
    methods: {
      async open() {
        // ...
        if (await this.$refs.confirm.open()) {
          // ...
          this.isResoleved = true
        } else {
          // ...
        }
      }
    }
  }
</script>

Next DrillDown Pt.5

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?