Vue, vuetify и список для справочников

129
02 октября 2019, 09:10

Есть вот такой интерфейс. Слева справочники, вот думаю как сделать чтобы там был список справочников, чтобы пользователь мог выбрать любой нужный ему справочник. Правда не знаю как реализовать, подскажите и если что-то нужно добавить в тему, подскажите и я добавлю, заранее спасибо!

store.js

import Vue from 'vue'
import Vuex from 'vuex'
import * as actions from './actions'
import * as mutations from './mutations'
import users from './modules/users/usersStore'
import roles from './modules/roles/rolesStore'
import employees from './modules/employees/employeeStore'
Vue.use(Vuex);
const store = new Vuex.Store({
    actions,
    mutations,
    modules: {
        users,
        roles,
        employees
    },
    state: {
        first: null,
        langList: [
            {
                code: 'ru',
                shortName: 'РУС',
                name: 'Русский'
            },
            {
                code: 'kk',
                shortName: 'ҚАЗ',
                name: 'Қазақша'
            },
            {
                code: 'en',
                shortName: 'ENG',
                name: 'English'
            }
        ],
        sidebar: true,
        idxMenu: 0,
        emptyItem: {
            title: 'Ошибка', path: '/error', icon: 'error'
        },
        menuItems: [
            // {title: 'Общие настройки', path: '/', icon: 'home'},
            {title: 'Безопасность', subheader: true, divider: false},
            {title: 'Пользователи', path: '/users', icon: 'book'},
            {title: 'Роли', path: '/roles', icon: 'lock_open'},
            {title: 'Справочники', subheader: true, divider: false},
            {title: 'Подразделения', path: '/?type=devision', icon: 'business'},
            {title: 'Сотрудники', path: '/employees', icon: 'people'}
        ]
    }
});
export default store

LeftSideMenu.vue

<template>
    <v-navigation-drawer v-model="sidebar" app>
        <v-toolbar flat class="transparent">
            <v-list>
                <v-list-tile>
                    <v-list-tile-title class="title text-xs-center font-weight-regular text-uppercase">
                        {{ $t('Администрирование') }}
                    </v-list-tile-title>
                </v-list-tile>
            </v-list>
        </v-toolbar>
        <v-divider></v-divider>
        <v-list>
            <template v-for="(item, index) in menuItems">
                <v-list-tile
                        v-if="!item.subheader"
                        :key="item.title"
                        :to="item.path"
                        ripple
                        @click="toggleMenu(index)">
                    <v-list-tile-action>
                        <v-icon medium>{{ item.icon }}</v-icon>
                    </v-list-tile-action>
                    <v-list-tile-content>{{ $t(item.title) }}</v-list-tile-content>
                </v-list-tile>
                <template v-else>
                    <v-divider v-if="item.divider"></v-divider>
                <v-subheader>
                    {{ item.title }}
                </v-subheader>
                </template>
            </template>
        </v-list>
    </v-navigation-drawer>
</template>
<script>
    export default {
        name: 'LeftSideMenu',
        data () {
            return {}
        },
        methods: {
            toggleMenu (index) {
                this.idxMenu = index
            }
        },
        computed: {
            idxMenu: {
                set (val) {
                    this.$store.state.idxMenu = val
                },
                get () {
                    return this.$store.state.idxMenu
                }
            },
            menuItems () {
                return this.$store.state.menuItems
            },
            sidebar: {
                get () {
                    return this.$store.state.sidebar
                },
                set (val) {
                    return this.$store.state.sidebar = val
                }
            }
        }
    }
</script>
<style>
</style>

EmployeePanel.vue

<template>
    <div>
        <v-card flat>
            <v-toolbar flat card prominent class="no-padding-toolbar">
                <v-toolbar-items>
                    <v-tooltip bottom>
                        <v-btn flat slot="activator" @click="dialog = true">
                            <v-icon medium>add</v-icon>
                        </v-btn>
                        <span>{{ $t('Добавить сотрудника') }}</span>
                    </v-tooltip>
                    <v-tooltip bottom>
                        <v-btn flat slot="activator" @click="delEmployees">
                            <v-icon medium>delete</v-icon>
                        </v-btn>
                        <span>{{ $t('Удалить сотрудника') }}</span>
                    </v-tooltip>
                </v-toolbar-items>
                <v-text-field
                        v-model="search"
                        append-icon="search"
                        :label="$t('Поиск')"
                        single-line
                        hide-details>
                </v-text-field>
            </v-toolbar>
            <v-divider>
            </v-divider>
            <v-data-table
                    :headers="commonHeaders"
                    :items="employees"
                    :search="search"
                    v-model="selected"
                    item-key="employeeName"
                    :tran1="$t('Должность')"
                    :no-data-text="$t('Нет данных')"
                    :no-results-text="$t('Не найдены значения')"
                    hide-actions select-all
                    class="fixed-headers">
                <template slot="items" slot-scope="props">
                    <td style="width: 48px; max-width: 48px;">
                        <v-checkbox v-model="props.selected" primary hide-details></v-checkbox>
                    </td>
                    <td>{{ props.item.employeeName }}</td>
                    <td>{{ props.item.ruName}}</td>
                    <td>{{ props.item.kzName}}</td>
                    <td>{{ props.item.enName}}</td>
                    <v-layout align-center justify-space-around row fill-height>
                        <v-icon medium @click="editItem(props.item)">
                            edit
                        </v-icon>
                        <v-icon medium @click="deleteItem(props.item)">
                            delete
                        </v-icon>
                    </v-layout>
                </template>
            </v-data-table>
        </v-card>
        <v-dialog v-model="dialog" persistent max-width="600px">
            <v-card>
                <v-form ref="form">
                    <v-card-text>
                        <v-container grid-list-md>
                            <v-layout wrap>
                                <v-flex xs12>
                                    <v-text-field :label="$t('Должность')" required
                                                  v-model="employeeName"></v-text-field>
                                </v-flex>
                                <v-flex xs12>
                                    <v-text-field :label="$t('ФИО сотрудника на русском')" v-model="ruName"
                                                  required></v-text-field>
                                </v-flex>
                                <v-flex xs12>
                                    <v-text-field :label="$t('ФИО сотрудника на казахском')" v-model="kzName"
                                                  required></v-text-field>
                                </v-flex>
                                <v-flex xs12>
                                    <v-text-field :label="$t('ФИО сотрудника на английском')" required
                                                  v-model="enName"></v-text-field>
                                </v-flex>
                            </v-layout>
                        </v-container>
                    </v-card-text>
                    <v-card-actions>
                        <v-spacer></v-spacer>
                        <v-btn color="blue darken-1" flat @click="closeMeth" closeMethod>{{$t('Закрыть')}}</v-btn>
                        <v-btn color="blue darken-1" flat @click="addEmployee">{{$t('Сохранить')}}</v-btn>
                    </v-card-actions>
                </v-form>
            </v-card>
        </v-dialog>
    </div>
</template>
<script>

    export default {
        name: 'EmployeesPanel',
        data() {
            return {
                isEdit: false,
                id: '',
                employeeName: '',
                ruName: '',
                kzName: '',
                enName: '',
                dialog: false,
                selected: [],
                search: '',
                commonHeaders: [
                    {text: 'Должность', align: 'left', value: 'employeeName'},
                    {text: 'ФИО на русском языке', align: 'left', value: 'ruName'},
                    {text: 'ФИО на казахском языке', align: 'left', value: 'kzName'},
                    {text: 'ФИО на английском языке', align: 'left', value: 'enName'}
                ],
                headersKk: [
                    {text: 'Лауазым', align: 'left', value: 'employeeName'},
                    {text: 'Аты мен тегі қызметкер орысша', align: 'left', value: 'ruName'},
                    {text: 'Аты мен тегі қызметкер казакша', align: 'left', value: 'kzName'},
                    {text: 'Аты мен тегi қызметкер ағылшын', align: 'left', value: 'enName'}
                ],
                headersDefault: [
                    {text: 'Должность', align: 'left', value: 'employeeName'},
                    {text: 'ФИО на русском языке', align: 'left', value: 'ruName'},
                    {text: 'ФИО на казахском языке', align: 'left', value: 'kzName'},
                    {text: 'ФИО на английском языке', align: 'left', value: 'enName'}
                ],
                headersEn: [
                    {text: 'Position', align: 'left', value: 'employeeName'},
                    {text: 'Name of the employee in Russian', align: 'left', value: 'ruName'},
                    {text: 'Name of the employee in Kazakh', align: 'left', value: 'kzName'},
                    {text: 'Name of the employee in English', align: 'left', value: 'enName'}
                ],
            }
        },
        methods: {

            deleteItem(item) {
                confirm('Вы действительно хотите удалить?' + item.employeeName) && this.$store.dispatch('employees/deleteEmployee', item.employeeName)
            },
            editItem(item) {
                this.dialog = true
                this.isEdit = true
                this.employeeName = item.employeeName
                this.ruName = item.ruName
                this.kzName = item.kzName
                this.enName = item.enName
                this.id = item.id
            },
            addEmployee() {
                this.dialog = false;
                let outer = this;
                let form = {
                    employeeName: outer.employeeName,
                    ruName: outer.ruName,
                    kzName: outer.kzName,
                    enName: outer.enName,
                    id: outer.id
                };
                if (this.isEdit === false) {
                    this.$store.dispatch('employees/addingEmployee', form);
                    this.$refs.form.reset()
                } else {
                    this.$store.dispatch('employees/editEmployee', form);
                    this.isEdit = false;
                    this.$refs.form.reset()
                }
            },
            delEmployees() {
                if (this.selected.length === 0) {
                    alert(this.$i18n.t('Для удаления нужно выбрать cотрудника'))
                } else {
                    const msg = this.$i18n.t('Удалить сотрудников?') + '(' + this.selected.length + ')';
                    let boo = confirm(msg) && this.$store.dispatch('employees/deleteEmployees', this.selected)
                    if (boo === true) {
                        this.selected = [];
                    } else {
                        this.selected = [];
                    }
                }
            },
            closeMeth() {
                this.dialog = !this.dialog;
                this.$refs.form.reset();
                this.isEdit = false;
            },
            setData() {
                this.$store.dispatch('employees/loadEmployees')
            }
        },
        created() {
            this.setData();
        },
        watch: {
            locale(val) {
                console.log(val)
                if (val === 'kk') {
                    this.commonHeaders = this.headersKk
                } else if (val === 'ru') {
                    this.commonHeaders = this.headersDefault
                } else if (val === 'en') {
                    this.commonHeaders = this.headersEn
                }
            }
        },
        computed: {
            languages() {
                return this.$store.state.langList
            },
            employees() {
                return this.$store.state.employees.all
            },
            locale: {
                get() {
                    return this.$i18n.locale
                },
                set(val) {
                    this.$i18n.locale = val
                }
            },
        }
    }

</script>
<style>
    .card--flex-toolbar {
        margin-top: -65px;
    }
</style>

Вот нашел Grid List:

<div id="app">
  <v-app id="inspire">
    <v-layout>
      <v-flex xs12 sm6 offset-sm3>
        <v-card>
          <v-card-actions>
            <v-select v-model="size" :items="items" label="Size"></v-select>
            <v-spacer></v-spacer>
          </v-card-actions>
          <v-container v-bind="{ [`grid-list-${size}`]: true }" fluid>
            <v-layout row wrap>
              <v-flex
                v-for="n in 9"
                :key="n"
                xs4
              >
                <v-card flat tile>
                  <v-img
                    :src="`https://unsplash.it/150/300?image=${Math.floor(Math.random() * 100) + 1}`"
                    height="150px"
                  ></v-img>
                </v-card>
              </v-flex>
            </v-layout>
          </v-container>
        </v-card>
      </v-flex>
    </v-layout>
  </v-app>
</div>

new Vue({
  el: '#app',
  data: () => ({
    size: 'sm',
    items: [
      { text: 'Extra small (2px)', value: 'xs' },
      { text: 'Small (4px)', value: 'sm' },
      { text: 'Medium (8px)', value: 'md' },
      { title: 'Подразделения', path: '/?type=devision' },
      { title: 'Сотрудники', path: '/employees'}
    ]
  })
})

Но в нём я не понимаю что такое:
1. v-layout 2. v-flex 3. v-card и тд, понял из этого Grid List(a) только наверное 10% внутри описанного

READ ALSO
Поменять дату по нажатию на button

Поменять дату по нажатию на button

Есть график на котором можно выбирать диапазон например с 2010-1-01 по 2020-2-02Я попытался сделать чтоб по нажатию на кнопку забивалась конкретная...

143
Почему не работает onMouseLeave в react?

Почему не работает onMouseLeave в react?

Не работает onMouseLeave когда кнопка disabled, а когда enabled то работает

136
Слайдер fotorama не отображает alt

Слайдер fotorama не отображает alt

При использовании fotorama, не отображаются alt в картинкахПрошу помощи

154
Почему появляется ошибка undefined?

Почему появляется ошибка undefined?

Почему выводит undefined?

168