0
点赞
收藏
分享

微信扫一扫

封装一个vue3 Toast组件,支持组件和api调用

目录

一、小程序UI

1.讲述

2. 介绍vantWeapp

3. 使用vantWeapp

安装

构建

依赖

引用

二、后端

1. 后端实体对象

2. 后端接口

3. 实现类

4. 请求处理类

三、前端

1. 定义路径

2. 页面引用

3. 页面

4. 页面美化

5. 数据

6. 效果展示


一、小程序UI

1.讲述

    1. 简洁明了:小程序的界面设计应该简洁明了,避免过多的视觉干扰和复杂的布局。用户可以通过一目了然的界面结构快速找到所需的功能。

    2. 一致性:小程序的不同页面之间应该保持一致的界面设计,包括颜色、字体、按钮等方面的统一。这样可以提高用户的学习和使用效率,减少用户的困惑。

    3. 易用性:小程序的界面设计应该考虑用户的使用习惯和心理需求,尽量减少用户的操作步骤和思考负担。例如,常用的功能应该放在显眼的位置,操作按钮应该易于点击等。

    4. 可访问性:小程序的界面设计应该考虑到不同用户的特殊需求,例如视力障碍者、听力障碍者等。设计师应该通过合适的颜色对比度、字体大小等方式来提高小程序的可访问性。

    5. 反馈机制:小程序的界面设计应该提供即时的反馈机制,告知用户他们的操作是否成功或失败。例如,可以通过动画、弹窗等方式来提示用户操作的结果。

2. 介绍vantWeapp

1. 提供常用UI组件:vantWeapp提供了丰富的UI组件,包括按钮、表单、列表、卡片、标签、导航、弹窗等,可以帮助开发者快速构建出美观、易用的小程序页面。

2. 提高开发效率:vantWeapp的组件具有可复用性,可以减少开发者的重复工作,提高开发效率。

3. 提供业务组件:vantWeapp还提供了一些常用的业务组件,例如地址选择器、城市选择器、日期选择器等,可以帮助开发者快速实现一些常用的业务需求。

4. 提供功能组件:vantWeapp还提供了一些功能组件,例如图片预览、下拉刷新、上拉加载等,可以帮助开发者实现一些常用的功能需求。

3. 使用vantWeapp

安装

构建

如图 : 

依赖

引用

例如 : 

{
"navigationBarTitleText": "投票管理",
"usingComponents": {
"tabs":"/components/tabs/tabs",
"van-button": "vant-weapp/button",
}
}
<van-button type="default">默认按钮</van-button>
<van-button type="primary">主要按钮</van-button>
<van-button type="info">信息按钮</van-button>
<van-button type="warning">警告按钮</van-button>
<van-button type="danger">危险按钮</van-button>

效果图  :

二、后端

1.  后端实体对象

Vote : 投票

package com.CloudJun.ssm.model;

import lombok.Data;

@Data
public class Vote {
private Integer id;

private Integer meetingId;

private String name;

private String remark;

private Integer state;

private String images;

public Vote(Integer id, Integer meetingId, String name, String remark, Integer state, String images) {
this.id = id;
this.meetingId = meetingId;
this.name = name;
this.remark = remark;
this.state = state;
this.images = images;
}

@Override
public String toString() {
return "Vote{" +
"id=" + id +
", meetingId=" + meetingId +
", name='" + name + '\'' +
", remark='" + remark + '\'' +
", state=" + state +
", images='" + images + '\'' +
'}';
}
}

2. 后端接口

VoteMapper : 自动生成的对象接口

package com.CloudJun.ssm.mapper;

import com.CloudJun.ssm.model.Vote;

import java.util.List;

public interface VoteMapper {
int deleteByPrimaryKey(Integer id);

int insert(Vote record);

int insertSelective(Vote record);

Vote selectByPrimaryKey(Integer id);

int updateByPrimaryKeySelective(Vote record);

int updateByPrimaryKey(Vote record);

List<Vote> selectByList(Integer state);
}

VoteService : 自己为了实现方法创建的接口

package com.CloudJun.ssm.service;

import com.CloudJun.ssm.model.Vote;

import java.util.List;

/**
* @author CloudJun
* @create  2023-10-24 14:41
*/

public interface VoteService {

int deleteByPrimaryKey(Integer id);

int insert(Vote record);

int insertSelective(Vote record);

Vote selectByPrimaryKey(Integer id);

int updateByPrimaryKeySelective(Vote record);

int updateByPrimaryKey(Vote record);

List<Vote> selectByList(Integer state);

}

3. 实现类

VoteServiceimpl : 实现调用方法功能而创建的实现类

package com.CloudJun.ssm.service.impl;

import com.CloudJun.ssm.mapper.VoteMapper;
import com.CloudJun.ssm.model.Vote;
import com.CloudJun.ssm.service.VoteService;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
* @author CloudJun
* @create  2023-10-24 14:42
*/

public class VoteServiceimpl implements VoteService {

@Autowired
private VoteMapper voteMapper;

@Override
public int deleteByPrimaryKey(Integer id) {
return voteMapper.deleteByPrimaryKey(id);
}

@Override
public int insert(Vote record) {
return voteMapper.insert(record);
}

@Override
public int insertSelective(Vote record) {
return voteMapper.insertSelective(record);
}

@Override
public Vote selectByPrimaryKey(Integer id) {
return voteMapper.selectByPrimaryKey(id);
}

@Override
public int updateByPrimaryKeySelective(Vote record) {
return 0;
}

@Override
public int updateByPrimaryKey(Vote record) {
return 0;
}

@Override
public List<Vote> selectByList(Integer state) {
return voteMapper.selectByList(state);
}
}

4. 请求处理类

VoteController : 处理前端发送的请求及处理数据,并且给予回馈数据到前端

package com.CloudJun.ssm.wxcontroller;

import com.CloudJun.ssm.mapper.VoteMapper;
import com.CloudJun.ssm.model.Info;
import com.CloudJun.ssm.model.Vote;
import com.CloudJun.ssm.util.ResponseUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* @author CloudJun
* @create  2023-10-24 14:24
*/

@RestController
@RequestMapping("/wx/vote")
public class VoteController {

@Autowired
private VoteMapper voteMapper;

@RequestMapping("/add")
public Object Add (Vote vote){
int i = voteMapper.insertSelective(vote);
return ResponseUtil.ok();
}

@RequestMapping("/list")
public Object list (Integer state){
List<Vote> votes = voteMapper.selectByList(state);
return ResponseUtil.ok(votes);
}

@RequestMapping("/update")
public Object update (Vote vote){
int i = voteMapper.updateByPrimaryKey(vote);
return ResponseUtil.ok();
}




}

三、前端

1 . 定义路径

// 以下是业务服务器API地址
// 本机开发API地址
var WxApiRoot = 'http://localhost:8080/oapro/wx/';
// 测试环境部署api地址
// var WxApiRoot = 'http://192.168.191.1:8080/oapro/wx/';
// 线上平台api地址
//var WxApiRoot = 'https://www.oa-mini.com/demo/wx/';

module.exports = {
IndexUrl: WxApiRoot + 'home/index', //首页数据接口
SwiperImgs: WxApiRoot+'swiperImgs',
MettingInfos: WxApiRoot+'meeting/list',
MettingVote : WxApiRoot+'info/list',
MettingVoteAdd : WxApiRoot+'vote/add',//增加投票
MettingVoteList : WxApiRoot+'vote/list',//获取投票信息
MettingVoteupdate : WxApiRoot+'vote/update',//确认投票
AuthLoginByWeixin: WxApiRoot + 'auth/login_by_weixin', //微信登录
UserIndex: WxApiRoot + 'user/index', //个人页面用户相关信息
AuthLogout: WxApiRoot + 'auth/logout', //账号登出
AuthBindPhone: WxApiRoot + 'auth/bindPhone' //绑定微信手机号
};

2. 页面引用

list.json

{
"navigationBarTitleText": "投票管理",
"usingComponents": {
"tabs":"/components/tabs/tabs",
"van-button": "vant-weapp/button",
"van-notice-bar": "vant-weapp/notice-bar/index",
"van-toast": "vant-weapp/toast/index"
}
}

3. 页面

list.wxml

<!--pages/vote/list/list.wxml-->
<tabs tabList="{{tabs}}"  bindtabsItemChange="tabsItemChange">
</tabs>
<view style="height: 100rpx;"></view>

<view class="{{componentStatus[0] ? '' : 'hidden'}}">
<!-- 发起投票版块 -->
<view class="publish">

<form bindsubmit='votesubmit'>
  <view class="img">
<view class="img_left" >
<image class="imgs"  src="{{imageUrl=='' ? '/static/persons/15.gif':imageUrl }}" mode="aspectFit" bindtap="handleUploadImage"></image>
<input hidden="true"  type="text" name="images" value="{{imageUrl}}" />
</view>
</view>
  <view class="meeting_id">
  <view class="meeting_title">所属会议 : </view>
  <picker bindchange="meetingChange" name="meetingId" value="{{array[meeting_id].id}}"    range-key="title" range="{{array}}">
    <view class="meeting_text" >{{array[meeting_id].title==null?'请选择会议':array[meeting_id].title}}</view>
  </picker>
</view>
<view class="meeting_id" id="meeting_id">
  <view class="meeting_title">投票标题 : </view>
   <input class="vote_text" placeholder="请输入标题" type="text" name="name" />
</view>
<view class="textarea" id="vote_text">
  <view class="meeting_textarea">投票说明 : </view>
   <textarea class="vote_textarea"  name="remark"  type="text" ></textarea>
</view>
<view class="vote_button">
  <button class="vote_button_empty" type="default" formType="reset"  plain="true">清空内容</button>
  <view style="width: 70rpx;"></view>
  <button class="vote_button_submit" type="primary" formType="submit" plain="true">确认发起</button>
</view>
</form>
</view>

</view>

  <view class="{{componentStatus[1] ? '' : 'hidden'}}">
    <van-notice-bar
  left-icon="flower-o"
  mode="closeable"
  color="#6d9d9e"
  delay="100"
  backgroundColor="#e4ecec"
  text="无论我们能活多久,我们能够享受的只有无法分割的此刻,不会回头,离弦的箭、逝去的生活和失去的机会。此外别无其他。"
/>
<!-- 已参与投票 -->
<block wx:for-items="{{engage}}" wx:for-item="item" wx:key="item.id">
<view class="vote_carryout">
<image class="vote_carryout_img" src="{{item.images}}"></image>
<view class="vote_carryout_text">
<view style="width: 450rpx;display: flex;flex-direction:column;">
<text class="vote_carryout_text_f" >{{item.name}}</text>
<text class="vote_carryout_text_t">{{item.remark}}</text>
</view>
<button class="vote_carryout_text_btn" bindtap="voteparticipate"  data-item="{{item.id}}"  size="mini">参与</button>
</view>
</view>
</block>


  </view>
  <view class="{{componentStatus[2] ? '' : 'hidden'}}">
  
    <van-notice-bar
  left-icon="flower-o"
  mode="closeable"
  color="#6d9d9e"
  delay="100"
  backgroundColor="#e4ecec"
  text="无论我们能活多久,我们能够享受的只有无法分割的此刻,不会回头,离弦的箭、逝去的生活和失去的机会。此外别无其他。"
/>
<!-- 未参与投票 -->
<block wx:for-items="{{not}}" wx:for-item="item" wx:key="item.id">
<view class="vote_carryout">
<image class="vote_carryout_img" src="{{item.images==null?'/static/persons/15.gif':item.images}}"></image>
<view class="vote_carryout_text">
<view style="width: 450rpx;display: flex;flex-direction:column;">
<text class="vote_carryout_text_f" >{{item.name}}</text>
<text class="vote_carryout_text_t">{{item.remark}}</text>
</view>
<button class="vote_carryout_text_btn" bindtap="Votenotbtn"  size="mini">已参与</button>
</view>
</view>
</block>
  
  </view>
  <view class="{{componentStatus[3] ? '' : 'hidden'}}">
  
    <van-notice-bar
  left-icon="flower-o"
  mode="closeable"
  color="#6d9d9e"
  delay="100"
  backgroundColor="#e4ecec"
  text="无论我们能活多久,我们能够享受的只有无法分割的此刻,不会回头,离弦的箭、逝去的生活和失去的机会。此外别无其他。"
/>
<!-- 未参与投票 -->
<block wx:for-items="{{lists}}" wx:for-item="item" wx:key="item.id">
<view class="vote_carryout">
<image class="vote_carryout_img" src="{{item.images==null?'/static/persons/15.gif':item.images}}"></image>
<view class="vote_carryout_text">
<view style="width: 450rpx;display: flex;flex-direction:column;">
<text class="vote_carryout_text_f" >{{item.name}}</text>
<text class="vote_carryout_text_t">{{item.remark}}</text>
</view>
<button class="vote_carryout_text_btn"  size="mini">{{item.state==0?'未参与':'已参与'}}</button>
</view>
</view>
</block>
 

  </view>

4. 页面美化

list.wxss

/* pages/vote/list/list.wxss */
.hidden {
display: none;
}

.img {
height: 450rpx;
/* display: flex; */
/* border-radius: 6px; */
/* align-items: center; */
}

.imgs {
height: 420rpx;
width: 419rpx;
margin-left: 105rpx;
box-shadow: 0 0 20px rgb(117, 241, 241);
border-radius: 10rpx;
}

.img_left {
margin-top: 28rpx;
height: 450rpx;
width: 600rpx;
margin-left: 57rpx;
/* border-radius: 23rpx; */
/* background-color: deeppink; */
}

.publish {
width: 100%;
}

.meeting_id {
height: 100rpx;
background-color: rgb(230, 243, 243);
display: flex;
/* border-radius: 6px; */
align-items: center;
}

.meeting_title {
margin-left: 20rpx;
}

.meeting_text {
/* background-color: aqua; */
margin-left: 20rpx;
margin-top: 10rpx;
padding-left: 20rpx;
font-size: 14px;
height: 50rpx;
width: 520rpx;
}

#meeting_id {
border-top: 2px solid #fafafa;
}

#vote_text {
display: flex;
align-items: center;
}

.vote_text {
margin-left: 35rpx;
}

.meeting_textarea {
margin-left: 20rpx;
width: 440rpx;
}

.vote_textarea {
height: 160rpx;
width: 490px;
padding-right: 10rpx;
padding-top: 10rpx;
padding-left: 10rpx;
border: 2px solid #c0f0f1;
border-radius: 20rpx;
}

.textarea {
border-top: 2px solid #fafafa;
background-color: rgb(238, 247, 247);
}

.vote_button {
border-top: 4px solid #fafafa;
display: flex;
width: 80%;
align-items: center;
margin-left: 73rpx;
}
.vote_carryout{
background-color: rgba(150, 250, 250, 0.315);
box-shadow: 0 0 20px rgb(117, 241, 241);
margin: 20rpx 30rpx 0rpx 70rpx;
border-radius: 20rpx;
height: 460rpx;
width: 620rpx;
}
.vote_carryout_img{
height: 350rpx;
width: 620rpx;
border-radius: 20rpx;
}
.vote_carryout_text{
display: flex;
height: 100rpx;
border-radius: 20rpx;
}
.vote_carryout_text_f{
margin-left: 50rpx;
height: 40rpx;
font-size: 12px;
}
.vote_carryout_text_t{
margin-left: 50rpx;
height: 40rpx;
color: rgba(116, 114, 114, 0.89);
font-size: 12px;
}
.vote_carryout_text_btn{
margin-top: 10rpx;
height: 80rpx;
font-size: 12px;
size: 12px;
background-color: rgb(174, 249, 252);
}

5. 数据

list.js

// pages/vote/list/list.js
var app = getApp();
const api = require('../../../config/api');
const util = require('../../../utils/util.js');
Page({
/**
* 页面的初始数据
*/

data: {
tabs: ['发起投票', '未参与', '已参与', '全部投票'],//顶部导航栏
componentStatus: [true, false, false, false],//用于处理内容显示
array: ['美国', '中国', '巴西', '日本'],
engage:[],//未参与的投票
not:[],//已参与的投票
lists:[],//全部投票信息
meeting_id: '请选择会议',
imageUrl: '',//图片路径
votename: '123'
},
//选择所属会议的事件
meetingChange(e) {
// console.log(e.detail.value)
this.setData({
meeting_id: e.detail.value
})
},
//初始会议信息
meetingini() {
util.request(api.MettingVote).then(res => {
this.setData({
array: res.data.infoList
})
}).catch(res => {
console.log('服器没有开启,使用模拟数据!')
})
},
//初始化未参与的投票
Voteiniengage() {
util.request(api.MettingVoteList,{state:0}).then(res => {
// console.log(res);
this.setData({
engage: res.data
})
}).catch(res => {
console.log('服器没有开启,使用模拟数据!')
})
},
//初始化已参与的投票
Voteininot() {
util.request(api.MettingVoteList,{state:1}).then(res => {
// console.log(res);
this.setData({
not: res.data
})
}).catch(res => {
console.log('服器没有开启,使用模拟数据!')
})
},
//初始化全部投票信息
VoteiniList() {
util.request(api.MettingVoteList).then(res => {
// console.log(res);
this.setData({
lists: res.data
})
}).catch(res => {
console.log('服器没有开启,使用模拟数据!')
})
},
//参与投票的点击事件
voteparticipate(id){
// console.log(id.target.dataset.item)
wx.showModal({
title: '提示',
content: '你是否要贡献出你宝贵的一票?',
success: function (res) {
if (res.confirm) {
//这里是点击了确定以后
util.request(api.MettingVoteupdate, {id:id.target.dataset.item}).then(res => {
// console.log(res)
if (res.errno == 0) {
wx.showToast({
title: '成功投票!!',
icon: 'none',
duration: 1000//持续的时间
})
}
}).catch(res => {
console.log('服器没有开启,发布失败')
})
} else {//这里是点击了取消以后
console.log('用户点击取消')
}
}
})
},
//发起投票的事件
votesubmit(data) {
console.log(data.detail.value)
wx.showModal({
title: '提示',
content: '确定发起该投票吗?',
success: function (res) {
if (res.confirm) {
//这里是点击了确定以后
util.request(api.MettingVoteAdd, data.detail.value).then(res => {
// console.log(res)
if (res.errno == 0) {
wx.showToast({
title: '发布投票成功',
icon: 'none',
duration: 1500//持续的时间
})
}
}).catch(res => {
console.log('服器没有开启,发布失败')
})
} else {//这里是点击了取消以后
console.log('用户点击取消')
}
}
})
},
//已参与按钮的点击事件
Votenotbtn() {
wx.showToast({
title: '已进行投票,不可再投',
icon: 'none',
duration: 1000//持续的时间
})
},
//图片选择器
handleUploadImage() {
wx.chooseImage({
count: 1,
success: (res) => {
const imagePath = res.tempFilePaths[0];
// 处理选择的图片路径
// console.log('选择的图片路径:', imagePath);
this.setData({
imageUrl: imagePath // 更新图片路径,触发重新渲染
});
}
});
},
/**
* 生命周期函数--监听页面加载
*/

onLoad(options) {
this.meetingini();
this.Voteiniengage();
this.Voteininot();
this.VoteiniList();
},

/**
* 生命周期函数--监听页面初次渲染完成
*/

onReady() {

},

/**
* 生命周期函数--监听页面显示
*/

onShow() {

},

/**
* 生命周期函数--监听页面隐藏
*/

onHide() {

},

/**
* 生命周期函数--监听页面卸载
*/

onUnload() {

},

/**
* 页面相关事件处理函数--监听用户下拉动作
*/

onPullDownRefresh() {

},

/**
* 页面上拉触底事件的处理函数
*/

onReachBottom() {

},

/**
* 用户点击右上角分享
*/

onShareAppMessage() {

},
//点击导航栏进行切换下方内容
tabsItemChange(e) {
let index = e.detail.index;
//全部的组件赋值为false
const lists = [false, false, false, false];
//将所点击的组件赋值为true
lists[index] = true;
this.setData({
componentStatus: lists // 更新 data 中的 componentStatus 属性值
});
},
// tabsItemChange(e){
// let index = e.detail.index;
// console.log('vote.index='+index)
// if(index==1 || index==2){
// if (app.globalData.hasLogin) {

// }else{
// wx.navigateTo({
// url: '/pages/auth/login/login',
// })
// }
// }
// }
})

6. 效果展示

发起投票

参与投票

查看所有投票

举报

相关推荐

0 条评论