Django模板集成带import的Vue组件时报错,求正确使用方法
问题
我尝试将Vue组件集成到Django模板中,基础配置已正常运行,但在使用一个需要自身导入内容的组件时遇到了问题。
组件文件vue/dropdown.html代码如下:
<div id="app"> <template> ... </template> </div> <script setup> import { computed, ref } from 'vue' import {CheckIcon, ChevronUpDownIcon} from '@heroicons/vue/20/solid' const query =ref('') const selectedPerson = ref(null) ... var app = new Vue({ delimiters: ['[[', ']]'], el: '#app', data: { message: 'Hello Vue!', }, }); </script>
其中这两行import语句:
import {computed, ref} from 'vue' import {CheckIcon, ChevronUpDownIcon} from '@heroicons/vue/20/solid'
触发了浏览器控制台错误:
Cannot use import statement outside a module
通过base.html调用组件的代码:
<html lang="{{ LANGUAGE_CODE }}"> <head>...</head> <body> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> {% include 'vue/dropdown.html' %} </body> </html>
请问正确使用这些import的方式是什么?
解决方案
方案一:改用ES模块方式引入Vue
这种方式适配import语法,是Vue 3推荐的现代写法:
- 更新
base.html中的Vue CDN链接,使用模块版本:<script type="module" src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.esm-browser.js"></script> - 修改
dropdown.html的代码:- 给
<script>标签加上type="module"属性 - 替换Heroicons的import为CDN模块链接
- 删掉冗余的
new Vue()实例创建代码(<script setup>会自动关联组件) - 去掉外层多余的
<template>标签,直接在根元素内写模板内容
<div id="app"> <!-- 直接写组件模板内容 --> ... </div> <script setup type="module"> import { computed, ref } from 'vue' // 用CDN模块地址引入Heroicons import { CheckIcon, ChevronUpDownIcon } from 'https://cdn.jsdelivr.net/npm/@heroicons/vue@2.0.18/dist/20/solid.esm.js' const query = ref('') const selectedPerson = ref(null) // 你的其他逻辑代码... </script> - 给
方案二:使用全局Vue API,避免模块依赖
如果不想用ES模块,可以改用Vue全局暴露的API,完全不用import:
- 保持
base.html的Vue CDN(换成Vue 3的全局版本):<script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.js"></script> - 修改
dropdown.html代码:- 去掉
<script setup>和所有import语句 - 从
Vue全局对象中解构需要的API - Heroicons直接用官网复制的SVG代码替代(避免导入依赖)
<div id="app"> <!-- 模板中用v-html渲染SVG图标 --> <span v-html="CheckIcon"></span> ... </div> <script> const { createApp, ref, computed } = Vue; // 从Heroicons官网复制对应图标的SVG代码 const CheckIcon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5"><path fill-rule="evenodd" d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" clip-rule="evenodd" /></svg>'; const ChevronUpDownIcon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z" clip-rule="evenodd" /></svg>'; createApp({ delimiters: ['[[', ']]'], setup() { const query = ref('') const selectedPerson = ref(null) // 定义计算属性等逻辑 const filteredItems = computed(() => { // 你的计算逻辑 }) // 暴露变量给模板使用 return { query, selectedPerson, filteredItems, CheckIcon, ChevronUpDownIcon } } }).mount('#app') </script> - 去掉
关键注意点
你之前的代码混合了Vue 2的new Vue()实例写法和Vue 3的<script setup>语法,二者冲突,必须统一成Vue 3的写法;另外import只能在ES模块环境中使用,要么给<script>加type="module",要么改用全局API。
内容的提问来源于stack exchange,提问作者nik_kobe
相关产品推荐
相关产品推荐

