Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

v-iterator

dongqueue162MIT1.1.3

Easy iterator component for vuetify 2.x

vuetify, ag-grid, ag-chart, page-builder

readme

v-iterator

Composition of repeatedly used vue UI framework's components. It's declare and controlled by data, you don't have to declear each component at 'template'.

version 1.0.1

  • support vuetify.

    version 1.0.6

  • support AG Grid vue.

    version 1.0.8

  • suppert AG Chart vue.

    version 1.1.0

  • support element-ui.

    version 1.1.1

  • bug fix at statement 'if': boolean value does not work that is included in array.

    version 1.1.2

  • bug fix : rendering with v-card-subtitle

    version 1.1.3

  • minior update: add currency at element-ui

installation

install the npm package:

npm i v-iterator --save

Dependency

Required: Lodash

Optional: Vuetify 2.X . AG-Grid . AG-Chart . Element-Ui

Get started

NPM (ES moduels) / installing the package and Vuetify 2.x from scratch:

vuetify.js:

// src/plugins/vuetify.js

import Vue from 'vue'
import Vuetify from 'vuetify/lib'

Vue.use(Vuetify)

const opts = {}

export default new Vuetify(opts)

element.js

// src/plugins/element.js
import Vue from 'vue'
import ElementUI from 'element-ui'
import lang from 'element-ui/lib/locale/lang/en'
import locale from 'element-ui/lib/locale'
import 'element-ui/lib/theme-chalk/index.css'
locale.use(lang)

Vue.use(ElementUI)

Registry <v-iterator> globally in your main.js:

import Vue from 'vue'
import App from './App.vue'

// only when using vuetify
import vuetify from '@/plugins/vuetify'

// only when using element-ui
import 'element-ui'

// import and set v-iterator
import {VIterator} from 'v-iterator'
Vue.component(VIterator.name, VIterator)

// only when using ag-grid
import { AgGridVue } from 'ag-grid-vue'
Vue.component('ag-grid-vue', AgGridVue)
import 'ag-grid-community/dist/styles/ag-grid.css'
import 'ag-grid-community/dist/styles/ag-theme-balham.css'

// only when using ag-chart
import { AgChartsVue } from 'ag-charts-vue'
Vue.component('ag-charts-vue', AgChartsVue)

new Vue({
  vuetify,
  render: h => h(App)
}).$mount('#app')

Add runtime compiler option at 'vue.config.js'

module.exports = {
  runtimeCompiler: true
}

Add externals at vue.config.js:

module.exports = {
  configureWebpack: {
    externals: {
      'element-ui': 'element-ui', // if you don't use element-ui, add this line
      'vuetify/lib': 'vuetify/lib' // if you don't use vuetify, add this line
    }
  }
}

How to use

Api is basically same with original component

  <template>
    <v-iterator :dynamicArg="screen" :data="$data" @btnClick="btnClick">
  </template>
  <script>
    export default {
      data: () => ({
        screen: {
          items: [
            { component: 'container', framework: 'vuetify', fluid: true, items: [
              { component: 'btn', framework: 'vuetify', color: 'grey lighten-3', itemtext: 'Block Button', style: 'width: 100%;', 
                evnts: [{ event: 'click', method: 'btnClick'}]
              },
              { component: 'card', framework: 'vuetify', flat: true, items: [
                { component: 'card-text', framework: 'vuetify', itemtext: 'textData' }
              ]}
            ]}
          ]
        },
        textData: 'Button clicked!',
        clickedCount: 0
      }),
      methods: {
        btnClick () {
          this.clickedCount++
          this.textData = String(this.textData).concat(': ', this.clickedCount)
        }
      }
    }
  </script>

custom attribute 'framework'

  • From version 1.1.0, element-ui framework is supported. So that define framework, this attribute is added.
  • value: vuetify (short key: v), element (short key: el)
  • default: vuetify
  • to change default value: set 'VUE_APP_FRAMEWORK' at your .env file
    VUE_APP_FRAMEWORK=element

included vuetify component

  • Almost vuetify components are supported.

    component name

    agGrid: 'AG Grid',
    agd: 'AG Grid',
    agChart: 'AG Chart',
    
    alert: 'Alert',
    alt: 'Alert',
    appBar: 'AppBar',
    appbar: 'AppBar',
    apb: 'AppBar',
    autocomplete: 'Autocomplete',
    aut: 'Autocomplete',
    avatar: 'Avatar',
    ava: 'Avatar',
    badge: 'Badge',
    bge: 'Badge',
    banner: 'Banner',
    bnr: 'Banner',
    bottomNavigation: 'BottomNavigation',
    bnavi: 'BottomNavigation',
    btmnav: 'BottomNavigation',
    bottomSheet: 'BottomSheet',
    bsheet: 'BottomSheet',
    btmsht: 'BottomSheet',
    breadcrumbs: 'Breadcrumbs',
    bread: 'Breadcrumbs',
    brd: 'Breadcrumbs',
    breadcrumbsItem: 'BreadcrumbsItem',
    breadItem: 'BreadcrumbsItem',
    breaditm: 'BreadcrumbsItem',
    brditm: 'BreadcrumbsItem',
    button: 'Button',
    btn: 'Button',
    buttonToggle: 'ButtonToggle',
    btnToggle: 'ButtonToggle',
    btntog: 'ButtonToggle',
    card: 'Card',
    crd: 'Card', 
    cardTitle: 'CardTitle',
    crdtle: 'CardTitle',
    cardSubtitle: 'CardSubtitle',
    crdsut: 'CardSubitle',
    cardText: 'CardText',
    crdtxt: 'CardText',
    cardActions: 'CardActions',
    crdact: 'CardActions',
    calendar: 'Calendar',
    caledr: 'Calendar',
    cal: 'Calendar',
    carousel: 'Carousel',
    car: 'Carousel',
    carouselItem: 'CarouselItem',
    caritm: 'CarouselItem',
    carouselTranstion: 'CarouselTranstion',
    cartrn: 'CarouselTranstion',
    carouselReverseTranstion: 'CarouselReverseTranstion',
    carrevtrn: 'CarouselReverseTranstion',
    chip: 'Chip',
    chp: 'Chip',
    chipGroup: 'ChipGroup',
    chpgrp: 'ChipGroup',
    checkbox: 'Checkbox',
    chk: 'Checkbox',
    col: 'Col',
    combobox: 'Combobox',
    com: 'Combobox',
    container: 'Container',
    contai: 'Container',
    currency: 'Currency',
    cur: 'Currency',
    dataIterator: 'DataIterator',
    dtaIte: 'DataIterator',
    dataFooter: 'DataFooter',
    dtafoo: 'DataFooter',
    datePicker: 'DatePicker',
    date: 'DatePicker',
    dte: 'DatePicker',
    dtepik: 'DatePicker',
    dialog: 'Dialog',
    dia: 'Dialog',
    dialogTranstion: 'DialogTranstion',
    diatrn: 'DialogTranstion',
    dialogTopTranstion: 'DialogTopTranstion',
    diatoptrn: 'DialogTopTranstion',
    dialogBottomTranstion: 'DialogBottomTranstion',
    diabottrn: 'DialogBottomTranstion',
    divider: 'Divider',
    dvd: 'Divider',
    div: 'Div',
    expansionPanels: 'ExpansionPanels',
    expanels: 'ExpansionPanels',
    exppans: 'ExpansionPanels',
    expansionPanel: 'ExpansionPanel',
    expanel: 'ExpansionPanel',
    exppan: 'ExpansionPanel',
    expansionPanelHeader: 'ExpansionPanelHeader',
    expanelh: 'ExpansionPanelHeader',
    exppanhdr: 'ExpansionPanelHeader',
    expansionPanelContent: 'ExpansionPanelContent',
    expanelc: 'ExpansionPanelContent',
    exppancon: 'ExpansionPanelContent',
    expandTransition: 'ExpandTransition',
    exptrn: 'ExpandTransition',
    fadeTransition: 'FadeTransition',
    fadtrn: 'FadeTransition',
    fileInput: 'FileInput',
    file: 'FileInput',
    fle: 'FileInput',
    form: 'Form',
    frm: 'Form',
    footer: 'Footer',
    fter: 'Footer',
    ftr: 'Footer',
    hover: 'Hover',
    hovr: 'Hover',
    hvr: 'Hover',
    icon: 'Icon', 
    icn: 'Icon',
    image: 'Image', 
    img: 'Image',
    input: 'Input',
    in: 'Input',
    inp: 'Input',
    item: 'Item',
    itm: 'Item',
    itemGroup: 'ItemGroup',
    itmgrp: 'ItemGroup',
    lazy: 'Lazy',
    laz: 'Lazy',
    list: 'List',
    lst: 'List',
    listGroup: 'ListGroup',
    lstgrp: 'ListGroup',
    listItem: 'ListItem',
    lstitm: 'ListItem',
    listItemTitle: 'ListItemTitle',
    lstitmtle: 'ListItemTitle',
    listItemSubtitle: 'ListItemSubtitle',
    lstitmsut: 'ListItemSubtitle',
    listItemAction: 'ListItemAction',
    lstitmact: 'ListItemAction',
    listItemActionText: 'ListItemActionText',
    lstitmacttxt: 'ListItemActionText',
    listItemAvatar: 'ListItemAvatar',
    lstitmava: 'ListItemAvatar',
    listItemContent: 'ListItemContent',
    lstitmcon: 'ListItemContent',
    listItemIcon: 'ListItemIcon',
    lstitmicn: 'ListItemIcon',
    listItemGroup: 'ListItemGroup',
    lstitmgrp: 'ListItemGroup',
    menu: 'Menu',
    meu: 'Menu',
    navigationDrawer: 'NavigationDrawer',
    navdrw: 'NavigationDrawer',
    navidrw: 'NavigationDrawer',
    overflow: 'OverflowButton',
    overbtn: 'OverflowButton',
    overlay: 'Overlay',
    ovl: 'Overlay',
    pagination: 'Pagination',
    page: 'Pagination',
    pag: 'Pagination',
    parallax: 'Parallax',
    par: 'Parallax',
    pax: 'Parallax',
    progressLinear: 'ProgressLinear',
    progressL: 'ProgressLinear',
    prglin: 'ProgressLinear',
    progressCircular: 'ProgressCircular',
    progressC: 'ProgressCircular',
    prgcir: 'ProgressCircular',
    radio: 'Radio',
    rdo: 'Radio',
    radioGroup: 'RadioGroup',
    radiogrp: 'RadioGroup',
    rdogrp: 'RadioGroup',
    rating: 'Rating',
    rate: 'Rating',
    rat: 'Rating',
    range: 'RangeSlider',
    rangeSlider: 'RangeSlider',
    rng: 'RangeSlider',
    rngsld: 'RangeSlider',
    responsive: 'Responsive',
    res: 'Responsive',
    row: 'Row',
    scrollXTransition: 'ScrollXTransition',
    scrxtrn: 'ScrollXTransition',
    scrollYTransition: 'ScrollYTransition',
    scrytrn: 'ScrollYTransition',
    select: 'Select',
    slt: 'Select',
    sheet: 'Sheet',
    sht: 'Sheet',
    simpleTable: 'SimpleTable',
    simtbl: 'SimpleTable',
    skeletonLoader: 'SkeletonLoader',
    skeleton: 'SkeletonLoader',
    skelod: 'SkeletonLoader',
    slideItem: 'SlideItem',
    sliitm: 'SlideItem',
    slideGroup: 'SlideGroup',
    sligrp: 'SlideGroup',
    slider: 'Slider',
    sld: 'Slider',
    snackbar: 'Snackbar',
    sba: 'Snackbar',
    spacer: 'Spacer',
    spc: 'Spacer',
    speedDial: 'SpeedDial',
    spddil: 'SpeedDial',
    stepper: 'Stepper',
    stp: 'Stepper',
    stepperContent: 'StepperContent',
    stpcon: 'StepperContent',
    stepperHeader: 'StepperHeader',
    stphdr: 'StepperHeader',
    stepperItems: 'StepperItems',
    stpitm: 'StepperItems',
    stepperStep: 'StepperStep',
    stpstp: 'StepperStep',
    subheader: 'Subheader',
    subhdr: 'Subheader',
    switch: 'Switch',
    swc: 'Switch',
    tabItem: 'TabItem',
    tabitm: 'TabItem',
    tabReverseTransition: 'TabReverseTransition',
    tabrevtrn: 'TabReverseTransition',
    tabTransition: 'TabTransition',
    tabtrn: 'TabTransition',
    tabs: 'Tabs',
    tab: 'Tab',
    tabsItems: 'TabsItems',
    tabsitms: 'TabsItems',
    text: 'Text',
    txt: 'Text',
    textarea: 'Textarea',
    texta: 'Textarea',
    txta: 'Textarea',
    textField: 'Textfield',
    textfield: 'Textfield',
    txtfld: 'Textfield',
    toolbar: 'Toolbar',
    tlb: 'Toolbar',
    toolbarItems: 'ToolbarItems',
    tlbitms: 'ToolbarItems',
    timePicker: 'TimePicker',
    time: 'TimePicker',
    tim: 'TimePicker',
    treeview: 'Treeview',
    tre: 'Treeview',
    tree: 'Treeview',
    window: 'Window',
    win: 'Window',
    windowItem: 'WindowItem',
    winitm: 'WindowItem'

    Event

    Please set method name that related with event at v-on of v-iterator.

    <template>
    <v-iterator :dynamicArg="screen" :data="$data" @btnClick="btnClick">
    </tempalte>
    <script>
    export default {
      data: () => ({
        screen: {
          items: [
            { component: 'container', fluid: true, items: [
              { component: 'btn', color: 'grey lighten-3', itemtext: 'Block Button', style: 'width: 100%;', 
                evnts: [{ event: 'click', method: 'btnClick'}]
              },
              { component: 'card', flat: true, items: [
                { component: 'card-text', itemtext: 'textData' }
              ]}
            ]}
          ]
        },
        textData: 'Button clicked!',
        clickedCount: 0
      }),
      methods: {
        btnClick () {
          this.addCount()
        },
        addCount () {
          this.clickedCount++
          this.textData = String(this.textData).concat(': ', this.clickedCount)
        }
      }
    }
    </script>

    Slot

    If you want to use slot of vuetify component, set like below

    use slot without return value of slot

    { 
    component: 'btn', loading: true, itemtext: 'custom loader', 
    slots: [
      { name: 'loader', items: [{ component: 'text', class: 'ma-0 pa-0', itemtext: 'Loading...' }] }
    ]
    }

    use slot with return value of slot

    {
    component: 'carousel', showArrowsOnHover: true
    slots: [
      { name: 'prev', type: 'data', slotDataName: 'slot', items: [
        { component: 'btn', attrs: 'slot.attrs', on: 'slot.on', color: 'success', itemtext: 'previous' }
      ]}
    ]
    }

    Etc

    i18n

    If you want to use i18n code at lable or text, just use code name like this.

    {
      component: 'btn', label: 'common.confirm'
    }

    or

    {
      component: 'btn', label: this.$t('common.confirm')
    }

    reference

    When you call child component's function at vuetify, need reference like this.

original vuetify

<template>
  <v-form ref="form" v-model="valid" lazy-validation>
    <v-text-field v-model="text" label="text"/>
    <v-btn @click="save">Validate</v-btn>
  </v-form>
</template>
<script>
export default {
  data () {
    return {
      text: '',
      valid: true
    }
  },
  methods: {
    save () {
      this.$refs.form.validate()
    }
  }
}
</script>

v-iterator

<template>
  <v-iterator ref="iterator", :dynamicArg="screen" :data="data" @save="save"/>
</template>
<script>
export default {
  data () {
    return {
      screen: {
        items: [
          { component: 'form', ref: 'form', model: 'valid', 'lazy-validation': true, 
            items: [
              { component: 'text-field', model: 'text', label: 'text' },
              { component: 'btn', itemtext: 'Validate', evnts: [{event: 'click', method: 'save'}]}
            ]
          }
        ]
      },
      data: {
        text: '',
        valid: true
      }
    }
  },
  methods: {
    save () {
      this.$refs.iterator.getRef('form').validate()
    }
  }
}
</script>

v-for

v-iterator use prop name 'itemsfor' instead of 'v-for'.

original vuetify

<template>
  <v-sheet>
    <v-tabs dark show-arrows>
      <v-tab v-for="i in 30" :key="i">
        Item {{ i }}
      </v-tab>
    </v-tabs>
  </v-sheet>
</template>

v-iterator

<template>
  <v-iterator :dynamicArg="screen">
</template>
<script>
export default {
  data () {
    return {
      screen: {
        items: [
          { component: 'sheet', items: [
            { component: 'tabs', dark: true, 'show-arrows': true,
              itemsfor: 30, subItemName: 'i', items: [
                { component: 'tab', itemtext: {value: i, func: e => `Item ${e}`}}
              ]
            }
          ]}
        ]
      }
    }
  }
}
</script>

v-if

v-if is replaced by 'if' array. All object in 'if' array is connected by 'and' condition.

vuetify

<template>
  <v-text-field v-model="name" label="Name"/>
  <v-text-field v-model="email" label="e-mail"/>
  <v-checkbox v-model="agree" label="Agree">
  <v-btn v-if="name && email && agree === true">Submit</b-btn>
  <v-btn v-else>Clear</v-btn>
</template>
<script>
export default {
 ....
}
</script>

v-iterator

<template>
  <v-iterator :dynamicArg="screen" :data="data">
</template>
<script>
export default {
  data () {
    return {
      screen: {
        items: [
          { component: 'text-field', model: 'name', label: 'Name' },
          { component: 'text-field', model: 'email', label: 'E-mail' },
          { component: 'checkbox', model: 'agree', label: 'Agree' },
          { component: 'btn', if: [{target: 'name'}, {target: 'email'}, {target: 'agree', value: true}], itemtext: 'Submit' },
          { component: 'btn', if: [{target: '_self', value: ({name, email, agree}) => name && email && agree === true, ne: true}], itemtext: 'Clear' }
        ]
      },
      data: {
        name: null,
        email: null,
        agree: false
      }
    }
  }
}
</script>

or

data () {
  return {
    screen: {
      items: [
        { component: 'text-field', model: 'name', label: 'Name' },
        { component: 'text-field', model: 'email', label: 'E-mail' },
        { component: 'checkbox', model: 'agree', label: 'Agree' },
        { component: 'btn', itemtext: this.btnText}
      ]
    },
    data: {
      name: null,
      email: null,
      agree: false
    }
  }
},
computed: {
  btnText () {
    return this.data.name && this.data.email && this.data.agree === true ? 'Submit' : 'Clear'
  }
}

or

data () {
  return {
    screen: {
      items: [
        { component: 'text-field', model: 'name', label: 'Name' },
        { component: 'text-field', model: 'email', label: 'E-mail' },
        { component: 'checkbox', model: 'agree', label: 'Agree' },
        { component: 'btn', itemtext: 'btnText' }
      ]
    },
    data: {
      name: null,
      email: null,
      agree: false,
      btnText: 'Clear'
    }
  }
},
watch: {
  'data.name' () {
    this.getBtnText()
  },
  'data.email' () {
    this.getBtnText()
  },
  'data.agree' () {
    this.getBtnText()
  }
},
methods: {
  getBtnText () {
    this.data.btnText = this.data.name && this.data.email && this.data.agree === true ? 'Submit' : 'Clear'
  }
}