Как динамически отображать мобильное меню с Tailwind и Vue.js? - PullRequest
0 голосов
/ 29 сентября 2019

Я пытаюсь создать адаптивное меню с Tailwind CSS и Vue.js. В настоящее время у меня есть этот шаблон:

<template>
<nav class="flex items-center justify-between flex-wrap bg-pink-100 p-6">
    <div class="flex items-center flex-shrink-0  mr-6">
        <span class="font-semibold text-xl tracking-tight">Pixie</span>
    </div>
    <div class="block md:hidden" >
        <button @click='clickMenu' class="flex items-center px-3 py-2 border rounded" >
        <svg class="fill-current h-3 w-3" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><title>Menu</title><path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"/></svg>
        </button>
    </div>
    <div class="w-full flex-grow md:flex md:items-center md:w-auto" v-if="menuVisible">
        <div class="text-sm md:flex-grow">
        <a href="#responsive-header" class="block mt-4 md:inline-block md:mt-0 hover:text-white mr-4">
            Features
        </a>
        <a href="#responsive-header" class="block mt-4 md:inline-block md:mt-0  hover:text-white mr-4">
            Pricing
        </a>
        <a href="#responsive-header" class="block mt-4 md:inline-block md:mt-0  hover:text-white">
            Blog
        </a>
        </div>
        <div>
        <a href="#" class="inline-block text-sm px-4 py-2 leading-none border rounded  text-white bg-blue-500 hover:border-transparent mt-4 md:mt-0">Sign Up</a>
        <a href="#" class="inline-block text-sm px-4 py-2 leading-none border rounded  hover:border-transparent mt-4m d:mt-0">Log In</a>
        </div>
    </div>
</nav>
</template>

С этим Javascript:

<script>
export default {
    data: function() {
        return {
            menuVisible: true
        }
    },
    methods: {
        clickMenu: function() {
            this.menuVisible = !this.menuVisible
        }
    }

}
</script>

Все, что я хочу сделать, - это изначально скрыть мобильное меню, когда точка останова достигает 'sm' в Tailwind. Это означало бы, что пользователь должен будет нажать кнопку меню, чтобы увидеть меню, которое, я думаю, является ожидаемым поведением на мобильных устройствах.

Я не хочу создавать 2 отдельных меню, которые отображаются на разных точках остановакак я хочу, чтобы избежать дублирования кода. Есть ли способ получить доступ к текущей точке останова Tailwind в Vue.js? Это означало бы, что я мог бы установить menuVisible для вычисляемого свойства, которое позволяет ему быть видимым, только если точка останова - рабочий стол или планшет, или если пользователь щелкнул меню.

Или есть еще лучший способ сделать это?

Спасибо за любую помощь!

1 Ответ

0 голосов
/ 30 сентября 2019

Одним из способов достижения этой цели может быть настройка TailwindCSS-точек останова в вашем tailwind.config.js и последующее повторное использование этого файла для импорта значений точек останова в ваш компонент Menu.

Здесь мы устанавливаем точки останова TailwindCSS в соответствии с документацией TailwindCSS . На самом деле мы просто устанавливаем значения точек останова TailwindCSS по умолчанию, но их установка делает их доступными через файл.

//tailwind.config.js

module.exports = {
  theme: {
    screens: {
      sm: '640px',
      md: '768px',
      lg: '1024px',
      xl: '1280px'
    }
  }
}

Теперь, в вашем Menu.vue, вы можете импортировать точку останова из вашей TailwindCSS-config и записатьнеобходимая функция, чтобы проверить, меньше ли текущий размер окна, чем точка останова md. Если это не так, вы можете просто вернуть true. Если это так, вы можете проверить, открывалось ли меню.

// Menu.vue
<script>
const tailwindConfig = require('tailwind.config.js')

export default {
  data() {
    return {
      windowWidth: 0,
      menuOpen: false,
      mdBreakpoint: Number(tailwindConfig.theme.screens.md.replace('px', ''))
    }
  },
  computed: {
    menuVisible() {
      return this.windowWidth > mdBreakpoint ? true : this.menuOpen

    }
  },
  methods: {
    updateWindowSize() {
      this.windowWidth = window.innerWidth
    },
    clickMenu() {
      this.menuOpen = !this.menuOpen
    }
  },
  mounted() {
    this.updateWindowSize()
    window.addEventListener('resize', this.updateWindowSize)
  },
  beforeDestroyed() {
    window.removeEventListener('resize', this.updateWindowSize)
  }
}
</script>
...