简体   繁体   中英

How do I import an svg in Vue 3?

I tried following: https://github.com/visualfanatic/vue-svg-loader/tree/master

but there's a version conflict with vue-template-compiler since that's used in Vue 2.

I tried: https://github.com/visualfanatic/vue-svg-loader

but I'm missing a specific vue dependency.

I noticed there's a caveat with using typescript and you need to declare the type definition file. However, I still get "Cannot find module '../../assets/myLogo.svg' or its corresponding type declarations."

Here's what I added:

vue.config.js

module.exports = {
  chainWebpack: (config) => 
  {
    const svgRule = config.module.rule('svg');

    svgRule.uses.clear();

    svgRule
      .use('vue-loader-v16')
      .loader('vue-loader-v16')
      .end()
      .use('vue-svg-loader')
      .loader('vue-svg-loader');
  },
  configureWebpack: process.env.NODE_ENV === 'production' ? {} : {
    devtool: 'source-map'
  },
  publicPath: process.env.NODE_ENV === 'production' ?
    '/PersonalWebsite/' : '/'
}

shims-svg.d.ts

declare module '*.svg' {
  const content: any;
  export default content;
}

MyComponent.vue

<template>
  <div>
     <MyLogo />
  </div>
</template>

<script lang="ts">
import * as MyLogo from "../../assets/myLogo.svg";

export default defineComponent({
  name: "MyComponent",
  components: {
    MyLogo
  },
  props: {
    
  },
  setup(props)
  {
    return {
      props
    };
  }
});


</script>

Actually SVGs are supported right out of the box with Vue CLI. It uses file-loader internally. You can confirm it by running the following command on the terminal:

vue inspect --rules

If "svg" is listed (it should be), then all you've got to do is:

<template>
  <div>
    <img :src="myLogoSrc" alt="my-logo" />
  </div>
</template>

<script lang="ts">
  // Please just use `@` to refer to the root "src" directory of the project
  import myLogoSrc from "@/assets/myLogo.svg";

  export default defineComponent({
    name: "MyComponent",

    setup() {
      return {
        myLogoSrc
      };
    }
  });
</script>

So there's no need for any third party library—that is if your sheer purpose is only to display SVGs.

And of course, to satisfy the TypeScript compiler on the type declaration:

declare module '*.svg' {
  // It's really a string, precisely a resolved path pointing to the image file
  const filePath: string;

  export default filePath;
}

Can't say for sure, since I haven't tried with ts, but as posted here

this should work.

declare module '*.svg' {
    import type { DefineComponent } from 'vue';
    const component: DefineComponent;
    export default component;
}

I see you're using:

import * as MyLogo from "../../assets/myLogo.svg";

I believe that should be:

import MyLogo from "../../assets/myLogo.svg";

Example from fresh installed vue.js 3.2:

<img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125"/>

vue-svg-loader is not compatible with vue 3. To import svg and use it as a component, simply wrap the contents of the file in 'template'

In component:

<template>
  <div class="title">
    <span>Lorem ipsum</span>
    <Icon />
  </div>
</template>

<script>
import Icon from '~/common/icons/icon.svg';

export default {
  name: 'PageTitle',
  components: { Icon },
};
</script>

Webpack:

{
   test: /\.svg$/,
   use: ['vue-loader', path.resolve(__dirname, 'scripts/svg-to-vue.js')],
}

scripts/svg-to-vue.js:

module.exports = function (source) {
  return `<template>\n${source}\n</template>`;
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM