现在的需求是,点击下面的小图标,弹出上传文件对话框,然后点击发布按钮,上传输入框里的文字和图片。
使用nuxt ui组件实现不了,只能使用原生的input输入框:
components/Tweet/Form/Input.vue
<template>
<div>
<div class="flex items-center flex-shrink-0 p-4 pb-0" v-if="loading">
<div class="flex w-12 items-start">
<UAvatar :src="user?.profileImage" />
</div>
<div class="w-full p-2">
<UTextarea v-model="text" placeholder="发布动态" />
</div>
<UAvatar :src="inputImageUrl" v-if="inputImageUrl" size="3xl" :ui="ui" />
</div>
<div v-else>
<AppLoad />
</div>
<div class="flex items-center justify-between pt-2 pb-2 mr-2 pr-24 pl-16">
<div class="flex items-center gap-2">
<div class="mydiv">
<UIcon name="solar-album-linear" class="myicon" @click="iconClick" />
</div>
<div class="mydiv">
<UIcon name="fluent-gif-16-regular" class="myicon" />
</div>
<div class="mydiv">
<UIcon name="solar-chart-square-linear" class="myicon" />
</div>
<div class="mydiv">
<UIcon name="solar-smile-square-linear" class="myicon" />
</div>
<div class="mydiv">
<UIcon name="solar-calendar-outline" class="myicon" />
</div>
<input
ref="imageInput"
type="file"
class="hidden"
accept="image/png, image/gif, image/jpeg"
@change="handleImageChange"
:disabled="!loading"
/>
</div>
<UButton :disabled="!loading" label="发布" @click="handleFormSubmit" />
</div>
</div>
</template>
最下面的input文本框,添加了隐藏样式,使用ref属性,绑定了imageInput变量。图片上的@click点击事件,点击后,就是变量的点击动作:
const loading = ref(true);
const imageInput = ref();
const iconClick = () => {
imageInput.value.click();
};
在vue中,ref属性是给Dom元素或子组件添加引用,添加引用后,就可以通过ref访问该元素了。原生的html的元素,一般是添加id属性,然后通过document.getElementById("id")来访问该元素。
在点击按钮事件里,加上loading加载页面,可以有个很好的反馈效果,同时设置按钮是否可用状态,既是点击按钮后,按钮不可用,提交完成,即恢复可用状态。
async function handleFormSubmit() {
loading.value = false;
try {
const response = await postTweet({
text: text.value,
mediaFiles: [selectFile.value],
});
// console.log(response);
} catch (error) {
console.log(error);
} finally {
loading.value = true;
}
}