Vue3里如何上传图片以及图片回显

简介: Vue3里如何上传图片以及图片回显

Vue3里的上传图片跟javascript的上传图片的原理都是一样的,Vue有Vue的写法但总体不变。

话不多说上代码:

<div id="contens">
        <p id="contens_TEXT" v-html="contens.introduction"></p>
    </div>
    <div id="title_Text">
        <h3>精彩评论</h3>
    </div>
    <div class="ListOfUsers_box" v-for="towText in towTexts" :key="towText">
        <div class="ListOfUsers">
            <img id="ListOfUsers_img" :src="towText.headimg" alt="">
            <div class="ListOfUsers_content">
                <p><b>{{ towText.nickname }}</b></p>
                <p style="margin:0%">{{ towText.content }}</p>
                <div style="display:flex;justify-content: space-around;">
                    <div style="width:60%;display: flex; justify-content: space-between;">
                        <!-- != null?towText.imag:'https://travel.kuxia.top/upload/20220902/b968cc55f9ff6679efd5b45e2dd89d30.jpg' -->
                        <img id="ListOfUsers_content_img" v-for="(towTextImg, index) in towText.image" :key="index"
                            :src="towTextImg" :onerror="errorimg" @click="imgTck(towText.image)" alt="">
                    </div>
                    <div class="but">
                        <van-button type="primary" @click="showt(towText.id, towText.nickname)">回复</van-button>
                    </div>
                </div>
            </div>
        </div>
        <!-- 回复 -->
        <div class="comments">
            <div style="display:flex" v-for="commentsImg in towText.item" :key="commentsImg">
                <p><b>{{ commentsImg.nickname }}</b></p>
                <p>{{ commentsImg.content }}</p>
            </div>
        </div>
    </div>
    <van-action-sheet v-model:show="show" title="回复评论">
        <div class="content">
            <textarea name="" id="" cols="30" rows="10" v-model="reply" style="border:none"></textarea>
            <van-button type="primary" @click="clickTOW"
                style="display:flex;justify-content: center;width: 92%;margin-left: 4%;">提交评论</van-button>
        </div>
    </van-action-sheet>
    <!-- 晒照 -->
    <div class="tarbat">
        <div style="display:flex;flex-wrap: wrap; width:14%;margin-left:4%">
            <img v-show="likeS" style="width:30px;height:30px" src="../assets/dianzan.png" @click="giveAlike" alt="">
            <img v-show="like2" style="width:30px;height:30px" src="../assets/dianzan2.png" @click="giveAlikeTow"
                alt="">
            <p style=" margin:0%" @click="giveAlike">点赞</p>
        </div>
        <div style="width: 70%;display: flex;align-items: center;justify-content: center;">
            <van-button type="primary" @click="according"
                style="display:flex;justify-content: center;width: 85%;margin-left: 4%;border-radius : 50px 50px 50px 50px;">我要晒照</van-button>
        </div>
        <van-action-sheet v-model:show="showres" title="晒照">
            <div class="content">
                <textarea name="" id="" cols="30" rows="10" v-model="replyTow"></textarea>
                <van-uploader v-model="fileList" multiple :max-count="3" />
                <van-button type="primary" @click="accordingTow"
                    style="display:flex;justify-content: center;width: 92%;margin-left: 4%;">提交晒照</van-button>
            </div>
        </van-action-sheet>
    </div>
    <!-- 弹出图片 -->
    <van-image-preview v-model:show="showTow" :images="images" @change="onChange">
        <template v-slot:index>第{{ index + 1 }}页</template>
    </van-image-preview>
</template>
<script setup>
import axios from 'axios';
import qs from 'qs';
import { Button } from 'vant';
import { ref } from 'vue'
// import router from '@/router';
import {
    useRouter,
    useRoute
} from "vue-router";
import { createApp } from 'vue';
const router = useRouter();
const route = useRoute();
const contens = ref('');
const userDatas = ref([]);
const towTexts = ref([])
const reply = ref('')
const replyTow = ref('')
const show = ref(false);
const showres = ref(false)
const showTow = ref(false);
var clickTOW;
var datase;
let errorimg = 'this.src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2023%2F0209%2Fa362b55ej00rprvbv010vd200rs00rsg00hx00hx.jpg&thumbnail=660x2147483647&quality=80&type=jpg"'
datase = () => {
    axios({
        method: "post", //请求方式
        url: "api/science/clockdetail ", //url
        data: qs.stringify({
            // 参数
            // placeid: route.query.id,
            scienceid: route.query.eventid
        }),
    }).then((res) => {
        console.log(res.data); //成功回调
        contens.value = res.data.info
        towTexts.value = res.data.coment
        console.log(towTexts.value);
    })
}
datase()
const images = ref([
    // 'https://fastly.jsdelivr.net/npm/@vant/assets/apple-1.jpeg',
    // 'https://fastly.jsdelivr.net/npm/@vant/assets/apple-2.jpeg',
]);
const onChange = (newIndex) => {
    index.value = newIndex;
};
const imgTck = (Imgtow) => {
    showTow.value = true
    console.log(Imgtow);
    images.value = Imgtow
}
const index = ref(0);
const showt = (id, nickname) => {
    show.value = true
    clickTOW = () => {
        if (reply.value != '') {
            axios({
                method: "post", //请求方式
                url: "", //url
                data: qs.stringify({
                    // 参数
                }),
            }).then((res) => {
                console.log(res.data); //成功回调
                datase()
            })
            show.value = false;
        }
    }
}
const fileList = ref([]);
const according = () => {
    showres.value = true
}
const accordingTow = () => {
    // 创建数据表单
    var data = new FormData();
    // let imgArrs = []
    for (let index = 0; index < fileList.value.length; index++) {
        let fileOne = fileList.value[index].file;
        data.append('file', fileOne) //这里就要使用我么在上面创建的from.DATA了将图片的数据放进去
        //图片上传
        axios({
            method: "post", //请求方式
            url: "", //url
            data: data // 参数
        }).then((res) => {
            console.log(res.data); //成功回调
            imgArrs.push(res.data.front_file)
            if (imgArrs.length == index + 1) {
                 //图片回显
                axios({
                    method: "post", //请求方式
                    url: "", //url
                    data: qs.stringify({
                        // 参数
                    })
                }).then((res) => {
                    console.log(userDatas.value.nickname);
                    console.log(userDatas.value.img);
                    console.log(route.query.eventid);
                    console.log(replyTow.value);
                    console.log(String(imgArrs));
                    console.log(res.data); //成功回调
                    datase()
                })
            }
        })
    }
    console.log(replyTow.value);
    showres.value = false
}
// 点赞
const gicealike = ref(false)
const likeS = ref(true)
const like2 = ref(false)
const giveAlike = () => {
    if (gicealike) {
        likeS.value = false
        like2.value = true
        like()
    }
}
const giveAlikeTow = () => {
    likeS.value = true
    like2.value = false
}
const like = () => {
    axios({
        method: "post", //请求方式
        url: "", //url
        data: qs.stringify({
            // 参数
        }),
    }).then((res) => {
        console.log(res.data); //成功回调
        like.value = false
        like2.value = true
    })
}
</script>
<style>
body {
    background-color: rgba(241, 241, 241, 1);
}
.title_tows {
    width: 100%;
    height: 2.5rem;
    background-color: cornflowerblue;
}
.list_tow_list {
    width: 100%;
    /* height: 100ch; */
    margin-top: 1%;
}
#img_imaget {
    position: absolute;
    width: 1.875rem;
    height: 1.875rem;
    top: 1%;
}
.listetows {
    background-color: #fff;
    box-shadow: 0.125rem 0.1875rem;
    width: 94%;
    margin-left: 3%;
    border-radius: 5%;
    margin-top: 2%;
}
#img_images {
    width: 94%;
    height: 8.75rem;
    border-radius: 5%;
    margin-left: 3%;
    margin-top: 2%;
}
.title_tows_text {
    width: 100%;
    height: 2.5rem;
    display: flex;
    justify-content: center;
    align-items: center;
    color: #fff;
}
#contens {
    width: 94%;
    margin-left: 3%;
    background-color: #fff;
    border-radius: 4%;
}
#contens_TEXT {
    width: 94%;
    margin-left: 3%;
    padding: 1%;
}
#title_Text {
    width: 94%;
    background-color: #fff;
    height: 40px;
    margin: 3%;
    border-radius: 10px 10px 10px 10px;
}
#title_Text h3 {
    width: 96%;
    margin: 0%;
    margin-left: 2%;
    display: flex;
    height: 40px;
    align-items: center;
}
.ListOfUsers_box {
    width: 94%;
    margin: 3%;
    background-color: #fff;
    position: relative;
    border-radius: 10px 10px 10px 10px;
    height: auto;
    padding-bottom: 1%;
}
.ListOfUsers {
    display: flex;
}
#ListOfUsers_img {
    width: 20%;
    height: 20%;
    margin-left: 2%;
    margin-top: 2%;
}
.ListOfUsers_content {
    width: 100%;
    margin-left: 2%;
    height: 30%;
}
#ListOfUsers_content_img {
    width: 30%;
    height: 55px;
}
.comments {
    margin-left: 25%;
    height: auto;
    width: 70%;
    margin-top: 2%;
    margin-bottom: 2%;
    background-color: rgb(241, 241, 241);
    border-radius: 10px 10px 10px 10px;
}
.comments p {
    margin: 0%;
    padding: 5%;
    border-radius: 10%;
}
.but {
    margin-left: -10%;
    margin-top: 5%;
}
.content {
    padding: 16px 16px 60px;
}
.content textarea {
    width: 100%;
    height: 70%;
}
.tarbat {
    width: 100%;
    height: 60px;
    background-color: rgb(249, 249, 249);
    position: fixed;
    bottom: 0%;
    display: flex;
    justify-items: center;
    justify-content: space-around;
}
</style>

大致原理就是使用图片上传的接口先将图图片获取到将其转化为字符串, 回显的话页很简单就是将你上传图片后的路径在放到创建的fromdata函数里。(各位只需要将链接放到URL地址里就可以了)用到的组件还得请各位去下载喽Vant 4

相关文章
|
2月前
|
缓存 JavaScript UED
Vue3中v-model在处理自定义组件双向数据绑定时有哪些注意事项?
在使用`v-model`处理自定义组件双向数据绑定时,要仔细考虑各种因素,确保数据的准确传递和更新,同时提供良好的用户体验和代码可维护性。通过合理的设计和注意事项的遵循,能够更好地发挥`v-model`的优势,实现高效的双向数据绑定效果。
155 64
|
2月前
|
JavaScript 前端开发 API
Vue 3 中 v-model 与 Vue 2 中 v-model 的区别是什么?
总的来说,Vue 3 中的 `v-model` 在灵活性、与组合式 API 的结合、对自定义组件的支持等方面都有了明显的提升和改进,使其更适应现代前端开发的需求和趋势。但需要注意的是,在迁移过程中可能需要对一些代码进行调整和适配。
128 60
|
20天前
|
JavaScript API 数据处理
vue3使用pinia中的actions,需要调用接口的话
通过上述步骤,您可以在Vue 3中使用Pinia和actions来管理状态并调用API接口。Pinia的简洁设计使得状态管理和异步操作更加直观和易于维护。无论是安装配置、创建Store还是在组件中使用Store,都能轻松实现高效的状态管理和数据处理。
69 3
|
2月前
|
前端开发 JavaScript 测试技术
Vue3中v-model在处理自定义组件双向数据绑定时,如何避免循环引用?
Web 组件化是一种有效的开发方法,可以提高项目的质量、效率和可维护性。在实际项目中,要结合项目的具体情况,合理应用 Web 组件化的理念和技术,实现项目的成功实施和交付。通过不断地探索和实践,将 Web 组件化的优势充分发挥出来,为前端开发领域的发展做出贡献。
46 8
|
2月前
|
存储 JavaScript 数据管理
除了provide/inject,Vue3中还有哪些方式可以避免v-model的循环引用?
需要注意的是,在实际开发中,应根据具体的项目需求和组件结构来选择合适的方式来避免`v-model`的循环引用。同时,要综合考虑代码的可读性、可维护性和性能等因素,以确保系统的稳定和高效运行。
41 1
|
2月前
|
JavaScript
Vue3中使用provide/inject来避免v-model的循环引用
`provide`和`inject`是 Vue 3 中非常有用的特性,在处理一些复杂的组件间通信问题时,可以提供一种灵活的解决方案。通过合理使用它们,可以帮助我们更好地避免`v-model`的循环引用问题,提高代码的质量和可维护性。
50 1
|
2月前
|
JavaScript
在 Vue 3 中,如何使用 v-model 来处理自定义组件的双向数据绑定?
需要注意的是,在实际开发中,根据具体的业务需求和组件设计,可能需要对上述步骤进行适当的调整和优化,以确保双向数据绑定的正确性和稳定性。同时,深入理解 Vue 3 的响应式机制和组件通信原理,将有助于更好地运用 `v-model` 实现自定义组件的双向数据绑定。
|
2月前
|
存储 JavaScript 前端开发
vue3的脚手架模板你真的了解吗?里面有很多值得我们学习的地方!
【10月更文挑战第21天】 vue3的脚手架模板你真的了解吗?里面有很多值得我们学习的地方!
vue3的脚手架模板你真的了解吗?里面有很多值得我们学习的地方!
|
2月前
|
JavaScript 索引
Vue 3.x 版本中双向数据绑定的底层实现有哪些变化
从Vue 2.x的`Object.defineProperty`到Vue 3.x的`Proxy`,实现了更高效的数据劫持与响应式处理。`Proxy`不仅能够代理整个对象,动态响应属性的增删,还优化了嵌套对象的处理和依赖追踪,减少了不必要的视图更新,提升了性能。同时,Vue 3.x对数组的响应式处理也更加灵活,简化了开发流程。
|
2月前
|
JavaScript 前端开发 开发者
Vue 3中的Proxy
【10月更文挑战第23天】Vue 3中的`Proxy`为响应式系统带来了更强大、更灵活的功能,解决了Vue 2中响应式系统的一些局限性,同时在性能方面也有一定的提升,为开发者提供了更好的开发体验和性能保障。
90 7