微信小程序开发uni-app
首先介绍一下博主水平:规划路线Java后端开发,因为参加比赛缺乏前端人员,于是学习前端知识
本人的前端三剑客知识非常垃圾,仅限于看懂,做此日记 记录前端Uni-app学习
学到的知识
uni-app的前端东西就是在官方组件复制粘贴;然后去插件市场下载插件
uni-datetime-picker日期选择器
uni-forms 表单&页面跳转
问题2:后端给我传参字符串我多选框咋回显不上啊???而且我给他传格式也不行
能穿,但是他给我的是字符串数组,得把多选框value改一下!
Uni-app网易优选项目改造
书接上回:前端基础太辣鸡 记录问题
前期页面搭建就不说什么了,首先是JS,后端队友给了我好多API,我不会用,
反正我这么几天的理解就是上B站搜uni的各种课 看自己不会的地方;
uni.request(OBJECT)
这个我直接放在提交方法里面了,因为里面有数据 各种调试+看文档终于搞明白了;
methods: {onClick(e) {console.log('执行click事件', e.data)uni.showToast({title: '点击反馈'});},changeLog(e) {this.valiFormData.datetimerange = e;console.log("datetimerangechange事件:", e);},submit(ref) {this.$refs[ref].validate().then(res => {res.datetimerange=this.valiFormData.datetimerange;console.log('success', res,this.valiFormData.datetimerange );//uni.request({url: 'http://pipibr.com:3000/api/task/insert/',header: {'Content-Type': 'application/x-www-form-urlencoded',},method: "POST",success(res) {//console.log(res.data,"this.valiFormData.datetimerange ",this.valiFormData.datetimerange );console.log(res.data);},data: {userid: 1,name: res.name,price: res.price,phone: res.phone,address: res.add,add: res.sex,//startTime:this.valiFormData.datetimerange ,endTime: 1},});uni.showToast({title: `校验通过`})}).catch(err => {console.log('err', err);})},},
uni-popup弹窗
setTimeout(callback, delay, rest);定时器
this.timer = setInterval(() => {// 关闭所有页面,打开到应用内的某个页面wx.reLaunch({url: '/pages/personal/personal'});clearTimeout(this.timer);}, 1000);
vuex的状态机完整数据流
uni.getStorage(OBJECT)
我一直想在
mutations:{ initInfo(state,info,token){ } },
加一个参数token,加不进去 只能再写一个函数就完了
mutations:{initInfo(state,info){state.userInfo = info}},
mutations:{initInfo(state,info,token){state.userInfo = infostate.token = tokenconsole.log('state.token=',token)}},
index.js导入modules模块
user.js
import {$post} from '../../utils/request.js'
export default {namespaced:true, //开启命名空间后,访问所有属性都需要带模块名state(){return {userInfo:null,token:null,task:null,}},mutations:{initInfo(state,info){state.userInfo = info//console.log('存到initInfo',state.userInfo); },initTask(state,task){state.task= taskconsole.log('存到initTask',state.task); },initToken(state,token){state.token = token//console.log('state.token=',token)}},actions:{userLoginAct(context,info){$post('/api/user/account/token/',info).then(res=>{console.log("login页面res=",res,"info=",info);if(res.code!=200){let title=res.status+" "+res.erroruni.showToast({title,icon:'none'})}else{let title="登录成功!"uni.showToast({title,icon:'none'})this.timer = setInterval(() => {// 关闭所有页面,打开到应用内的某个页面wx.reLaunch({url: '/pages/personal/personal'});clearTimeout(this.timer);}, 1000);info.token=res.data.token;}context.commit('initInfo',info)//存一下//console.log("login页面info=",info);context.commit('initToken',res.data.token)uni.setStorage({key:'userInfo',data:info,key:'token',data:res.data.token,})},}
}
问题1 :怎么在当前user.js页面另外一个userXxx(context,info)函数调用state里的token?
因为接口必须调用token验证只能写在这个登录方法里面调用token很难受!而且只有登录的时候才能获取任务信息
能不能在每个页面都传递token 然后直接重新调用userLoginAct(context,info)传参数。
能!看下面的问题3
问题3:uni如何在methods中调用store的变量
不能直接用,得在js里面import store from '../../store/index.js' //引入仓库
<script>import store from '../../store/index.js' //引入仓库export default {data() {return {// 单选数据源sexs: [{text: '男',value: 0}, {text: '女',value: 1}, {text: '保密',value: 2}],},computed: {user(){let {userInfo}= this.$store.state.userthis.valiFormData.hobby=userInfo.data.hobbyconsole.log('hobby',userInfo.data.hobby,'hobby框内容',this.valiFormData.hobby)return userInfo.data.user.gende},},onReady() {// 设置自定义表单校验规则,必须在节点渲染完毕后执行this.$refs.valiForm.setRules(this.rules)},methods: {onClickItem(e) {console.log(e);this.current = e.currentIndex},submit(ref) {let stoken=this.$store.state.user.token//let {userInfo}= this.$store.state.user//console.log('data',Data);uni.request({url: ' ',data: {// interest : 1 interest : this.valiFormData.hobby },header: {'Content-Type': 'application/x-www-form-urlencoded','Authorization': 'Bearer '+ stoken},method: "POST",success(res) {console.log('res的',valiFormData.hobby);console.log('self的res',res)if(res.statusCode===403){let title="您尚未登录!"uni.showToast({title,icon:'none'})}else if(res.statusCode!=200){console.log(res);let title=res.msg+" "+res.datauni.showToast({title,icon:'none'})}else{let title="更新成功!"uni.showToast({title,icon:'none'})//bug:点击多选框 回显失效}}})},}}
</script>
computed生命周期直接调用状态机数据
computed: {username(){let {userInfo}= this.$store.state.userlet name = userInfo ? userInfo.username : '尚未登录'console.log("name=",name,"userInfo=",userInfo);return name}},
用户信息持久存储及跨组件使用
uni.getStorageSync(KEY) 从本地缓存中同步获取指定 key 对应的内容。
下面针对 小程序如果没有状态机&其它页面也能拿到缓存数据 的存储方法
直接在App.vue
onLaunch: function() {console.log('App Launch')//尝试提取本地存储用户信息try {const value = uni.getStorageSync('userInfo');if (value) { //value:从本地提取出来的对象console.log('value=',value);this.$store.commit('user/initInfo',value)}} catch (e) {// errorconsole.log('提取用户信息失败')}},
地址选择
仿青团社兼职小程序id=6846
在App.vue添加以下的import引用实现icon;
<style lang="scss">/*每个页面公共css */@import url("/static/font/iconfont.css");@import "./static/colorui/main.css";@import "./static/colorui/icon.css";@import './app.scss';
</style>
uni-app中v-for点击跳转指定页面
在v-for里item添加path,传参到方法里,
<view class="nav-item" :data-index="index" data-ptpid="58ac-1481-a7d3-b98e" v-for="(item, index) in navList" :key="item.name" @click="goDetail(item.path)">
方法直接
wx.reLaunch({url:e});
<template><view class="container"><view class="header"><view class="header-img"><view class="header-image-left"><image lazyLoad @tap="chooseImage" data-ptpid="4c7f-1f6c-b145-b80f" :src="avatarUrl + '?imageView2/0/w/180'" v-if="avatarUrl"></image><view class="header-name">{{ userName || (isLogin ? '暂无小主信息' : '登录开启赚钱之旅哦') }}</view></view></view></view><inner-banner className="mg32" :list="bannerList" ptpId="1ab7-1b95-8e0e-3b22"></inner-banner><view class="nav-box"><view class="nav-item" :data-index="index" data-ptpid="58ac-1481-a7d3-b98e" v-for="(item, index) in navList" :key="item.name" @click="goDetail(item.path)"><view class="nav-title"><view :class="'iconfont ' + item.icon"></view>{{ item.name }}</view><view class="nav-icon"><view v-if="item.num || item.num === 0">{{ item.num }}</view><view class="iconfont iconarrow"></view></view></view></view><view class="login-mask" v-if="!isLogin"><open-button @initData="loginSuccess" openType="getPhoneNumber" ptpId="mineLogin"></open-button></view><qts-dialog @reset="handleReset" :isDialog="isDialog" :signInfo="signInfo"></qts-dialog></view>
</template><script>var n = ['https://qiniu-image.qtshe.com/719defaultAvatar1.png', 'https://qiniu-image.qtshe.com/719defaultAvatar2.png', 'https://qiniu-image.qtshe.com/719defaultAvatar3.png'];
var app = getApp();
export default {components: {openButton,qtsDialog,innerBanner,downloadDialog},data() {return {money: '0.00',score: 0,perfectResume: false,bannerList: [],navList: [{icon: 'iconmy_people_normal',name: '个人信息',// cb: function () {// uni.navigateToMiniProgram({// // appId: 'wx71ff0ba1e3426010',// path: '../self/self'// });// }// 关闭所有页面,打开到应用内的某个页面path : '/pages/self/self'},{icon: 'iconmy_people_normal',name: '身份认证',cb: function () {uni.navigateToMiniProgram({url: '/pages/authen/authen'});}},{icon: 'iconmy_collect_normal',name: '已发布的任务',// num: 0, 在后面显示数字cb: function () {uni.navigateTo({path: '../publish/publish' });}},{icon: 'iconmy_new_normal',name: '已完成的任务',cb: function () {uni.navigateTo({path: '../history/history'});}},{icon: 'iconmy_site_normal',name: '联系我们',cb: function () {uni.navigateTo({path: '../about/about'});}}],userApplyStatistics: {allCount: 0,hasApplyCount: 0,applyOngoingCount: 0,applySuccessCount: 0},isDialog: false,signInfo: {attendanceNumber: '',attendanceIntegralList: '',attendanceTotal: '',beansList: ''},beansList: [5, 5, 5, 5, 50, 5, 100],attendance: false,userName: '',avatarUrl: 'https://qiniu-image.qtshe.com/719defaultAvatar2.png',isLogin: false};},onLoad: function () {uni.hideShareMenu();},onShow: function () {this.resourceBanner();this.isLogin = true;},onShareAppMessage: function () {return {title: '每日签到领青豆,爆款好物0元得>>',imageUrl: 'https://qiniu-image.qtshe.com/early1024/share_qiandao.png',path: '/pages/index/index?pt=8'};},methods: {// 跳转到简历完善页面skipToResume: function () {uni.navigateTo({url: '/pages/self/self',fail: function(err) {console.log(err);}});},goDetail(e){var that = this;console.log(e);wx.reLaunch({url: e}); }}};
</script>
<style lang="scss">@import './mine.scss';
</style>
v-for如果是空数组,运行时在wxml不显示
问题4:怎么把后端过来的数组赋值给自己的data
下面这篇
后端以ssm框架拟写接口 前端利用uniapp调用接口,实 现数据的展示以及基本的增删改查.
uni-nav-bar导航栏组件,主要用于头部导航
uni-card卡片组件
问题5:怎么把每个v-for的item点击的时候跳到新页面
如果每个详情页面都要配新页面好烦啊,而且不可能实现,因为无法知道后端传来的数据数量
答案:新建页面 直接页面之间传对象
问题6:SyntaxError: Unexpected token o in JSON at position 1
把JSON.parse去掉就可以了
onLoad(options) {//接受参数this.goodsObj =JSON.parse(options.taskItem);//这行 没有JSON.parse 就undefinedconsole.log('detail接受参数',options.taskItem,'name',this.goodsObj.name);//这行 有JSON.parse 就SyntaxError: Unexpected token o in JSON at position 1},
问题7:我的需求,在当前页面用onload生命周期存task,再赋值给data数据失败因为代码顺序是
onLoad() {let {userInfo}=this.$store.state.user//let {userInfo}= this.$store.state.userlet userid=userInfo.data.user.idthis.$store.dispatch('user/userTask',userid)let {task}=this.$store.state.userconsole.log('publish页面task',task,'Info',userInfo,this.list);},
这样就是存完就取不行的!存的慢
computed: {username(){let {userInfo}= this.$store.state.userlet {task}=this.$store.state.userthis.list=task console.log('publish页面task',task,'Info',userInfo,this.list);return userInfo.data.user.id}, },onLoad() {let {userInfo}=this.$store.state.user//let {userInfo}= this.$store.state.userlet userid=userInfo.data.user.idthis.$store.dispatch('user/userTask',userid) },
笨法:onLoad存 调用computed取赋值;
小程序生命周期 & 页面生命周期 & 页面相关事件处理函数 & 简易双向绑定 & 表单组件
把uni.request得到的数据动态放到computed里面,会一变化,就一直蹦;
看完上面的,我现在把onLoad不变,动态的数据放到onShow里面不知道能不能解决问题8;
!问题8:我使用computed返回name,但是修改数据后不能实时更新
关键在于computed只执行一次,烦死了!用update没反应;
【uni-app框架】Vue之实时更新响应式数据的方法【使用生命周期updated方法】
问题9:做多选框后端数据赋值到表单回显时onLoad和computed使用区别
除了多选框的uniforms后端数据赋值到表单两者都差不多:
computed: {user(){ let {userInfo}= this.$store.state.user// this.selftoken=this.$store.state.user.token// console.log("self页面:userInfo=",userInfo,'user=',userInfo.data.user,'token',selftoken)this.valiFormData.name=userInfo.data.user.usernamethis.valiFormData.hobby=userInfo.data.hobbyconsole.log('hobby',userInfo.data.hobby)return userInfo},},
onLoad() {let {userInfo}= this.$store.state.user// this.selftoken=this.$store.state.user.token// console.log("self页面:userInfo=",userInfo,'user=',userInfo.data.user,'token',selftoken)this.valiFormData.name=userInfo.data.user.usernamethis.valiFormData.hobby=userInfo.data.hobbyconsole.log('hobby',userInfo.data.hobby)},
但是做多选框必须放在onLoad()下面,不然uni-app计算属性(computed)、方法(methods)、监听(watch)当点击多选框,即计算属性computed变动时会继续调用computed()里的方法;
如何在uniapp的css里引用图片
.education-wrap {background: #f6f7fb url('https://qiniu-image.qtshe.com/20200824_edcuationHeader.png') no-repeat top;background-size: 100% 260rpx;min-height: 100vh;padding-top: 226rpx;position: relative;overflow: hidden;padding-bottom: 176rpx;
}
uniapp 设置页面背景图片
uniapp实现本地图片的上传以及身份证的智能识别
bigBannerList: [{image: 'https://qiniu-image.qtshe.com/1627351727554_768.png'}],
在js里直接调本地图片{image:'/static...'}不显示,只能下面这样,鼠鼠我啊,真的是太菜了捏。
import img from '@/static/images/indexbigbanner.png';
bigBannerList: [{image: img}],
background: url('~@/static/imgs/xxx/bg.png');
好像这样可以,等爷有空去看看;
@tap与@click的区别
想用taskId数组传给后端,得到task的任务详情,不咋会js语法,我对ChatGPT提出以下问题:
Vue的<script>中,可以使用JavaScript的循环语句来遍历数组或对象。
例如,遍历一个数组可以使用for循环:
<script>
export default {data() {return {items: ['apple', 'banana', 'orange']}},mounted() {for (let i = 0; i < this.items.length; i++) {console.log(this.items[i])}}
}
</script>
遍历一个对象可以使用for...in循环:
<script>
export default {data() {return {person: {name: 'Tom',age: 18,gender: 'male'}}},mounted() {for (let key in this.person) {console.log(key + ': ' + this.person[key])}}
}
</script>
另外,在Vue中也可以使用v-for指令来进行循环渲染,例如:
<template><div><ul><li v-for="(item, index) in items" :key="index">{{ item }}</li></ul></div>
</template><script>
export default {data() {return {items: ['apple', 'banana', 'orange']}}
}
</script>
上面的代码将会渲染一个包含三个列表项的无序列表。在v-for指令中,item表示数组中的每个元素,index表示数组的索引。:key属性用于提高Vue的渲染性能。
vue的<script>里面怎么遍历,然后将遍历到的东西存到data的数组里
在Vue的<script>中,可以使用v-for指令进行遍历。具体步骤如下:
在data中定义一个空数组,用于存储遍历到的数据,例如:
data() {return {items: []}
}
在模板中使用v-for指令进行遍历,并将遍历到的数据存入items数组中,例如:
<template><div><ul><li v-for="(item, index) in itemList" :key="index">{{ item }}</li></ul></div>
</template><script>
export default {data() {return {items: []}},computed: {itemList() {return ['item1', 'item2', 'item3']}},mounted() {// 将遍历到的数据存入items数组中this.itemList.forEach(item => {this.items.push(item)})}
}
</script>
在上面的例子中,v-for指令会遍历itemList数组中的每个元素,并将遍历到的数据存入item变量中。items数组会在mounted钩子中被遍历,将遍历到的数据存入其中。
vue的<script>里面怎么遍历对象,然后将遍历到的属性存到data的数组里
<template><div><ul><li v-for="property in properties">{{ property }}</li></ul></div>
</template><script>
export default {data() {return {person: {name: 'Tom',age: 18,gender: 'Male'},properties: []}},mounted() {this.properties = Object.keys(this.person)}
}
</script>
最终成功,感觉更多的是js语法的学习!
computed: {username(){let {userInfo}= this.$store.state.userlet {history}=this.$store.state.userfor (var key in history) {console.log(history[key].taskId)this.taskid.push(history[key].taskId)}console.log('history页面',, this.taskid); return ..},},onLoad() {let {userInfo}=this.$store.state.user//let {userInfo}= this.$store.state.userlet userid=userInfo.data.user.idthis.$store.dispatch('user/acceptHistory',userid)},
uniapp跳转页面成功,点击确定按钮进行跳转,延迟跳转
uni.showModal({title:"感谢您的反馈,我们将尽快整改!",showCancel:false,success:function(){uni.switchTab({url:'/pages/mine/mine',})}})
vue的数组[]转换成字符串以get方式传给后端
可以使用JavaScript中的数组方法join()将数组转换为字符串,然后将字符串作为参数传递给后端