Ответы пользователя по тегу Vue.js
  • Как сделать проверку забайнденного атрибута?

    IgorPI
    @IgorPI
    Это решается с помощью q-form



    https://quasar.dev/vue-components/form
    Ответ написан
    Комментировать
  • Как в Vue-приложении сначала загрузить данные в $store, а уже потом рендерить шаблоны?

    IgorPI
    @IgorPI
    const Foo = {
      template: `...`,
      beforeRouteEnter (to, from, next) {
        // вызывается до подтверждения пути, соответствующего этому компоненту.
        // НЕ ИМЕЕТ доступа к контексту экземпляра компонента `this`,
        // так как к моменту вызова экземпляр ещё не создан!
      },
      beforeRouteUpdate (to, from, next) {
        // вызывается когда маршрут, что рендерит этот компонент изменился,
        // но этот компонент будет повторно использован в новом маршруте.
        // Например, для маршрута с динамическими параметрами `/foo/:id`, когда мы
        // перемещаемся между `/foo/1` и `/foo/2`, экземпляр того же компонента `Foo`
        // будет использован повторно, и этот хук будет вызван когда это случится.
        // Также имеется доступ в `this` к экземпляру компонента.
      },
      beforeRouteLeave (to, from, next) {
        // вызывается перед переходом от пути, соответствующего текущему компоненту;
        // имеет доступ к контексту экземпляра компонента `this`.
      }
    }


    beforeRouteEnter (to, from, next) {
      next(vm => {
        // экземпляр компонента доступен как `vm`
      })
    }


    Источник
    Ответ написан
    2 комментария
  • Общий обработчик ошибок для запросов во vue?

    IgorPI
    @IgorPI
    Используйте интерцептор.

    Подкину свой пример.
    Оформил в виде плагина для VUE.
    Обратите внимание на эту строчку
    export const $axios: AxiosInstance = _axios

    Теперь все запросы идут через интерцептор, именно в нём буду ловить и обрабатывать ошибки протокола.

    import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
    import Vue from 'vue'
    
    // Full config:  https://github.com/axios/axios#request-config
    // axios.defaults.baseURL = process.env.baseURL || process.env.apiUrl || '';
    // axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
    // axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
    
    /* eslint-disable */
    const config = {
      baseURL: process.env.VUE_APP_API,
      timeout: 30000,
      validateStatus (status: number) {
        return status < 500 // Resolve only if the status code is less than 500
      }
    }
    /* eslint-enable */
    
    const _axios: AxiosInstance = axios.create(config)
    
    /* eslint-disable */
    // @ts-ignore
    _axios.interceptors.request.use(async (config: AxiosRequestConfig): AxiosRequestConfig | Promise<AxiosRequestConfig> => {
      return Promise.resolve(config)
      },  (error) => {
        // Do something with request error
        return Promise.reject(error)
      }
    )
    /* eslint-disable */
    
    // Add a response interceptor
    _axios.interceptors.response.use((response): Promise<AxiosResponse> | any => {
      return response
      },  (error) => {
        // Do something with response error
        return Promise.reject(error)
      }
    )
    
    class AxiosPlugin {
      public install () {
        Object.defineProperties(Vue.prototype, {
          axios: {
            get () {
              return _axios
            }
          },
          $axios: {
            get () {
              return _axios
            }
          }
        })
      }
    }
    
    const axiosPlugin: AxiosPlugin = new AxiosPlugin()
    
    Vue.use(axiosPlugin)
    
    export default axiosPlugin
    export const $axios: AxiosInstance = _axios
    Ответ написан
    Комментировать
  • Можно ли получить данные из дочернего компонента?

    IgorPI
    @IgorPI
    Привожу пример рабочего компонента.
    Обратите внимание на

    model: {
        prop: 'selected',
        event: 'change'
      },


    <template>
      <v-autocomplete
        v-model="selected"
        :items="users"
        :search-input.sync="usersSearchQuery"
        persistent-hint
        :label="label"
        :rules="rules"
        :loading="loading"
      >
        <template
          v-slot:prepend
          v-if="visibleIcon && ['lg', 'md'].includes($vuetify.breakpoint.name)"
        >
          <v-icon class="pl-5 pr-9">mdi-account-tie</v-icon>
        </template>
        <template v-slot:selection="{ attr, on, item }">
          <span>{{ item.first_name }} {{ item.last_name }}</span>
        </template>
        <template v-slot:item="{ item }">
          <v-list-item-avatar
            color="indigo"
            class="headline font-weight-light white--text"
          >
            {{ item.first_name.charAt(0) }}
          </v-list-item-avatar>
          <v-list-item-content>
            <v-list-item-title>{{ item.first_name }} {{ item.last_name }}</v-list-item-title>
            <v-list-item-subtitle
              v-if="item.role"
              v-text="item.role.name"
            ></v-list-item-subtitle>
          </v-list-item-content>
        </template>
      </v-autocomplete>
    </template>
    
    <script lang="ts">
    import Vue from 'vue'
    import { debounce } from 'vuetify/src/util/helpers'
    import { Users } from '@/api/Users'
    
    export default Vue.extend({
      name: 'UserAutocomplete',
      model: {
        prop: 'selected',
        event: 'change'
      },
      props: {
        selectedId: {
          type: Number,
          default: 0
        },
        search: {
          type: String,
          default: ''
        },
        rules: {
          type: Array,
          default: undefined
        },
        visibleIcon: {
          type: Boolean,
          default: false
        },
        label: {
          type: String,
          default: ''
        }
      },
    
      data () {
        return {
          loading: false,
          selectOnce: false,
          selected: null,
          usersSearchQuery: null,
          usersProcessLoading: false,
          usersSearchDebounce: debounce((q: string) => {
            this.loading = true
            new Users().findUsers(q)
              .then(({ count, items }) => {
                this.users = items
    
                if (this.selectOnce === false) {
                  this.selectOnce = true
                  this.selected = this.users.find((e) => e.id === this.selectedId)
                  console.log(this.selectedId, this.users)
                  console.log(this.selected)
                }
              }).finally(() => {
                this.loading = false
              })
          }, 400),
          users: []
        }
      },
    
      watch: {
        selected (value) {
          this.$emit('change', value)
        },
    
        usersSearchQuery (val: string) {
          this.usersSearchDebounce(val)
        }
      },
    
      created () {
        this.usersSearchQuery = this.search
      }
    })
    </script>
    Ответ написан
    1 комментарий
  • Как сделать плагин так, что бы он стал реактивным в шаблоне?

    IgorPI
    @IgorPI Автор вопроса
    В общем дело обстоит следующим образом.

    В Vue есть метод observable

    Нужно указать объект за которым планируем следить
    Vue.observable({
          count: 0
        })


    В моём случае, так
    class JsSIPlugin {
      public install () {
        Object.defineProperties(Vue.prototype, {
          $jsSIP: {
            get (): JsSIP {
              return $jssip
            }
          }
        })
    
        Vue.observable($jssip)
      }
    }


    Теперь в шаблоне происходит магия.
    Ответ написан
    1 комментарий
  • Какой посоветуете набор vue компонентов для создания личного кабинета?

    IgorPI
    @IgorPI
    Мне нравится Quasar
    Работал с Vuetify, слишком много багов, по сравнению с Quasar
    Ответ написан
  • Как в Nuxt отключить progress bar загрузки страницы при обычных AJAX запросах?

    IgorPI
    @IgorPI
    nuxt.config.js
    ...
      /*
      ** Customize the progress bar color
      */
      loading: false,
    
      modules: [],
    ...


    В моем случае ещё был Quasar
    Vue.use(Quasar, {
      lang,
      iconSet,
      config: {
        iconSet,
        screen: {
          bodyClasses: true
        },
        loadingBar: {
          color: 'purple',
          size: '0px',
          position: 'bottom'
        }
      }
    })
    Ответ написан
  • Nuxt данные, которые получает, встраивает в html, как это исправить?

    IgorPI
    @IgorPI
    Может есть какой-то параметр в nuxt.config.js для этого?


    Конечно есть

    nuxt.config.js
    module.exports = {
      mode: 'spa',
      ...
    }
    Ответ написан
  • Из-за чего ошибка при отправки?

    IgorPI
    @IgorPI
    Ответ написан
    Комментировать
  • Как правильно организовать передачу прав для конкретной роли юзера с back-end на front-end?

    IgorPI
    @IgorPI
    Как я бы поступил.

    Ход моих мыслей.
    ...

    В идеальном мире back end and frond and не должны знать о существовании друг друга, но речь не об этом.

    Бизнес логика в back end, будет своя.
    Бизнес логика на сайте, мобильном приложении так же будет своя.

    Было бы не плохо иметь специальный метод, который возвращает эти самые привилегии списком.
    А уже потом, в (мобильном приложении, сайте) на основе полученных данных скрывать те или иные разделы.

    Опять же, если юзер используя UI, пытается получить те или иные данные по API, Он однозначно должен выступать с определенными разрешениями, которые запрограммированы в самом back end.

    К чему я виду, даже если вы скроете кнопки визуально, злоумышленник или юзер без привилегий все ровно может получить доступ к данным.

    Поэтому в первую очередь, разрешения, роли нужно программировать на уровне API
    Ответ написан
  • Как создать массив реактивных переменных?

    IgorPI
    @IgorPI
    Когда вы получили массив неких данных, вы всегда можете в каждый элемент добавить любое свойство или функцию или объект.

    Соответственно, у каждого элемента может быть обработчик чего-либо или булево свойство.
    А вообще вопрос не понятен.
    Ответ написан
    Комментировать
  • Nodejs native в vue, как https сделать плагином?

    IgorPI
    @IgorPI Автор вопроса
    Проблема в конфликте имени.
    Вот это рабочий вариант.
    Проще некуда.

    const { http, https } = require("follow-redirects")
    
    const HttpsPlugin = {
      install:  function(Vue, options) {
        Vue.https = https
        window.https = https
        Object.defineProperties(Vue.prototype, {
          https: {
            get() {
              return https
            }
          },
          $https: {
            get() {
              return https
            }
          },
        })
      }
    }
    
    Vue.use(HttpsPlugin)
    Ответ написан
  • Как вытащить параметры из asyncData nuxt?

    IgorPI
    @IgorPI
    Коллега, установи данные по дефолту.в data

    data
    data: function () {
          return {
            organization: {
              name: "",
              reviews: [],
              images: [],
            }
        },


    asyncData
    async asyncData({query, $axios}) {
    
          let params = Object.assign({}, query)
    
          let organization = {}
          await $axios.$get(`${process.env.api}/organizations.getById`, {
            params
          }).then(({code, data}) => {
            organization = data
          });
    
    
          return {
            organization
          }
        },


    После этих манипуляций нечего крошиться не будет.
    Ответ написан
    2 комментария
  • Почему проект крашится nuxt?

    IgorPI
    @IgorPI
    Коллега, сделайте state по дефолту.

    В моём случае, я делаю так.
    Обратите внимание, я создал свойства по дефолту, но они пустые.
    У вас больше не будет крошиться проект
    import {ACTIVE_COUNTRY_ID, CITY, COUNTRIES, CATEGORIES, REGION, TITLE, COUNTRY} from "./mutation-types";
    
    
    export const state = () => ({
      [TITLE]: "",
      [CITY]: {
        id: 0,
        name: ""
      },
      [REGION]: {
        id: 0,
        name: ""
      },
      [ACTIVE_COUNTRY_ID]: 0,
      [COUNTRY]: {
        id: 0,
        name: ""
      },
      [COUNTRIES]: [],
      [CATEGORIES]: [],
    });
    Ответ написан
    3 комментария
  • Как использовать Nuxt в Docker?

    IgorPI
    @IgorPI
    Я так понимаю, что нужно использовать два конфига: docker-dev/docker-prod и nginx/dev nginx/prod
    Но я не могу понять как и тот и другой настроить правильно для двух режимов? Можете помочь?


    Привожу пример

    Development configuration
    # Development configuration
    version: "3.1"
    
    services:
    
      # Php application
      app:
        container_name: cc.app
        build:
          context: .
          dockerfile: ./docker/php/Dockerfile-dev
        restart: on-failure
        volumes:
          - .:/www
          - ./docker/php/log:/var/log
          - ./docker/php/usr/local/etc/php/conf.d:/usr/local/etc/php/conf.d
        depends_on:
          - db
        links:
          - db
        expose:
          - 9000
        environment:
          PHP_INI_SCAN_DIR: ":/usr/local/etc/php/conf.d"
    
    
      # Database
      db:
        image: percona:latest
        container_name: cc.db
        restart: on-failure
        ports:
          - 127.0.0.160:3306:3306
        expose:
          - 3306
        environment:
          - MYSQL_ROOT_PASSWORD=rk3kw1UDdqOEF4L1pmNkcyQ2oL
          - MYSQL_DATABASE=cc
          - MYSQL_ROOT_HOST=%
    
    
    
      # Nginx api server
      nginx-api:
        container_name: cc.nginx-api
        image: nginx:latest
        restart: on-failure
        volumes:
          - ./docker/nginx/dev/nginx.conf:/etc/nginx/nginx.conf
          - ./docker/nginx/dev/sites-enabled/vhost-api.conf:/etc/nginx/sites-enabled/vhost-api.conf
        ports:
          - 127.0.0.160:8090:80
        depends_on:
          - app
        expose:
          - 80
        command: ["nginx", "-g", "daemon off;"]
    
    
    
      # Nginx admin server
      nginx-admin:
        container_name: cc.nginx-admin
        image: nginx:latest
        restart: on-failure
        volumes:
          - ./docker/nginx/dev/nginx.conf:/etc/nginx/nginx.conf
          - ./docker/nginx/dev/sites-enabled/vhost-admin.conf:/etc/nginx/sites-enabled/vhost-admin.conf
        ports:
          - 127.0.0.160:8091:80
        depends_on:
          - app
        expose:
          - 80
        command: ["nginx", "-g", "daemon off;"]
    
    
      # Nginx secure server
      nginx-secure:
        container_name: cc.nginx-secure
        image: nginx:latest
        restart: on-failure
        volumes:
          - ./docker/nginx/dev/nginx.conf:/etc/nginx/nginx.conf
          - ./docker/nginx/dev/sites-enabled/vhost-secure.conf:/etc/nginx/sites-enabled/vhost-secure.conf
        ports:
          - 127.0.0.160:8092:80
        depends_on:
          - app
        expose:
          - 80
        command: ["nginx", "-g", "daemon off;"]


    Production configuration
    # Production configuration
    version: "3.1"
    
    services:
    
      # Php application
      app:
        container_name: ruintouch.app
        restart: always
        build:
          context: .
          dockerfile: ./docker/php/Dockerfile-prod
        expose:
          - 9000
    
    
    
      # Nginx api server
      nginx-api:
        container_name: ruintouch.nginx-api
        image: nginx:latest
        restart: always
        volumes:
          - ./docker/nginx/prod/nginx.conf:/etc/nginx/nginx.conf
          - ./docker/nginx/prod/sites-enabled/vhost-api.conf:/etc/nginx/sites-enabled/vhost-api.conf
        ports:
          - 8095:80
        expose:
          - 80
        command: ["nginx", "-g", "daemon off;"]
    
    
    
      # Nginx admin server
      nginx-admin:
        container_name: ruintouch.nginx-admin
        image: nginx:latest
        restart: always
        volumes:
          - ./docker/nginx/prod/nginx.conf:/etc/nginx/nginx.conf
          - ./docker/nginx/prod/sites-enabled/vhost-admin.conf:/etc/nginx/sites-enabled/vhost-admin.conf
        ports:
          - 8096:80
        expose:
          - 80
        command: ["nginx", "-g", "daemon off;"]
    
    
    
          #Nuxt publication
      nuxt-public:
        container_name: ruintouch.nuxt_public
        restart: always
        build:
          context: ./nuxt_public
          dockerfile: Dockerfile-prod
        ports:
          - "3001:3000"
        expose:
          - "3000"


    С "vue hot reload in docker" увы ((
    Ответ написан
  • Как вернуть противоположный бул тип короткой записью?

    IgorPI
    @IgorPI
    this.datas.TodayStatus = !this.datas.TodayStatus
    Ответ написан
    Комментировать
  • Как закрыть доступ к API и пускать только из приложения?

    IgorPI
    @IgorPI
    Что мешает использовать единый сервер авторизации?

    Например я реализовал это следующим образом.

    Вот мой стек.

    Nuxt
    Symfony

    Я хочу получить категории
    Роут /categories.get защищён.

    var request = require("request");
    
    var options = { method: 'GET',
      url: 'http://127.0.0.160:8091/categories.get',
      qs: { lvl: '0', offset: '0', count: '100' },
      headers: 
       {
         'Authorization': 'Bearer eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE1NzMyMTE3NzAsIm5iZiI6MTU3MzIxMTc3MCwiZXhwIjoxNTczMjE1MzcwLCJ1c2VyX2VtYWlsIjoiYWRtaW5AbWFpbC5jb20ifQ.0-VX8Pbv9l-ELXOoPV_6DTP1166X5DUvHZobXHh5xed2FRbNbbGMFrrai7khnApfywQeZjzasrqVwmcgrDq4kg',
         'cache-control': 'no-cache' 
       } };
    
    request(options, function (error, response, body) {
      if (error) throw new Error(error);
    
      console.log(body);
    });


    Итог.

    API и Nuxt защищены одним токеном.

    Как защищён роутинг в Nuxt?

    import {ACCESS_TOKEN} from "../store/mutation-types"
    
    
    export default async function ({store, redirect, $axios}) {
      
      const token = store.getters[ACCESS_TOKEN]
      console.log(token)
      if (!token) {
        return redirect("/login")
      }
      
      await $axios.$post(`${process.env.api}/security.checkAccessToken`, {token})
        .then(({code}) => {
          if (code === 0) {
            console.info("Token verified!")
            return redirect()
          }
          console.info("Token not verified!")
          return redirect("/login")
        }).catch((e) => {
          console.info(e)
          return redirect("/login")
        })
    }


    Мой ответ:
    Единый сервер авторизации.
    Ответ написан
    Комментировать
  • Как получить выбранные данные из v-select?

    IgorPI
    @IgorPI
    v-model решит вашу проблему.

    <v-col cols="12" sm="6">
              <v-select
                v-model="model"
                :items="states"
                label="Select"
                multiple
                chips
                hint="What are the target regions"
                persistent-hint
              ></v-select>
            </v-col>


    ...
    data () {
        return {
          model: [],
        }
      }
    ...
    Ответ написан
    5 комментариев
  • Как организовать страницу пользователя?

    IgorPI
    @IgorPI
    Проведите аналогию например с vk.com.
    Во Вконтакте есть API.

    Что бы получить данные своего профиля, мы передаём токен.

    Например:
    У вас есть метод https://api.site.com/account.getProfileInfo?token=...
    Выполнив get запрос, вы получите нечто похожее.
    {
    "response": {
    "first_name": "Кристина",
    "last_name": "Шипилова",
    "bdate": "20.3.1991",
    "bdate_visibility": 2,
    "city": {
    "id": 21940,
    "title": "Верхний Мамон"
    },
    "country": {
    "id": 1,
    "title": "Россия"
    },
    "home_town": "Воронеж В- Мамон",
    "maiden_name": "",
    "phone": "+7 *** *** ** 79",
    "relation": 1,
    "sex": 1,
    "status": "ОБОЖАЮ СИРЕНЬ&#128526;"
    }
    }


    Далее, рассовываете в нужные теги.

    Опять же, если речь идёт о конкретных действиях.
    Пример из моего проекта, только тяну не профиль, а категории.
    async asyncData({$axios}) {
          let category_items = []
          let promise_category = $axios.$get(`${process.env.api}/categories.get`,
              {
                params: {
                  lvl: 0,
                  count: 25,
                  offset: 0
                }
              })
              .then(({code, count, items}) => {
                if (code === 0) {
                  items.forEach((e) => {
                    category_items.push({
                      id: e.id,
                      name: e.name,
                      children: [],
                      deleted_loading: false,
                      lvl: e.lvl,
                      selected: false,
                    })
                  })
                }
              })
    
          await Promise.all([promise_category])
          return {
            category_items
          }
        },


    Нужен ли Vuex?
    Вам решать.
    Ответ написан
    1 комментарий
  • Как решить эту проблему?

    IgorPI
    @IgorPI
    Чтобы в родителе ловить эвенты, достаточно

    child
    <template>
      <div @click="$emit('click')"></div>
    </template>
    
    parent
    <template>
      <div class="warp">
        <item @click="" />
        <item @click="" />
        <item @click="" />
      </div>
    </template>
    Ответ написан
    Комментировать