如何引入组件?

以以下代码为例:

  1. <template>
  2. <div>
  3. <router-link to="/money">记帐</router-link>
  4. |
  5. <router-link to="/labels">标签</router-link>
  6. |
  7. <router-link to="/statistics">统计</router-link>
  8. </div>
  9. </template>

方法一:在App.vue里直接使用(全局)

如:

  1. <template>
  2. <div id="app">
  3. <router-view/>
  4. <div>
  5. <router-link to="/money">记帐</router-link>
  6. |
  7. <router-link to="/labels">标签</router-link>
  8. |
  9. <router-link to="/statistics">统计</router-link>
  10. </div>
  11. </div>
  12. </template>

优点:可以在所有的页面渲染该组件。
缺点:不能控制部分页面隐藏该组件。

方法二:在各各页面引入组件

先在components创建Nav.vue组件,代码如下。

  1. <template>
  2. <div>
  3. <router-link to="/money">记帐</router-link>
  4. |
  5. <router-link to="/labels">标签</router-link>
  6. |
  7. <router-link to="/statistics">统计</router-link>
  8. </div>
  9. </template>
  10. <script lang="ts">
  11. export default {
  12. name: 'Nav'
  13. };
  14. </script>
  15. <style lang="scss" scoped>
  16. </style>

然后在想要添加的页面的代码里引入组件即可。比如我想在Money.vue文件里引入:

  1. <template>
  2. <div>
  3. Money.vue
  4. <hr>
  5. <Nav/>
  6. </div>
  7. </template>
  8. <script lang="ts">
  9. import Nav from '@/components/Nav.vue';
  10. export default {
  11. name: 'money',
  12. components: {Nav}
  13. };
  14. </script>
  15. <style lang="scss" scoped>
  16. </style>

其他想引入该组件可以重复以上步骤。

优点:可以控制一些页面不需要引用该组件。
缺点:一直重复。。。。

方法三:方法二的改进版

不在各各页面引入组件,而是在管理全局的main.ts文件里引入!

同样先创建Nav.vue组件,然后在main.ts引入文件:

  1. import Vue from 'vue';
  2. import App from './App.vue';
  3. import './registerServiceWorker';
  4. import router from './router';
  5. import store from './store';
  6. import Nav from '@/components/Nav.vue'; //添加了这行代码
  7. Vue.config.productionTip = false;
  8. Vue.component('Nav',Nav); //添加了这行代码
  9. new Vue({
  10. router,
  11. store,
  12. render: h => h(App)
  13. }).$mount('#app');

最后只需要在需要引入该组件的页面添加 <Nav/> 即可!

优点:可以选择页面是否引入组件。
缺点:暂时没有

插槽

如果需要在页面传送信息给组件该怎么实现?如下代码,有Money.vue、Statistics.vue、Labels.vue这三个页面,每个文件与以下代码除了 .content 里的信息不同,HTML与CSS完全一样,那么就需要封装成组件提供使用。

  1. //Money.vue
  2. <template>
  3. <div class="nav-wrapper">
  4. <div class="content">
  5. Money.vue
  6. </div>
  7. <Nav/>
  8. </div>
  9. </template>
  10. <script lang="ts">
  11. export default {
  12. name: 'money',
  13. };
  14. </script>
  15. <style lang="scss" scoped>
  16. .nav-wrapper {
  17. border: 1px solid green;
  18. display: flex;
  19. flex-direction: column;
  20. min-height: 100vh;
  21. }
  22. .content {
  23. border: 1px solid blue;
  24. overflow: auto;
  25. flex-grow: 1;
  26. }
  27. </style>

封装成:

  1. <template>
  2. <div class="nav-wrapper">
  3. <div class="content">
  4. ???? //如何实现不一样?
  5. </div>
  6. <Nav/>
  7. </div>
  8. </template>
  9. <script lang="ts">
  10. export default {
  11. name: 'Layout'
  12. }
  13. </script>
  14. <style lang="scss" scoped>
  15. .nav-wrapper {
  16. border: 1px solid green;
  17. display: flex;
  18. flex-direction: column;
  19. min-height: 100vh;
  20. }
  21. .content {
  22. border: 1px solid blue;
  23. overflow: auto;
  24. flex-grow: 1;
  25. }
  26. </style>

但问题来了,class名为 content 里的内容是不同,那么这里每个页面都不能一样,该怎么做?

这个问题Vue官方提供了一种办法,名为“插槽”。

只需要在组件里需要不一样的地方添 <slot/> ,在页面里引入组件的同时,把信息写进组件里,组件会在渲染的过程中把信息传递给组件,如下:

  1. //Layout.vue组件
  2. <template>
  3. <div class="nav-wrapper">
  4. <div class="content">
  5. <slot/>
  6. </div>
  7. <Nav/>
  8. </div>
  9. </template>
  10. <script lang="ts">
  11. //忽略
  12. </script>
  13. <style lang="scss" scoped>
  14. //忽略
  15. </style>

页面如下:

  1. <template>
  2. <Layout>
  3. Money.vue
  4. </Layout>
  5. </template>
  6. <script lang="ts">
  7. export default {
  8. name: 'money',
  9. };
  10. </script>
  11. <style lang="scss" scoped>
  12. </style>

如何引入一个目录下的所有文件?

假如一个文件下全是icon,要引入某个文件的话难道需要一个一个用 import 引入?这个过程一直重复,可以考虑直接引入整个文件。代码如下:

  1. <script lang="ts">
  2. const importAll = (requireContext: __WebpackModuleApi.RequireContext) => requireContext.keys().forEach(requireContext);
  3. try {
  4. importAll(require.context('路径', true,/\.svg$/));
  5. } catch(error){
  6. console.log(error);
  7. }
  8. ...
  9. </script>