今天做了一个案例"给你喜欢的人送花",如果喜欢谁,就给谁送花,最多可以送5朵。运行效果如下。
这个项目是使用 npm create vite@latest 命令创建的。
包括2个组件:
- 根组件App.vue
- 子组件HelloVote.vue。
目录结构如图所示:
然而在运行这个项目的时候,却出现了问题,App.vue中4张图片不能正常显示。
html
<template>
<div class="wrapper">
<h2>给你喜欢的人送花</h2>
<ul>
<li v-for="(item, index) in list" :key="index">
<div class="imgvote">
<img :src="item.poet" :alt="item.name">
</div>
<HelloVote :sendto="item.name">喜欢</HelloVote>
</li>
</ul>
</div>
</template>
对应的JavaScript中,代码为
javascript
data(){
return{
list: [
{ poet: require('./assets/liu.png'), name: '柳永', },
{ poet: require('./assets/su.png'), name: '苏轼', },
{ poet: require('./assets/xin.png'), name: '辛弃疾', },
{ poet: require('./assets/li.png'), name: '李清照', },
]
]
}
}
查看控制台,报错" require is not defined",require未定义。
于是到网上一通搜索,找到几篇文章,说是vite不支持require,要想使其支持,需要安装一个插件,还需要修改一些对应的配置文件。
安装插件简单,执行对应的命令即可。可是配置文件那里我有些看不明白,不知道该从哪里修改,甚至不知道配置文件具体是哪个。
后来又找到一篇文章,文中提到的方法不需要安装插件,不需要修改配置文件,只需要换种写法,不用require即可。我照做,果然问题解决,图片正常显示。
修改后的代码如下:
javascript
data() {
return {
list: [
{ poet: new URL(`./assets/liu.png`, import.meta.url).href, name: '柳永', },
{ poet: new URL(`./assets/su.png`, import.meta.url).href, name: '苏轼', },
{ poet: new URL(`./assets/xin.png`, import.meta.url).href, name: '辛弃疾', },
{ poet: new URL(`./assets/li.png`, import.meta.url).href, name: '李清照', },
],
}
},
修改前后对比:
javascript
//修改前
{ poet: require('./assets/liu.png'), name: '柳永', },
//修改后
{ poet: new URL(`./assets/liu.png`, import.meta.url).href, name: '柳永', },
new URL()这里使用了模板字符串,在本例中,使用普通的单引号或双引号字符串也可以。
只不过模板字符串可以支持动态URL。例如:
javascript
function getImageUrl(person) {
return new URL(`./assets/${person}.png`, import.meta.url).href
}
这种解决方法来源于vite官网(https://vitejs.cn/vite5-cn/guide/assets.html),感兴趣的话可以前往查看,这是vite官网的部分截图。
案例完整的代码如下:
一、App.vue
html
<script>
import HelloVote from './components/HelloVote.vue'
export default {
data() {
return {
list: [
{ poet: new URL('./assets/liu.png', import.meta.url).href, name: '柳永', },
{ poet: new URL('./assets/su.png', import.meta.url).href, name: '苏轼', },
{ poet: new URL("./assets/xin.png", import.meta.url).href, name: '辛弃疾', },
{ poet: new URL(`./assets/li.png`, import.meta.url).href, name: '李清照', },
],
// list: [
// { poet: require('./assets/liu.png'), name: '柳永', },
// { poet: require('./assets/su.png'), name: '苏轼', },
// { poet: require('./assets/xin.png'), name: '辛弃疾', },
// { poet: require('./assets/li.png'), name: '李清照', },
// ],
}
},
components: {
HelloVote,
},
}
</script>
<template>
<div class="wrapper">
<h2>给你喜欢的人送花</h2>
<ul>
<li v-for="(item, index) in list" :key="index">
<div class="imgvote">
<img :src="item.poet" :alt="item.name">
</div>
<HelloVote :sendto="item.name">喜欢</HelloVote>
</li>
</ul>
</div>
</template>
<style scoped>
ul,
li {
list-style: none;
}
.wrapper {
width: 80vw;
margin: 0 auto;
display: flex;
justify-content: center;
flex-direction: column;
}
.wrapper ul {
display: flex;
justify-content: space-between;
}
h2 {
text-align: center;
}
.wrapper li {
text-align: center;
}
.imgvote {
width: 16vw;
height: 20vw;
margin-bottom: 1rem;
}
.imgvote img {
width: 100%;
height: 100%;
border: 1px solid #ccc;
}
</style>
二、HelloVote.vue
html
<script>
export default {
data() {
return {
count: 0,
}
},
props: ['sendto'],
methods: {
onClick() {
if (this.count < 5) {
this.count++;
}
}
},
}
</script>
<template>
<div>
<button class="btn" @click="onClick">
<slot></slot>{{ sendto }}
</button>
<span>🌹x{{ count }}</span>
</div>
</template>
<style scoped>
.btn {
border: 1px solid #ccc;
padding: 5px;
border-radius: 5px;
cursor: pointer;
outline: none;
font-size: 16px;
width: 110px;
}
.btn:hover {
background-color: #ff8400;
color: #fff;
}
</style>
三、main.js
javascript
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')