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

    @MikUrrey
    Если productProfileCreditInfo всегда объект, когда он определен, то обычно работает такое:
    {{productProfileCreditInfo? productProfileCreditInfo.balance : ""}}
    то есть при отсутствии свойства в объекте оно просто не выведется, и это не приведет к исключению.
    Ответ написан
    Комментировать
  • Как лучше всего организовать связь данных дочерних компонентов и родительского?

    @MikUrrey
    В родительском компоненте, дочерние компонент отдельных данных не имеют, данные, как часть родительсикх данных, например, какого-то поля booksList.

    Скорее в компоненте, родительском для каталога книг, а глубже спускать в виде пропсов.
    И как это должно выглядить в коде, чтобы данные оставались связанными?

    <template>
      <lib-category v-model="booksList"></lib-category>
    </template>
    <script>
    import libCategory from "./libCategory.vue"
    default export {
      //...
      components: {libCategory},
      data() {
        return {
          booksList: [],
        }
      }
      //...
    }
    </script>


    libCategory.vue
    <template>
      <div v-for="(category, i) in booksListInner" :key="'i' + i">
         <!-- тут какое-то оформление категории -->
         ...
         <!-- а тут перечисляем книги, в нее входящие -->
         <lib-book v-for="(book, k) in category.children" :key="'k' + k" v-model="book"></lib-book>
      </div>
    </template>
    <script>
    import libBook from "./libBook.vue"
    default export {
      //...
      props: ['value'],
      components: {libBook},
      data() {
        return {
          booksListInner: [],
        }
      },
      watch: {
        value: {
          handler (value) { //связанность снаружи внутрь
            this.booksListInner = value
          },
          immediate: true,
          deep: true, //необходимо для объекта с вложенностью
        },
        booksListInner: {
          handler (booksListInner) { //связанность изнутри наружу
            this.$emit("input", booksListInner)
          },
          deep: true, //необходимо для объекта с вложенностью
        }
      }
    }
    </script>

    libBook.vue аналогично.
    Не знаю всех особенностей вашего списка, исхожу из минимального понимания. В зависимости от структуры данных могут быть нюансы в реактивности при добавлении новых элементов.
    Ответ написан
    Комментировать
  • Как организовать подстраницы во vue?

    @MikUrrey
    По смыслу Register = SignUp. Следовательно, Register - это должен быть Auth, или подобное более общее название - так было бы понятнее, семантичнее.
    Далее, если Register у вас не несет сам по себе какой-то функциональной и смысловой нагрузки и применяется только как "обертка", то лучше его не упоминать в маршрутизации и использовать только как "обертку".
    SignIn / SignUp:
    <template>
      <component :is="'auth-layout'">
        <!-- ... Vue-разметка для SignIn или SignUp ... -->
      </component>
    </template>
    <script>
      import AuthLayout from "@/layouts/AuthLayout";
      export default {
       components: {
         AuthLayout
       }
        //... код для SignIn или SignUp
      }
    </script>

    AuthLayout:
    <template>
      <div class="auth">
        <slot><!-- здесь отобразятся странички SignIn и SignUp --></slot>
      </div>
    </template>

    Т. е. целесообразно будет создать папку layouts, куда будут помещаться подобные глобальные шаблоны.
    Сами SignIn и SignUp размещайте исходя из размеров проекта и карты маршрутов: если маршрут идет через общий префикс, (/auth/sign-up, /auth/sign-in), то можно их поместить в папку auth, а можно и не помещать, если планируется, скажем, не более десятка страниц.
    Ответ написан
  • Почему выдает ошибку 404 при переходе в router vue?

    @MikUrrey
    Привет!
    Советую обратить внимание на вторую строку children, здесь присутствуют пропсы sub и formName, но маршруту нужно дать разрешение на их использование:
    { path: '/:sub/:formName', component: () => import('pages/Main.vue'), props: true }
    Ответ написан
    Комментировать
  • Как вызвать метод, который принимает event, когда props меняется?

    @MikUrrey
    Сделайте лучше вместо передачи event'а:
    <input ref="name" @blur="onBlur" ...

    ...
      onBlur() {
        const target = this.$refs.name
        ...
      }
    ...

    и тогда всё должно заработать
    Ответ написан
    Комментировать
  • Как вызвать метод в другом компоненте, который находится на другом уровне?

    @MikUrrey
    Из всех решений наилучшими будет пара приемов, которые сводятся к выводу взаимодействий на глобальный уровень.
    1) Как уже подсказали, event bus. Но лучше всего не так, как рекомендует документация, а на экземпляре $root. Например:

    //один из компонентов сообщает, что надо что-то выполнить
    methods: {
      iChangeSomething(value) {
        this.$root.$emit("something-changed", value)
      }
    }

    //другой это выполняет силами своего метода
    methods: {
      somethingChanged(value) {
        console.log({value})
      }
    },
    created() {
        this.$root.$on("something-changed", this.somethingChanged )
    },
    destroy() {
        this.$root.$off("something-changed", this.somethingChanged )
    }


    2) Плагин, который "сшит" с компонентом, и транслирует его метод в глобальную область.
    //определяем
    //@/plugins/user.js
    let doSomething = () => null
    
    export default function install(Vue) => {
      
      const MyComponent = {
        name: "MyComponent ",
        methods: {
          doSomething() {
             console.log("I'm doing something!")
          }
        },
        created() {
          doSomething = this.doSomething
        },
        render: function (createElement) {
          //...
        }
      }
      
      Vue.component('MyComponent', MyComponent)
      Vue.prototype.$doSomething = doSomething
    }

    //подключаем
    //main.js
    import {VuePlugin as User} from "@/plugins/user"
    Vue.use(User)
    new Vue({ ...

    //используем
    methods: {
       doSomething() {
          this.$doSomething()
       }
    }

    <!-- или так -->
    <button @click="$doSomething">BUTTON</button>

    Но здесь - один нюанс: придется прописывать render не тегами, а функциями.
    Поэтому решение годно больше для некоего универсального пакета, который вы сможете потом повторно использовать в других проектах с минимальными изменениями.

    Vuex - возможно, но не всегда уместно. Это инструмент работы с общими данными, он целесообразен в более-менее крупных проектах. Если стоит задача типа "чтобы от различных действий затемнялась общая панелька в UI", то лучше сделать панельку плагином, чем заводить ее свойства в store.
    Ответ написан
  • Как передать содержимое именованного слота потомку в render-функции?

    @MikUrrey Автор вопроса
    Оказалось все просто, делюсь решением.
    Нужно передать статичные слоты в качестве потомков (третий аргумент createElement), и проставлять в data каждого потомка соответствующий slot:
    export default {
       name: "form-element",
       render(h) {
          let data = {
              //.....................................
          };
          //.....................................
          let slots = []
          for(let slot in this.$slots) {
            slots.push(h('template', {slot}, this.$slots[slot]))
          }
          return h(component, data, slots);
       }
    }
    Ответ написан
    Комментировать
  • Как кастомизировать кнопки в vue-tiny-slider слайдере?

    @MikUrrey
    :prev-button="prevButton"
    ...
    ...
    computed: {
        prevButton() {
            return "<div class='button'>назад</div>"
        }
    }
    Ответ написан
  • Как правильно выполнить код внутри шаблона Vue?

    @MikUrrey Автор вопроса
    Нашел лишь единственный способ: сделать собственный компонент.
    <badge-cell :params="join('status', 'id', props.value)">{{props.value}}</badge-cell>

    вот в нутри компонента как раз переданный объект декомпозируется в необходимые для вывода данные.
    Ответ написан
    Комментировать