Как обработать форму Dynami c, используя vue. js - PullRequest
0 голосов
/ 12 июля 2020

Итак, я создаю вариант фильтра для своего веб-сайта, и его параметры загружаются из БД, и из-за этого я считаю, что не могу использовать обычный v-model для выполнения этой работы.

I имеют разные параметры фильтра, такие как Categories и Companies, и их параметры загружаются из БД, поэтому они могут иметь 5 или 10 вариантов.

Снимок экрана с фильтром на веб-сайте (лучше для визуализации) :

image

body {
    position: relative;
  }

  .save_filter{
    height: 40px;
  }

  .save_filter button {
    background: black;
    color: white;
    width: 100%;
    height: 100%;
    border: 0;
    border-radius: 5px;
    cursor: pointer;
  }

  .see_offer{
    position: absolute;
    bottom: 0;
    width: 100%;
    height: 50px;
    background-color: black;
    border-bottom-left-radius: 5px;
    border-bottom-right-radius: 5px;
  }

  .see_offer span{
    position: relative;
    left: calc(50% - 39.93px);
    top: calc(50% - 9.2px);
    color: white;
  }

  .main-body {
    max-width  : 1270px;
    font-family: "Ubuntu", sans-serif;
    margin     : 0 auto;
  }

  .page-content {
    padding-top: 70px;
    position   : relative;
    margin     : 0 auto;
  }

  .page-content .container {
    display        : flex;
    justify-content: space-evenly;
  }

  .page-content .first-section .category-title span {
    font-family   : "Segoe UI Regular";
    font-style    : normal;
    font-weight   : 600;
    font-size     : 23px;
    letter-spacing: 0.21em;
    color         : #1D1D25;
    position      : relative;
  }

  .page-content .first-section .category-title span::after {
    content      : "";
    display      : block;
    position     : absolute;
    border       : 2px solid #1D1D25;
    border-radius: 20px;
    width        : 96%;
    bottom       : -11px;
    left         : 0;

  }

  .page-content .second-section {
    padding-top: 44px;
    display    : flex;
  }

  .page-content .second-section .left {
    flex: 1;
  }

  .page-content .second-section .right {
    flex: 3;
  }

  .page-content .second-section .left .left-container {
    width    : 200px;
    min-width: 200px;
  }

  .second-section .left .left-container .filter {
    display       : flex;
  }

  .second-section .combo-group {
    position: relative;
    width   : 100%;
  }

  .second-section .combo-group select {
    font-family       : "Ubuntu", sans-serif;
    font-size         : 14px;
    color             : black;
    width             : 100%;
    box-sizing        : border-box;
    border-radius     : 7px;
    padding           : 0 20px;
    height            : 34px;
    -webkit-appearance: none;
    -moz-appearance   : none;
    border            : 1px solid #1D1D25;

    background-image: linear-gradient(45deg, transparent 50%, #010101 50%),
      linear-gradient(135deg, #010101 50%, transparent 50%);
    background-position: calc(100% - 20px) calc(1em + 1px),
      calc(100% - 15px) calc(1em + 1px), 100% 0px;
    background-size  : 5px 5px, 5px 5px, 2.5em 2.5em;
    background-repeat: no-repeat;
    background-color : white;
  }

  .second-section .combo-group select:focus {
    border-color: lightblue;
  }

  .second-section .left .left-container .companies {
    padding-bottom: 54px;
  }

  .second-section .left .left-container .companies p {
    margin-top: 0;
    font-size : 16px;
  }

  .chk-container {
    display            : block;
    position           : relative;
    padding-left       : 27px;
    margin-bottom      : 12px;
    cursor             : pointer;
    font-size          : 16px;
    -webkit-user-select: none;
    -moz-user-select   : none;
    -ms-user-select    : none;
    user-select        : none;
  }

  .chk-container input {
    position: absolute;
    opacity : 0;
    cursor  : pointer;
    height  : 0;
    width   : 0;
  }

  .chk-container input:checked~.checkmark {
    background-color: #1D1D25;
  }

  .chk-container input:checked~.checkmark {
    height: 20px;
    width : 20px;
    border: none;
  }

  .checkmark:after {
    content : "";
    position: absolute;
    display : none;
  }

  /* Show the checkmark when checked */
  .chk-container input:checked~.checkmark:after {
    display: block;
  }

  /* Style the checkmark/indicator */
  .chk-container .checkmark:after {
    left             : 7px;
    top              : 3px;
    width            : 4px;
    height           : 10px;
    border           : solid white;
    border-width     : 0 2px 2px 0;
    -webkit-transform: rotate(45deg);
    -ms-transform    : rotate(45deg);
    transform        : rotate(45deg);
  }

  .chk-container .checkmark {
    position        : absolute;
    top             : 0;
    left            : 0;
    height          : 20px;
    width           : 20px;
    background-color: #1D1D25;
  }

  .second-section .left .left-container .price {
    padding-bottom: 54px;
  }

  .second-section .left .left-container .price p {
    margin-top   : 0;
    margin-bottom: 6px;
    font-size    : 16px;
  }

  .slider {
    -webkit-appearance: none;
    width             : 100%;
    height            : 4px;
    background        : #C4C4C4;
    outline           : none;
    -webkit-transition: .2s;
    transition        : opacity .2s;
    border-radius     : 10px;
  }

  .slider:hover {
    opacity: 1;
  }

  .slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance        : none;
    width             : 12px;
    height            : 12px;
    background        : #1D1D25;
    cursor            : pointer;
    border-width      : 0;
    border-radius     : 50%;
  }

  .slider::-moz-range-thumb {
    width        : 12px;
    height       : 12px;
    background   : #1D1D25;
    cursor       : pointer;
    border-width : 0;
    border-radius: 50%;
  }

  .second-section .products {
    display        : flex;
    flex-wrap      : wrap;
    justify-content: space-around;
  }

  .second-section .products .box {
    position: relative;
    max-width       : 260px;
    width           : 260px;
    background-color: #F7F7F7;
    margin-bottom   : 62px;
  }

  .second-section .products .box .image {
    text-align     : center;
    padding-top    : 30px;
    padding-bottom : 25px;
    min-height     : 157px;
    display        : flex;
    align-items    : center;
    justify-content: center;
  }

  .second-section .products .box .image img {
    max-width: 200px;

  }

  .second-section .products .box .names {
    text-align    : center;
    font-size     : 18px;
    line-height   : 21px;
    margin-left: 10px;
    margin-right: 10px;
    padding-bottom: calc(45% + 10px);
  }

  .second-section .products .box .star {
    text-align    : center;
    padding-bottom: 17px;
  }

  .second-section .products .box .price {
    position: absolute;
    width: 100%;
    bottom: 50px;
    text-align: center;
    padding-bottom: 21px;
    color: #1d1d25;
    font-weight: 700;
  }

  .second-section .products .box .price span {
    font-size  : 24px;
    line-height: 28px;
  }

  .second-section .products .box .price span:first-child {
    font-size: 16px;
    line-height: 18px;
    vertical-align: super;
  }

  .second-section .pagination-container {
    display        : flex;
    justify-content: center;
    margin-top     : 15px;
  }

  .second-section .pagination-container span,
  .second-section .pagination-container a {
    color       : #1D1D25;
    background  : none;
    box-shadow  : none;
    border-width: 0;
    font-size   : 14px;
    margin-right: 0;
  }

  .second-section .pagination-container .active .current {
    border-radius: 0;
    border-bottom: 1px solid #1D1D25;

  }

  .second-section .pagination-container li .page-link {
    border-radius: 0;
    border-bottom: 1px solid #C4C4C4;
  }

  .second-section .pagination-container .current.prev,
  .second-section .pagination-container .current.next,
  .second-section .pagination-container .page-link.prev,
  .second-section .pagination-container .page-link.next {
    display     : flex;
    align-items : center;
    border-width: 0;
  }

  .second-section .pagination-container .prev-image {
    margin-right: 12px;
  }

  .second-section .pagination-container .next-image {
    margin-left: 12px;
  }

  @media screen and (max-width: 1100px) and (min-width: 769px) {
    .second-section .products .box {
      width           : 49%;
      /* margin-bottom: 50px; */
    }
  }

  @media screen and (max-width: 1023px) and (min-width: 769px) {

    .page-content {
      padding-top: 80px;
      width      : calc(100% - 5em);
    }
  }

  @media screen and (max-width: 768px) {
    .text-align {
      text-align: center;
    }

    .page-content {
      padding-top: 20px;
    }

    .page-content .second-section {
      padding-top: 30px;
      display    : block;
      width      : 90%;
      margin     : 0 auto;
    }

    .page-content .second-section .left {
      padding-right: 0px;
      padding-top  : 45px;
      margin-left  : 0px;
    }

    .page-content .second-section .left .left-container {
      width: 100%;
    }

    .second-section .left .left-container .filter {
      padding-bottom: 35px;
    }

    .second-section .products {
      padding-top: 35px;
    }

    .second-section .products .box {
      width        : 48%;
      margin-bottom: 5px;
    }

    .page-content .second-section .title span {
      font-size: 25px;
    }

    .page-content .second-section .container {
      flex-direction: column;
    }

    .page-content .second-section .right {
      padding-right: 0px;
      font-size    : 14px;
    }

    .second-section .products .box .image {
      height        : 100px;
      padding-top   : 20px;
      padding-bottom: 10px;
    }

    .second-section .products .box .image img {
      max-width : 170px;
      max-height: 100px;
    }

    .second-section .products .box .names {
      font-size     : 13px;
      line-height   : 15px;
      padding-bottom: 13px;
    }

    .second-section .products .box .star {
      padding-bottom: 11px;
    }

    .second-section .products .box .price {
      padding-bottom: 18px;
    }

    .second-section .products .box .price span:nth-child(1) {
      font-size  : 14px;
      line-height: 18px;
    }

    .second-section .products .box .price span:nth-child(2) {
      font-size  : 18px;
      line-height: 21px;
    }
  }
<section class="second-section">
  <div class="left">
    <div class="left-container">
      <form @submit.prevent="processFilter">
        <div class="filter">
          <div class="combo-group mobile">
            <select>
              <option v-for="sub in subCategories" :key="sub.id">
                {{sub.value}}
              </option>
            </select>
          </div>
          <div class="combo-group mobile">
            <select>
              <option v-for="company in companies" :key="company.id">
                {{company.name}}
              </option>
            </select>
          </div>
        </div>
        <div class="companies desktop">
          <p>Categories</p>
          <label class="chk-container" v-for="sub in subCategories" :key="sub.id">
                    {{sub.value}}
                    <input type="checkbox" id="chk-account-standard" />
                    <span class="checkmark"></span>
                  </label>
        </div>
        <div class="companies desktop">
          <p>Companies</p>
          <label class="chk-container" v-for="company in companies" :key="company.id">
                    {{company.name}}
                    <input type="checkbox" id="chk-account-standard" />
                    <span class="checkmark"></span>
                  </label>
        </div>
        <div class="price">
          <p>Price</p>
          <span id="min-value">10</span><span> - </span><span>1.000</span>
          <div class="pt-10">
            <input type="range" min="10" max="1000" value="1" class="slider" id="priceRang">
          </div>
        </div>
        <div class="save_filter">
          <button type="submit">Filter</button>
        </div>
      </form>
    </div>
  </div>
</section>

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

1 Ответ

1 голос
/ 12 июля 2020

Вы можете использовать для этого v-model, вам просто нужен отдельный массив для хранения выбранных опций. Вот пример в Vue документах.

Для вашего случая вам нужно установить value элемента input для поля, которое вы хотите использовать, а затем можете используйте v-model для сохранения выбранных входов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...