14.意见反馈页
14.1引入tabs组件
首先新建意见反馈页面feedback,然后个人中心页面加导航跳转
<navigator url="/pages/feedback/feedback" class="app_info_item">意见反馈</navigator>
在JSON中引入tabs组件
{
"usingComponents": {"Tabs":"../../components/Tabs/Tabs"},
"navigationBarTitleText": "意见反馈"
}
在wxml中
<!--pages/feedback/feedback.wxml-->
<Tabs tabs="{{tabs}}" bindtabsItemChange="handletabsItemChange">
内容
</Tabs>
在js中
// pages/feedback/feedback.js
Page({
/**
* 页面的初始数据
*/
data: {
tabs:[
{
id:0,
value:"体验问题",
isActive:true
},
{
id:1,
value:"商品、商家投诉",
isActive:false
}
],
},
// 标题点击事件 从子组件传递过来
handletabsItemChange(e){
// console.log(e);
// 1 获取被点击的标题索引
const {index}=e.detail;
// 2 修改源数组
let {tabs}=this.data;
tabs.forEach((v,i)=>i===index?v.isActive=true:v.isActive=false);
// 3 赋值到data中
this.setData({
tabs
})
},
})
14.2静态结构
<!--pages/feedback/feedback.wxml-->
<Tabs tabs="{{tabs}}" bindtabsItemChange="handletabsItemChange">
<view class="fb_main">
<view class="fb_title">问题的种类</view>
<view class="fb_tips">
<text>功能建议</text>
<text>购买遇到问题</text>
<text>性能问题</text>
<text>其他</text>
</view>
<view class="fb_content">
<textarea placeholder="请描述一下您的问题"></textarea>
<view class="fb_tool">
<button>+</button>
</view>
</view>
<view class="form_btn_wrap">
<button>
<icon type="success_no_circle" size="15" color="white"></icon>
提交
</button>
</view>
</view>
</Tabs>
/* pages/feedback/feedback.wxss */
page{
background-color: #eeeeee;
}
.fb_main{
padding: 20rpx;
color: #666;
}
.fb_tips{
display: flex;
flex-wrap: wrap;
}
text{
width: 30%;
padding: 10rpx;
text-align: center;
background-color: #fff;
margin: 15rpx 10rpx;
}
.fb_content{
background-color: #fff;
margin-top: 20rpx;
}
textarea{
padding: 10rpx;
}
.fb_tool{
display: flex;
flex-wrap: wrap;
padding-bottom: 30rpx;
}
.fb_tool button{
/* button样式后面要加! important */
/* 取消默认margin*/
margin: 0! important;
width: 90rpx! important;
height: 90rpx;
font-size: 40rpx;
display: flex;
justify-content: center;
align-items: center;
margin-left: 20rpx! important;
color: #ccc;
}
.form_btn_wrap{
margin-top: 20rpx;
}
.form_btn_wrap button{
width: 20%! important;
height: 70rpx;
/* 取消默认padding */
padding: 0;
margin-right: 0! important;
color: #fff;
background-color: #ff0000a2;
font-size: 32rpx;
display: flex;
justify-content: center;
align-items: center;
}
14.3自定义图片组件
?首先在components下新建组件文件UpImg并在JSON中引入
{
"usingComponents": {
"Tabs":"../../components/Tabs/Tabs",
"UpImg":"../../components/UpImg/UpImg"
},
"navigationBarTitleText": "意见反馈"
}
?在wxml中使用
<view class="fb_tool">
<button>+</button>
<view class="up_img_ite">
<UpImg></UpImg>
</view>
<view class="up_img_ite">
<UpImg></UpImg>
</view>
<view class="up_img_ite">
<UpImg></UpImg>
</view>
</view>
组件UpImg的代码?
<!--components/UpImg/UpImg.wxml-->
<view class="up_img_wrap">
<image src="https://p0.ssl.qhimgs1.com/sdr/400__/t01690b2f9590cc91ee.jpg"></image>
<icon type="clear" size="23" color="red"></icon>
</view>
/* components/UpImg/UpImg.wxss */
.up_img_wrap{
width: 90rpx;
height: 90rpx;
position: relative;
}
.up_img_wrap image{
width: 100%;
height: 100%;
border-radius: 15rpx;
}
.up_img_wrap icon{
position: absolute;
top: -30rpx;
right: -30rpx;
}
?
14.4选择并显示图片
?在wxml中给button按钮绑定一个点击事件,给UpImg赋值一个属性动态传递数据并对其for循环
<view class="fb_tool">
<button bindtap="handleChooseImg">+</button>
<!-- 当数组是简单数组的时候绑定的key是*this -->
<view class="up_img_ite" wx:for="{{chooseImage}}" wx:key="*this">
<UpImg src="{{item}}"></UpImg>
</view>
在js中?
// pages/feedback/feedback.js
Page({
/**
* 页面的初始数据
*/
data: {
// 被选中的图片的路径数组
chooseImage:[]
},
/* 点击"+"触发tap点击事件
1 调用小程序内置的选择图片的API
2 获取到图片的路径数组
3 把图片路径存到data的变量中
4 页面就可以根据图片数组进行循环显示
*/
handleChooseImg(){
// 调用小程序内置的选择图片API
wx.chooseImage({
// 同时选中的图片数量,最多9张
count: 9,
// 图片的格式 原图 压缩
sizeType:['original','compressed'],
// 图片的来源 相册 照相机
sourceType:['album','camera'],
success:(result)=>{
// console.log(result);
this.setData({
// 图片数组进行拼接(多次上传不是把前面的照片覆盖而是增加)
chooseImage:[...this.data.chooseImage,...result.tempFilePaths]
})
}
})
}
})
在UpImg.js中声明接收什么数据
Component({
/**
* 组件的属性列表
*/
properties: {
// 声明要接受什么数据
src:{
type:String,
value:""
}
},
?在UpImg.wxml中使用传递过来的src属性
<!--components/UpImg/UpImg.wxml-->
<view class="up_img_wrap">
<image src="{{src}}"></image>
<icon type="clear" size="23" color="red"></icon>
</view>
14.5删除图片
?在wxml中绑定点击事件
<view class="up_img_ite" wx:for="{{chooseImage}}" wx:key="*this" bindtap="handleRemoveImg" data-index="{{index}}">
<UpImg src="{{item}}"></UpImg>
</view>
在js中
/* 点击自定义图片组件
1 获取被点击的元素的索引
2 获取data中的图片数组
3 根据索引在数组中删除对应的元素
4 把数组重新设置回data中
*/
handleRemoveImg(e){
// 获取被点击的组件的索引
const {index}=e.currentTarget.dataset;
// console.log(index);
// 获取data中的图片数组
let {chooseImage}=this.data;
// 删除元素
chooseImage.splice(index,1);
this.setData({
chooseImage
})
}
14.6提交功能
在wxml中文本域绑定输入事件,button绑定提交按钮点击事件
<textarea value="{{textVal}}" bindinput="handleTextInput" placeholder="请描述一下您的问题"></textarea>
<button bindtap="handleFormSubmit">
<icon type="success_no_circle" size="15" color="white"></icon>
提交
</button>
在js中
data: {
// 被选中的图片的路径数组
chooseImage:[],
// 文本域的内容
textVal:""
},
// 外网的图片路径数组
UpLoadImgs:[],
/* 点击 提交
1 获取文本域的内容 类似输入框的获取
1.data中定义变量 表示文本域内容
2.文本域绑定一个输入事件 事件触发的时候把输入框的值存入到变量中
2 对这些内容合法性验证
3 验证通过 用户选择的图片上传到专门的图片服务器,返回图片外网的链接
1.遍历图片数组
2.挨个上传
3.自己再维护图片数组 存放图片上传后的外网链接
4 文本域和外网图片的路径一起提交到服务器(只做前端模拟,不会发送请求到后台)
5 清空当前页面
6 返回上一页
*/
// 文本域输入事件
handleTextInput(e){
this.setData({
textVal:e.detail.value
})
},
// 提交按钮的点击事件
handleFormSubmit(){
// 获取文本域的内容和图片数组
const {textVal,chooseImage}=this.data;
// 合法性验证(文本域是否为空)
if(!textVal.trim()){
// 不合法
wx.showToast({
title: '输入不合法',
icon:'none',
mask:'true'
});
return;
}
// 准备上传图片到专门的图片服务器
// 显示正在等待的图标
wx.showLoading({
title:"正在上传中",
mask:true
})
// 判断有没有需要上传的图片数组
if(chooseImage.length!=0){
// 上传文件的API不支持多个文件同时上传 方法:遍历数组挨个上传
chooseImage.forEach((v,i)=>{
wx.uploadFile({
// 被上传的文件路径
filePath: v,
// 上传文件的名称 用途:后台来获取文件
name: 'file',
// 文件要上传到哪里
url: 'https://images.ac.cn/Home/Index/UploadAction/',
// 顺带的文本信息
formData: {},
success:(result)=>{
console.log(result);
// JSON.parse去掉JSON格式
let url=JSON.parse(result.data).url;
// 给UpLoadImgs赋值
this.UpLoadImgs.push(url);
// console.log(UpLoadImgs);
// 所有的图片都上传完毕才触发
if(i===chooseImage.length-1){
// 关闭弹窗
wx.hideLoading();
console.log("把文本的内容和外网的图片数组提交到后台中");
// 提交成功了
// 重置页面
this.setData({
textVal:"",
chooseImage:[]
})
// 返回上一个页面
wx.navigateBack({
delta: 1,
})
}
}
})
})
}
else{
console.log("只是提交的文本");
wx.navigateBack({
delta: 1,
})
}
}
最后完成页代码
<!--pages/feedback/feedback.wxml-->
<Tabs tabs="{{tabs}}" bindtabsItemChange="handletabsItemChange">
<view class="fb_main">
<view class="fb_title">问题的种类</view>
<view class="fb_tips">
<text>功能建议</text>
<text>购买遇到问题</text>
<text>性能问题</text>
<text>其他</text>
</view>
<view class="fb_content">
<textarea value="{{textVal}}" bindinput="handleTextInput" placeholder="请描述一下您的问题"></textarea>
<view class="fb_tool">
<button bindtap="handleChooseImg">+</button>
<!-- 当数组是简单数组的时候绑定的key是*this -->
<view class="up_img_ite" wx:for="{{chooseImage}}" wx:key="*this" bindtap="handleRemoveImg" data-index="{{index}}">
<UpImg src="{{item}}"></UpImg>
</view>
</view>
</view>
<view class="form_btn_wrap">
<button bindtap="handleFormSubmit">
<icon type="success_no_circle" size="15" color="white"></icon>
提交
</button>
</view>
</view>
</Tabs>
/* pages/feedback/feedback.wxss */
page{
background-color: #eeeeee;
}
.fb_main{
padding: 20rpx;
color: #666;
}
.fb_tips{
display: flex;
flex-wrap: wrap;
}
text{
width: 30%;
padding: 10rpx;
text-align: center;
background-color: #fff;
margin: 15rpx 10rpx;
}
.fb_content{
background-color: #fff;
margin-top: 20rpx;
}
textarea{
padding: 10rpx;
}
.fb_tool{
display: flex;
flex-wrap: wrap;
padding-bottom: 30rpx;
}
.fb_tool button{
/* button样式后面要加! important */
/* 取消默认margin*/
margin: 0! important;
width: 90rpx! important;
height: 95rpx;
font-size: 40rpx;
display: flex;
justify-content: center;
align-items: center;
margin-left: 20rpx! important;
color: #ccc;
}
.up_img_ite{
margin-left: 20rpx;
}
.form_btn_wrap{
margin-top: 20rpx;
}
.form_btn_wrap button{
width: 20%! important;
height: 70rpx;
/* 取消默认padding */
padding: 0;
margin-right: 0! important;
color: #fff;
background-color: #ff0000a2;
font-size: 32rpx;
display: flex;
justify-content: center;
align-items: center;
}
// pages/feedback/feedback.js
Page({
/**
* 页面的初始数据
*/
data: {
tabs:[
{
id:0,
value:"体验问题",
isActive:true
},
{
id:1,
value:"商品、商家投诉",
isActive:false
}
],
// 被选中的图片的路径数组
chooseImage:[],
// 文本域的内容
textVal:""
},
// 外网的图片路径数组
UpLoadImgs:[],
// 标题点击事件 从子组件传递过来
handletabsItemChange(e){
// console.log(e);
// 1 获取被点击的标题索引
const {index}=e.detail;
// 2 修改源数组
let {tabs}=this.data;
tabs.forEach((v,i)=>i===index?v.isActive=true:v.isActive=false);
// 3 赋值到data中
this.setData({
tabs
})
},
/* 点击"+"触发tap点击事件
1 调用小程序内置的选择图片的API
2 获取到图片的路径数组
3 把图片路径存到data的变量中
4 页面就可以根据图片数组进行循环显示
*/
handleChooseImg(){
// 调用小程序内置的选择图片API
wx.chooseImage({
// 同时选中的图片数量,最多9张
count: 9,
// 图片的格式 原图 压缩
sizeType:['original','compressed'],
// 图片的来源 相册 照相机
sourceType:['album','camera'],
success:(result)=>{
// console.log(result);
this.setData({
// 图片数组进行拼接(多次上传不是把前面的照片覆盖而是增加)
chooseImage:[...this.data.chooseImage,...result.tempFilePaths]
})
}
})
},
/* 点击自定义图片组件
1 获取被点击的元素的索引
2 获取data中的图片数组
3 根据索引在数组中删除对应的元素
4 把数组重新设置回data中
*/
handleRemoveImg(e){
// 获取被点击的组件的索引
const {index}=e.currentTarget.dataset;
// console.log(index);
// 获取data中的图片数组
let {chooseImage}=this.data;
// 删除元素
chooseImage.splice(index,1);
this.setData({
chooseImage
})
},
/* 点击 提交
1 获取文本域的内容 类似输入框的获取
1.data中定义变量 表示文本域内容
2.文本域绑定一个输入事件 事件触发的时候把输入框的值存入到变量中
2 对这些内容合法性验证
3 验证通过 用户选择的图片上传到专门的图片服务器,返回图片外网的链接
1.遍历图片数组
2.挨个上传
3.自己再维护图片数组 存放图片上传后的外网链接
4 文本域和外网图片的路径一起提交到服务器(只做前端模拟,不会发送请求到后台)
5 清空当前页面
6 返回上一页
*/
// 文本域输入事件
handleTextInput(e){
this.setData({
textVal:e.detail.value
})
},
// 提交按钮的点击事件
handleFormSubmit(){
// 获取文本域的内容和图片数组
const {textVal,chooseImage}=this.data;
// 合法性验证(文本域是否为空)
if(!textVal.trim()){
// 不合法
wx.showToast({
title: '输入不合法',
icon:'none',
mask:'true'
});
return;
}
// 准备上传图片到专门的图片服务器
// 显示正在等待的图标
wx.showLoading({
title:"正在上传中",
mask:true
})
// 判断有没有需要上传的图片数组
if(chooseImage.length!=0){
// 上传文件的API不支持多个文件同时上传 方法:遍历数组挨个上传
chooseImage.forEach((v,i)=>{
wx.uploadFile({
// 被上传的文件路径
filePath: v,
// 上传文件的名称 用途:后台来获取文件
name: 'file',
// 文件要上传到哪里
url: 'https://images.ac.cn/Home/Index/UploadAction/',
// 顺带的文本信息
formData: {},
success:(result)=>{
console.log(result);
// JSON.parse去掉JSON格式
let url=JSON.parse(result.data).url;
// 给UpLoadImgs赋值
this.UpLoadImgs.push(url);
// console.log(UpLoadImgs);
// 所有的图片都上传完毕才触发
if(i===chooseImage.length-1){
// 关闭弹窗
wx.hideLoading();
console.log("把文本的内容和外网的图片数组提交到后台中");
// 提交成功了
// 重置页面
this.setData({
textVal:"",
chooseImage:[]
})
// 返回上一个页面
wx.navigateBack({
delta: 1,
})
}
}
})
})
}
else{
console.log("只是提交的文本");
wx.navigateBack({
delta: 1,
})
}
}
})
|