ZorNet.Ru — сайт для вебмастера » JavaScript и jQuery » Выпадающее многоуровневое меню Vue.js

Выпадающее многоуровневое меню Vue.js

Выпадающее многоуровневое меню Vue.js
Легкий и простой в использовании компонент Vue.js для навигации, что выделяет элементы меню до целевого раздела при нажатии при использовании файла. Создайте меню с разворачиваемым деревом с помощью рекурсивных компонентов Vue.js. Было бы неплохо визуально определить «глубину» дочернего компонента, чтобы пользователь получил представление. Чтобы продемонстрировать, как эффективно использовать рекурсивные компоненты сжимаемого древовидного меню.

Рекурсивные компоненты полезны для отображения комментариев в блоге, вложенных меню или в целом, где родитель и потомок одинаковы, хотя и с разным содержанием. Дерево рекурсивных компонентов пользовательского интерфейса будет визуальным представлением некоторой рекурсивной структуры данных. В этом уроке мы будем использовать древовидную структуру, где каждый узел является объектом.

Стильное многоуровневое древовидное меню Vue.js.

В рабочем виде:



Установка:

HEAD

Код
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>

HTML

Код
<div class="navigatsiya centralna" id="app">
  <ul class="samoletovosa-menyu">
  <item :model="treeData"></item>
  </ul>
</div>

CSS

Код
.samoletovosa-menyu {
  width: 85%;
  max-width: 550px;
  margin: 1em auto;
  background: rgba(27, 27, 27, 0.7);
  box-shadow: -1px 8px 10px 3px rgba(0, 0, 0, 0.3);
}

.samoletovosa-menyu li {
  user-select: none;
}

.samoletovosa-menyu li span {
  float: right;
}

.samoletovosa-menyu label, .samoletovosa-menyu a {
  position: relative;
  display: block;
  padding: 16px 16px 16px 54px;
  box-shadow: inset 0 -1px #000;
  color: #ffffff;
}
.no-touch .samoletovosa-menyu label:hover,
.no-touch .samoletovosa-menyu a:hover {
  background: #52565d;
}
.samoletovosa-menyu label::before,
.samoletovosa-menyu label::after,
.samoletovosa-menyu a::after {
  content: '';
  display: inline-block;
  width: 16px;
  height: 16px;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}
.samoletovosa-menyu label {
  cursor: pointer;
}

.samoletovosa-menyu label span {
  float: right;
  color: #828282;
}

.samoletovosa-menyu li.file > label::before {
content: "\f15b";  
}
.samoletovosa-menyu li.folder > label::before {
  content: "\f054";
}

.samoletovosa-menyu li.file > label::before {
content: "\f15b";  
}
.samoletovosa-menyu li.add > label::before {
  content: "\f067";
}

.samoletovosa-menyu label::before {
  /* arrow icon */
  font: normal normal normal 14px/1 FontAwesome;
  left: 18px;
  transform: translateY(-50%);
  transition: transform 0.3s;
}
.samoletovosa-menyu label.open::before {
  transform: translateY(-25%) rotate(90deg);
}

.samoletovosa-menyu ul label, .samoletovosa-menyu ul a {
  background: #1f1e1e;
  box-shadow: inset 0 -1px #353535;
  padding-left: 82px;
}
.no-touch .samoletovosa-menyu ul label:hover,
.no-touch .samoletovosa-menyu ul a:hover {
  background: #3c3f45;
}
.samoletovosa-menyu > li:last-of-type > label,
.samoletovosa-menyu > li:last-of-type > a,
.samoletovosa-menyu > li > ul > li:last-of-type label,
.samoletovosa-menyu > li > ul > li:last-of-type a {
  box-shadow: none;
}
.samoletovosa-menyu ul label::before {
  left: 36px;
}
.samoletovosa-menyu ul label::after,
.samoletovosa-menyu ul a::after {
  left: 59px;
}
.samoletovosa-menyu ul ul label,
.samoletovosa-menyu ul ul a {
  padding-left: 100px;
}
.samoletovosa-menyu ul ul label::before {
  left: 54px;
}
.samoletovosa-menyu ul ul label::after,
.samoletovosa-menyu ul ul a::after {
  left: 77px;
}
.samoletovosa-menyu ul ul ul label,
.samoletovosa-menyu ul ul ul a {
  padding-left: 118px;
}
.samoletovosa-menyu ul ul ul label::before {
  left: 72px;
}
.samoletovosa-menyu ul ul ul label::after,
.samoletovosa-menyu ul ul ul a::after {
  left: 95px;
}

JS

Код
var treeData = {
  name: "ZORNET.RU",
   
  children: [
  {
  name: "Первый раздел",
  children: [{ name: "Под категория #1" }, { name: "Под категория #2" }]
  },
  {
  name: "Второй раздел",
   
  children: [{ name: "Первый запрос" }, { name: "Второй запрос" }]
  },
  { name: "Третий запрос" }
  ]
};

Vue.component("item", {
  template: `<li :class="[isFolder ? 'folder' : 'file']">
  <label
  :class="{'open': open}"
  @click="toggle"
  @dblclick="changeType">
  {{ model.name }}
  <span v-if="isFolder">{{ isFolder ? model.children.length : '' }}</span>
  </label>
  <ul v-show="open" v-if="isFolder" :class="{'open': open}">
  <item
  v-for="(model, index) in model.children"
  :key="index"
  :model="model">
  </item>
  <li class="add" @click="addChild"><label>Добавить новый материал</label></li>
  </ul>
  </li>`,
  props: {
  model: Object
  },
  data: function() {
  return {
  open: true
  };
  },
  computed: {
  isFolder: function() {
  return this.model.children && this.model.children.length;
  }
  },
  methods: {
  toggle: function() {
  if (this.isFolder) {
  this.open = !this.open;
  }
  },
  changeType: function() {
  if (!this.isFolder) {
  Vue.set(this.model, "children", []);
  this.addChild();
  this.open = true;
  }
  },
  addChild: function() {
  this.model.children.push({
  name: "Новый предмет"
  });
  }
  }
});

new Vue({
  el: "#app",
  data: {
  treeData: treeData
  }
   
});

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

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

Демонстрация
2020-03-20 Загрузок: 1 Просмотров: 239 Комментарий: (1)

Поделиться в социальных сетях

Материал разместил

Оставь свой отзыв

Комментарий: 1
Kosten
Kosten 2020-03-20 02:381
0
Сама идея понравилась, в плане навигаций, но когда создал описание, что только на зарубежных сайтах нашел вполне развернутую информацию. А вот само меню реально в тупик поставило.

Ведь если смотреть HTML пару классов с некоторыми элементами, то вот под запросы там место не оказалось, где устанавливать ссылки. Что в дальнейшем понял, что нужно прописывать в прикрепленном JS, но здесь в первые такой расклад встречаю.

Возможно кто пользовался или знает как и где нужно прописать ссылки, или вообще это возможно, по пожалуйста подскажите.
avatar