Nocturnal Pajama Mutants

    v-iterator

    1.1.3 • Public • Published

    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 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'
      }
    }
    

    Install

    npm i v-iterator

    DownloadsWeekly Downloads

    78

    Version

    1.1.3

    License

    MIT

    Unpacked Size

    256 kB

    Total Files

    6

    Last publish

    Collaborators

    • npm
    • dongqueue