Material Design for Bootstrap 4 (Vue version) 소개
내비게이션이 MDBootstrap 그대로라면 vue-router의 router-link를 사용할 수 없어,
구성 요소를 약간 로컬로 변경했습니다.
완성된 화면

필요한 패키지 설치
yarn add mdbootstrap bootstrap-vue classnames
yarn add @types/classnames --dev
 템플릿의 구성 요소를 git clone으로 떨어뜨립니다.
yarn add mdbootstrap bootstrap-vue classnames
yarn add @types/classnames --dev
git clone https://github.com/mdbootstrap/Vue-Bootstrap-with-Material-Design.git mdb
템플릿에서 vue-cli로 만든 기존 프로젝트로 소스 복사
mkdir ~/works/todo/src/conponents/mdbootstrap
cp ~/works/mdb/src/components/* ~/works/todo/src/mdbootstrap
mkdir ~/works/todo/src/mixins
cp ~/works/mdb/src/mixins/* ~/works/todo/src/mixins
main.ts에 리플 효과의 CSS를 import 추가
src/main.tsimport Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import './registerServiceWorker';
import 'bootstrap/dist/css/bootstrap.css';
import 'mdbootstrap/css/mdb.css';
+ import './components/mdbootstrap/Waves.css';
Vue.config.productionTip = false;
new Vue({
  router,
  store,
  render: (h) => h(App),
}).$mount('#app');
 App.vue 네비게이션을 MDBootstrap 네비게이션으로 변경
src/App.vue<template>
  <div id="app">
    <!--Navbar-->
    <navbar position="top" class="indigo navbar-dark" name="ToDo" to="/" scrolling>
      <navbar-collapse>
        <navbar-nav>
          <navbar-item to="/" active exact waves-fixed>Home</navbar-item>
          <navbar-item to="/about" waves-fixed>About</navbar-item>
          <navbar-item to="/tasks" waves-fixed>Tasks</navbar-item>
          <!-- Dropdown -->
          <dropdown tag="li" class="nav-item">
            <dropdown-toggle tag="a" navLink color="indigo" waves-fixed>Dropdown</dropdown-toggle>
            <dropdown-menu>
              <dropdown-item>Action</dropdown-item>
              <dropdown-item>Another action</dropdown-item>
              <dropdown-item>Something else here</dropdown-item>
            </dropdown-menu>
          </dropdown>
        </navbar-nav>
          <!-- Search form -->
        <form class="form-inline">
          <mdinput type="text" placeholder="Search" aria-label="Search" label navInput waves waves-fixed/>
        </form>
      </navbar-collapse>
    </navbar>
    <div class="container">
      <router-view/>
    </div>
  </div>
</template>
<script>
import Navbar from "@/components/mdbootstrap/Navbar.vue";
import NavbarItem from "@/components/mdbootstrap/NavbarItem.vue";
import NavbarNav from "@/components/mdbootstrap/NavbarNav.vue";
import NavbarCollapse from "@/components/mdbootstrap/NavbarCollapse.vue";
import Container from "@/components/mdbootstrap/Container.vue";
import Dropdown from "@/components/mdbootstrap/Dropdown.vue";
import DropdownItem from "@/components/mdbootstrap/DropdownItem.vue";
import DropdownMenu from "@/components/mdbootstrap/DropdownMenu.vue";
import DropdownToggle from "@/components/mdbootstrap/DropdownToggle.vue";
import drop from "@/mixins/drop";
import Mdinput from "@/components/mdbootstrap/MdInput.vue";
export default {
  components: {
    Navbar,
    NavbarItem,
    NavbarNav,
    NavbarCollapse,
    Container,
    Dropdown,
    DropdownItem,
    DropdownMenu,
    DropdownToggle,
    Mdinput
  },
  mixins: [drop]
};
</script>
<style lang="scss">
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
.navbar .dropdown-menu a:hover {
  color: inherit !important;
}
.fixed-top {
  position: sticky;
}
</style>
 Navbar의 구성 요소를 router-link로 전환하도록 변경
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import './registerServiceWorker';
import 'bootstrap/dist/css/bootstrap.css';
import 'mdbootstrap/css/mdb.css';
+ import './components/mdbootstrap/Waves.css';
Vue.config.productionTip = false;
new Vue({
  router,
  store,
  render: (h) => h(App),
}).$mount('#app');
src/App.vue
<template>
  <div id="app">
    <!--Navbar-->
    <navbar position="top" class="indigo navbar-dark" name="ToDo" to="/" scrolling>
      <navbar-collapse>
        <navbar-nav>
          <navbar-item to="/" active exact waves-fixed>Home</navbar-item>
          <navbar-item to="/about" waves-fixed>About</navbar-item>
          <navbar-item to="/tasks" waves-fixed>Tasks</navbar-item>
          <!-- Dropdown -->
          <dropdown tag="li" class="nav-item">
            <dropdown-toggle tag="a" navLink color="indigo" waves-fixed>Dropdown</dropdown-toggle>
            <dropdown-menu>
              <dropdown-item>Action</dropdown-item>
              <dropdown-item>Another action</dropdown-item>
              <dropdown-item>Something else here</dropdown-item>
            </dropdown-menu>
          </dropdown>
        </navbar-nav>
          <!-- Search form -->
        <form class="form-inline">
          <mdinput type="text" placeholder="Search" aria-label="Search" label navInput waves waves-fixed/>
        </form>
      </navbar-collapse>
    </navbar>
    <div class="container">
      <router-view/>
    </div>
  </div>
</template>
<script>
import Navbar from "@/components/mdbootstrap/Navbar.vue";
import NavbarItem from "@/components/mdbootstrap/NavbarItem.vue";
import NavbarNav from "@/components/mdbootstrap/NavbarNav.vue";
import NavbarCollapse from "@/components/mdbootstrap/NavbarCollapse.vue";
import Container from "@/components/mdbootstrap/Container.vue";
import Dropdown from "@/components/mdbootstrap/Dropdown.vue";
import DropdownItem from "@/components/mdbootstrap/DropdownItem.vue";
import DropdownMenu from "@/components/mdbootstrap/DropdownMenu.vue";
import DropdownToggle from "@/components/mdbootstrap/DropdownToggle.vue";
import drop from "@/mixins/drop";
import Mdinput from "@/components/mdbootstrap/MdInput.vue";
export default {
  components: {
    Navbar,
    NavbarItem,
    NavbarNav,
    NavbarCollapse,
    Container,
    Dropdown,
    DropdownItem,
    DropdownMenu,
    DropdownToggle,
    Mdinput
  },
  mixins: [drop]
};
</script>
<style lang="scss">
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
.navbar .dropdown-menu a:hover {
  color: inherit !important;
}
.fixed-top {
  position: sticky;
}
</style>
Navbar의 구성 요소를 router-link로 전환하도록 변경
src/components/mdbootstrap/Navbar.vue
<template>
  <nav :class="className" :is="tag">
-    <a :href="href" class="navbar-brand">{{name}}
+    <router-link :to="to" class="navbar-brand">{{name}}
      <img v-if="src" :src="src" :alt="alt"/>
-    </a>
+    </router-link>
    <button class="navbar-toggler" type="button" data-toggle="collapse" :data-target="target" aria-controls="navbarSupportedContent"
        aria-expanded="false" aria-label="Toggle navigation" v-on:click="toggle">
      <span class="navbar-toggler-icon"></span>
    </button>
    <slot></slot>
  </nav>
</template>
<script>
//
//
//
//
//
//
//
//
//
//
//
//
//
//
import classNames from "classnames";
export default {
  props: {
    tag: {
      type: String,
      default: "nav"
    },
    expand: {
      type: String,
      default: "large"
    },
    position: {
      type: String
    },
-    href: {
+    to: {
      type: String
    },
    src: {
      type: String
    },
    alt: {
      type: String
    },
    name: {
      type: String
    },
    target: {
      type: String,
      default: "#navbarSupportedContent"
    },
    scrolling: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      className: classNames(
        "navbar",
        "navbar-dark",
        this.expand === "small"
          ? "navbar-expand-sm"
          : this.expand === "medium"
            ? "navbar-expand-md"
            : this.expand === "large" ? "navbar-expand-lg" : "navbar-expand-lx",
        this.position === "top"
          ? "fixed-top"
          : this.position === "bottom" ? "fixed-bottom" : "",
        this.scrolling ? "scrolling-navbar" : ""
      ),
      scrolled: false,
      toggleClicked: true
    };
  },
  methods: {
    toggle(e) {
      if (this.toggleClicked) {
        this.collapse.classList.toggle("show-navbar");
        this.collapse.classList.remove("hide-navbar");
        this.collapse.classList.toggle("collapse");
        this.collapse.style.overflow = "hidden";
        this.collapseOverflow = setTimeout(() => {
          this.collapse.style.overflow = "initial";
        }, 300);
        this.toggleClicked = false;
      } else {
        this.collapse.classList.add("hide-navbar");
        this.collapse.classList.toggle("show-navbar");
        this.collapse.style.overflow = "hidden";
        this.collapseOverflow = setTimeout(() => {
          this.collapse.classList.toggle("collapse");
          this.collapse.style.overflow = "initial";
        }, 300);
        this.toggleClicked = true;
      }
    },
    handleScroll() {
      if (window.scrollY > 100 && this.scrolled === false) {
        this.$el.style.paddingTop = 5 + "px";
        this.$el.style.paddingBottom = 5 + "px";
        this.scrolled = true;
      } else if (window.scrollY < 100 && this.scrolled === true) {
        this.$el.style.paddingTop = 12 + "px";
        this.$el.style.paddingBottom = 12 + "px";
        this.scrolled = false;
      }
    }
  },
  mounted() {
    this.collapse = this.$el.children.navbarSupportedContent;
    this.collapse.classList.add("collapse");
  },
  created() {
    window.addEventListener("scroll", this.handleScroll);
  },
  destroyed() {
    window.removeEventListener("scroll", this.handleScroll);
  }
};
</script>
<style scoped>
.scrolling-navbar {
  transition: padding 0.5s;
}
.nav-item {
  position: relative;
}
</style>
NavbarItem의 구성 요소를 router-link에서 전환하도록 변경
src/components/mdbootstrap/NavbarItem.vue<template>
  <li :is="tag" :class="[className, {'ripple-parent': waves}]" @click="wave">
-    <a :href="href" class="nav-link"><slot></slot></a>
+    <router-link :to="to" class="nav-link" :exact="exact"><slot></slot></router-link>
  </li>
</template>
<script>
//
//
//
//
//
//
import classNames from "classnames";
import waves from "../../mixins/waves";
export default {
  props: {
    tag: {
      type: String,
      default: "li"
    },
    active: {
      type: Boolean,
      default: false
    },
-    href: {
+    to: {
      type: String,
      default: "#"
    },
    waves: {
      type: Boolean,
      default: true
    },
    wavesFixed: {
      type: Boolean,
      default: false
    },
+    exact: {
+      type: Boolean,
+      default: false
+    }
  },
  data() {
    return {
      className: classNames("nav-item", this.active ? "active" : "")
    };
  },
  mixins: [waves]
};
</script>
<style scoped>
+ .navbar.navbar-dark .breadcrumb .nav-item > .nav-link.router-link-active,
+ .navbar.navbar-dark .navbar-nav .nav-item > .nav-link.router-link-active {
+   background-color: rgba(255, 255, 255, 0.1);
}
</style>
이것으로 완성.
 감상
<template>
  <li :is="tag" :class="[className, {'ripple-parent': waves}]" @click="wave">
-    <a :href="href" class="nav-link"><slot></slot></a>
+    <router-link :to="to" class="nav-link" :exact="exact"><slot></slot></router-link>
  </li>
</template>
<script>
//
//
//
//
//
//
import classNames from "classnames";
import waves from "../../mixins/waves";
export default {
  props: {
    tag: {
      type: String,
      default: "li"
    },
    active: {
      type: Boolean,
      default: false
    },
-    href: {
+    to: {
      type: String,
      default: "#"
    },
    waves: {
      type: Boolean,
      default: true
    },
    wavesFixed: {
      type: Boolean,
      default: false
    },
+    exact: {
+      type: Boolean,
+      default: false
+    }
  },
  data() {
    return {
      className: classNames("nav-item", this.active ? "active" : "")
    };
  },
  mixins: [waves]
};
</script>
<style scoped>
+ .navbar.navbar-dark .breadcrumb .nav-item > .nav-link.router-link-active,
+ .navbar.navbar-dark .navbar-nav .nav-item > .nav-link.router-link-active {
+   background-color: rgba(255, 255, 255, 0.1);
}
</style>
ERROR in /Users/uwettie/works/todo-client/src/App.vue
43:18 Could not find a declaration file for module '@/mixins/drop'. '/Users/uwettie/works/todo-client/src/mixins/drop.js' implicitly has an 'any' type.
    41 | import DropdownMenu from "@/components/mdbootstrap/DropdownMenu.vue";
    42 | import DropdownToggle from "@/components/mdbootstrap/DropdownToggle.vue";
  > 43 | import drop from "@/mixins/drop";
       |                  ^
    44 | import Mdinput from "@/components/mdbootstrap/MdInput.vue";
    45 |
    46 | export default {
Version: typescript 2.8.3, tslint 5.9.1
Vuetify
Vue.js의 머티리얼 디자인의 컴포넌트 프레임워크는 Vuetify라는 것이 유명하다.
그곳에서 하는 것이 좋을까.
Vue.js 전용이기 때문에 버려지면 싫다고 생각해 버리지만 괜찮을까.
 만든 소스
                
                    
        
    
    
    
    
    
                
                
                
                
                    
                        
                            
                            
                            Reference
                            
                            이 문제에 관하여(Material Design for Bootstrap 4 (Vue version) 소개), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
                                
                                https://qiita.com/uegaki-masaaki/items/ebaefbd8d7642332aea7
                            
                            
                            
                                텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
                            
                            
                                
                                
                                 우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)
                                
                                
                                우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)
                            
                            
                        
                    
                
                
                
            
Reference
이 문제에 관하여(Material Design for Bootstrap 4 (Vue version) 소개), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/uegaki-masaaki/items/ebaefbd8d7642332aea7텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
                                
                                
                                
                                
                                
                                우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)