uniapp社区交友开发前端模块开发

源码可以提供下载,详情访问末尾码云地址

环境搭建和创建项目

开发环境搭建

  • 使用HubilderX
  • 安装对应插件

创建uniapp项目

  • 创建项目(名称:社区交友)
  • 真机调试或微信开发者工具调试

App.vue引入全局公共样式

引入官方css样式库

  • 新建模板项目hello uniapp

  • 复制模板common下的css

  • 在本项目的app.vue进行引入css文件 @import “./common/uni.css ” (还要引入uni.tff文件,否则报错)

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xizHMjdI-1649380676444)(uniapp社区交友开发.assets/image-20220322164136184-16479384973031.png)]

引入自定义图标

  • 阿里巴巴矢量图标库 https://www.iconfont.cn/

  • 下载所选图标至项目打包 得到压缩文件

  • 修改icon.css文件去掉url,引入文件 测试图标使用

    <view><text class="iconfont icon-smile" style="font-size: 100rpx; color: red;"></text>
    </view>
    

引入css动画库

  • 下载animate.css

  • 引入animate.css

  • 测试css动画库的使用

    <view style="display: flex;justify-content: center;padding: 50rpx;"> <view class="" hover-class=" animated rubberBand" style="border: 1rpx solid black; padding: 20rpx;">点击效果</view></view>
    

设置全局属性globalStyle

  • 解析page.json文件 看官方文档

  • 设置导航栏的样式

    "globalStyle": {"navigationBarTextStyle": "black", //导航栏字体颜色"navigationBarTitleText": "社区交友",//导航栏文字"navigationBarBackgroundColor": "#FFF",//背景颜色"backgroundColor": "#FFF"}
    

底部导航开发

  • 设置图标(图片为png,81*81)用矢量图标库下载

  • 配置tabBar前提要配置pages数组页面

    "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages{"path": "pages/index/index","style": {}},{"path" : "pages/news/news","style" :                                                                                    {"navigationBarTitleText": "","enablePullDownRefresh": false}},{"path" : "pages/msg/msg","style" :                                                                                    {"navigationBarTitleText": "","enablePullDownRefresh": false}},{"path" : "pages/my/my","style" :                                                                                    {"navigationBarTitleText": "","enablePullDownRefresh": false}}],"tabBar": {"color": "#323232","selectedColor": "#FC5C82","backgroundColor": "#FFF","borderStyle": "black","list": [{"pagePath": "pages/index/index","text": "首页","iconPath": "static/tabbar/index.png","selectedIconPath": "static/tabbar/indexed.png"},{"pagePath": "pages/news/news","text": "动态","iconPath": "static/tabbar/news.png","selectedIconPath": "static/tabbar/newsed.png"},{"pagePath": "pages/msg/msg","text": "消息","iconPath": "static/tabbar/paper.png","selectedIconPath": "static/tabbar/papered.png"},{"pagePath": "pages/my/my","text": "我的","iconPath": "static/tabbar/home.png","selectedIconPath": "static/tabbar/homeed.png"}]}
    

uni-app和vuejs基础快速上手

view和text组件和动画的使用

  • hover-class的测试使用
  • text的测试使用
  • 两个内置组件的使用可参考官方文档

uniapp的css3选择器

  • 普通的选择器 id就用#,class就用.,什么都不加默认全部

  • 父级下的子级菜单的选择器

    .box>view:first-of-type{background-color: red;
    }
    .box>view:last-of-type{background-color: pink;
    }
    .box>view:nth-child(2){background-color: yellow;
    }
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SvOmDgZ5-1649380676446)(uniapp社区交友开发.assets/image-20220323110150462-16480045116861.png)]

  • 奇偶选择器

    //奇数选择器
    .box>view:nth-of-type(odd){background-color: red;
    }
    //偶数选择器
    .box>view:nth-of-type(even){background-color: green;
    }
    //偶数选择器
    .box:nth-of-type(even){background-color: green;
    }
    

flex布局快速入手

  • display:flex 外层使用,块内元素挤在一行内
  • justify-content:常用center,水平居中
  • align-items:常用center,垂直居中
  • felx-direction:改变排序方式,从行转换成列
  • felx-shirink:0 不被压缩
  • flex:1占一份 2占两份

数据渲染

  • {{}}获取data中的数据渲染
  • @tap触发点击事件

class和style的绑定

  • 绑定class用冒号:class
  • :class={‘class1’:isActive}
  • s:tyle=" {‘color’: Color,‘font-size’:num+‘px’}"

条件渲染

  • v-if的使用
  • v-show是会渲染只是不显示
  • 一般在template里面用v-if

列表渲染

  • v-for
  • 官方文档建议v-for写在

事件处理器

  • @tap点击事件
  • @tap.stop点里面不会触发外面的事件

监听属性

  • watch

  • 测试

    <template><view><view>{{num}}</view><button @tap="changNum()">按钮</button></view>
    </template><script>export default {data() {return {num:0}},watch:{num(val){console.log(val);}},methods: {changNum(){this.num++;}}}
    </script><style>
    button{background: blue;display: flex;justify-content: center;align-items: center;font-size: 15px;color: white;
    }
    </style>
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Gyz1MrF9-1649380676447)(uniapp社区交友开发.assets/image-20220323154220758-16480213421241.png)]

计算属性

  • 常用于数据的格式化

  • computed

  • 测试运用

    <template><view>{{formatWeight}}</view>
    </template><script>export default {data() {return {weight:2100}},computed:{formatWeight(){return (this.weight>1000)?this.weight/1000+'kg':this.weight+'g';}}}
    </script><style></style>

首页开发

page.json配置

  • 导航栏配置根据官方文档配置

    {"path": "pages/index/index","style": {"app-plus": {// 导航栏配置"titleNView":{// 搜索框配置"searchInput":{"align":"center","backgroundColor":"#F5F4F2","borderRadius":"4px","disabled":true,"placeholder":"搜索帖子","placeholderColor":"#6D6C67"},"buttons":[{"color":"#333333","colorPressed":"#FD597C","float":"right","fontSize":"20px","fontSrc":"/static/iconfont.ttf","text":"\ue668"}]}}}}
    
  • 用真机调试成功,微信开发者工具旁边无显示

图文列表样式

  • 封装free.css把常用样式封装 如==flex:display;justify-content:center;algin-items:center、

  • 引入自定义css库

  • 列表开发

    <view style="padding: 20rpx;"><view  class="flex;justify-between;align-center"><!-- 头像,昵称 --><view class="flex;align-center"><!-- 头像 --><image src="/static/common//nothing.png" class="mr-1; rounded"  style="width:65rpx;height:65rpx"></image><view><view style="font-size: 30rpx;">昵称</view><view style="color: #9d9589;font-size: 20rpx;">2022-3-15</view></view></view ><!-- 按钮 --><view class="flex;align-center; justify-center" style="background: #FF4A6A; width:90rpx; height:50rpx;color: white;" >关注</view></view><!-- 文章内容 --><view>哈哈哈</view><!-- 图片 --><view class="mt-1" ><image src="/static/demo/datapic/45.jpg" style="width: 100%; height: 350rpx;" lazy-load="true"></image></view><!-- 按钮 --><view class="flex" ><view  class="flex;align-center; justify-center flex-1"><view class="iconfont icon-dianzan2 "></view><view>赞</view></view><view  class="flex;align-center; justify-center flex-1"><view class="iconfont icon-cai; mr-2" ></view><view>踩</view></view><view  class="flex;align-center; justify-center flex-1"><view class="iconfont icon-pinglun2; mr-2"  ></view><view>评论</view></view><view  class="flex;align-center; justify-center flex-1"><view class="iconfont icon-zhuanfa1; mr-2" ></view><view>转发</view></view></view></view>
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-daoAQo1N-1649380676447)(uniapp社区交友开发.assets/image-20220323193232107.png)]

封装列表样式

  • 继续使用free.css封装代码

    <view><view class="p-2"><view  class="flex;justify-between;align-center"><!-- 头像,昵称 --><view class="flex;align-center"><!-- 头像 --><image src="/static/common//nothing.png" class="mr-1; rounded-circle"  style="width:65rpx;height:65rpx"></image><view><view class="font" style="line-height: 1.5;">昵称</view><view style=" ine-height: 1.5;" class="font-small; text-light-muted">2022-3-15</view></view></view ><!-- 按钮 --><view class="flex;align-center; justify-center; rounded; text-white; bg-main" style=" width:90rpx; height:50rpx;" >关注</view></view><!-- 文章内容 --><view class="font-md; my-1">我是标题</view><!-- 图片 --><view class="mt-1" ><image src="/static/demo/datapic/45.jpg" class="rounded" style="width: 100%; height: 350rpx;" lazy-load="true"></image></view><!-- 按钮 --><view class="flex" ><view  class="flex;align-center; justify-center flex-1"><view class="iconfont icon-dianzan2 "></view><view>赞</view></view><view  class="flex;align-center; justify-center flex-1"><view class="iconfont icon-cai; mr-2" ></view><view>踩</view></view><view  class="flex;align-center; justify-center flex-1"><view class="iconfont icon-pinglun2; mr-2"  ></view><view>评论</view></view><view  class="flex;align-center; justify-center flex-1"><view class="iconfont icon-zhuanfa1; mr-2" ></view><view>转发</view></view></view></view></view>
    
  • 封装本项目公共css(common.css 记得引入)

    .bg-main{background: #FF4A6A;
    }
    
  • 封装成组件动态渲染

    <block v-for="(item,index) in list" :key="index"><commonList :item="item" :index="index" ></commonList></block>import commonList from '@/components/common/common-list';components:{commonList},<view class="p-2"><view  class="flex;justify-between;align-center"><!-- 头像,昵称 --><view class="flex;align-center"><!-- 头像 --><image :src="item.userPic" class="mr-1; rounded-circle"  style="width:65rpx;height:65rpx"></image><view><view class="font" style="line-height: 1.5;">{{item.username}}</view><view style=" ine-height: 1.5;" class="font-small; text-light-muted">{{item.newstime}}</view></view></view ><!-- 按钮 --><view class="flex;align-center; justify-center; rounded; text-white; bg-main" style=" width:90rpx; height:50rpx;" >关注</view></view><!-- 文章内容 --><view class="font-md; my-1">{{item.title}}</view><!-- 图片 --><view class="mt-1" ><image :src="item.titlePic" class="rounded" style="width: 100%; height: 350rpx;" lazy-load="true"></image></view><!-- 按钮 --><view class="flex" ><view  class="flex;align-center; justify-center flex-1"><view class="iconfont icon-dianzan2; mr-2"></view><view>{{item.support.support_count}}</view></view><view  class="flex;align-center; justify-center flex-1"><view class="iconfont icon-cai; mr-2" ></view><view>{{item.support.unsupport_count}}</view></view><view  class="flex;align-center; justify-center flex-1"><view class="iconfont icon-pinglun2; mr-2"  ></view><view>{{item.comment_count}}</view></view><view  class="flex;align-center; justify-center flex-1"><view class="iconfont icon-zhuanfa1; mr-2" ></view><view>{{item.share_num}}</view></view></view></view>export default{props:{item:Object,key:Number}}
    

全局分割线开发

  • 封装组件divider.vue

    <!-- 分割线样式 --><view style="height: 15rpx; background-color: #F5F5F4;"></view>
    
  • 引入全局组件(分割线常用)

    import divider from '@/components/common/divider.vue';
    Vue.component('divider',divider);<block v-for="(item,index) in list" :key="index"><commonList :item="item" :index="index"></commonList><divider></divider>
    </block>
    

优化列表组件-动画特效

  • 图片显示优化
  • 关注、图标的点击动画特效(jello)
  • 图标主色调变化 加字体颜色
  • 为各元素添加click事件 (头像、关注、标题、图片、点赞、踩)
<template><view><view class="p-2"><view class="flex;justify-between;align-center"><!-- 头像,昵称 --><view class="flex;align-center"><!-- 头像 --><image :src="item.userPic" class="mr-1; rounded-circle" style="width:65rpx;height:65rpx" @click="openSapce()"></image><view><view class="font" style="line-height: 1.5;">{{item.username}}</view><view style=" ine-height: 1.5;" class="font-small; text-light-muted">{{item.newstime}}</view></view></view><!-- 按钮 --><view class="flex;align-center; justify-center; rounded; text-white; bg-main; animated faster "style=" width:90rpx; height:50rpx;" hover-class="rubberBand" @click="follow()">关注</view></view><!-- 文章内容 --><view class="font-md; my-1" @click="openDetail()" >{{item.title}}</view><!-- 图片 --><view class="mt-1" v-if="item.titlePic" @click="openDetail()"><image :src="item.titlePic" class="rounded" style="width: 100%; height: 350rpx;" lazy-load="true"></image></view><!-- 按钮 --><view class="flex"><view class="flex;align-center; justify-center flex-1 animated faster" hover-class="jello text-main" @click="doSupport('support')"><view class="iconfont icon-dianzan2; mr-2;"></view><view>{{item.support.support_count}}</view></view><view class="flex;align-center; justify-center flex-1 animated faster" hover-class="jello text-main" @click="doSupport('unsupport')"><view class="iconfont icon-cai; mr-2 "></view><view>{{item.support.unsupport_count}}</view></view><view class="flex;align-center; justify-center flex-1 animated faster" hover-class="jello  text-main" @click="openDetail()"><view class="iconfont icon-pinglun2; mr-2"></view><view>{{item.comment_count}}</view></view><view class="flex;align-center; justify-center  flex-1 animated faster" hover-class="jello text-main" @click="openDetail()"><view class="iconfont icon-zhuanfa1; mr-2"></view><view>{{item.share_num}}</view></view></view></view></view>
</template><script>export default {props: {item: Object,index: Number},methods:{openSapce(){console.log("打开个人空间");},follow(){console.log("关注");},openDetail(){console.log("打开详情页");},doSupport(type){console.log(type);}}}
</script><style>
</style>

优化列表组件-关注功能

  • 关注按钮的显示
  • 子组件触发父组件方法更新isFollowz
<view class="flex;align-center; justify-center; rounded; text-white; bg-main; animated faster "style=" width:90rpx; height:50rpx;" hover-class="rubberBand" @click="follow()" v-if="!item.isFollow">关注</view>follow(){// 触发父级follow方法this.$emit('follow',this.index);},<commonList :item="item" :index="index" @follow="follow(index)"></commonList>methods: {follow(index){this.list[index].isFollow=true;uni.showToast({title:'关注成功'})}}

优化列表组件-顶踩功能

  • 绑定class渲染
  • 方法参数传递
  • 父方法实现
<view class="flex;align-center; justify-center flex-1 animated faster" hover-class="jello text-main" @click="doSupport('support')":class="item.support.type==='support'?'support-active':''"><view class="iconfont icon-dianzan2; mr-2;"></view><view>{{item.support.support_count>0?item.support.support_count:'支持'}}</view></view>doSupport(type){this.$emit('doSupport',{type:type,index:this.index})}<commonList :item="item" :index="index" @follow="follow" @doSupport="doSupport"></commonList>doSupport(e) {let obj=this.newList[this.tabIndex].list[e.index]console.log(obj);if (obj.support.type === '') {//无操作obj.support[e.type + '_count']++;} else if (obj.support.type === 'support' && e.type === 'unsupport') {//之前是顶,顶减一,踩加一obj.support.support_count--;obj.support.unsupport_count++;} else if (obj.support.type === 'unsupport' && e.type === 'support') {//之前是踩,顶加一,踩减一obj.support.support_count++;obj.support.unsupport_count--;}obj.support.type = e.type;let msg = e.type === 'support' ? '顶' : '踩';uni.showToast({title: msg + '成功'})},

滚动tab导航开发

  • 顶部导航选项卡

    <scroll-view class="scroll-row border-bottom" scroll-x="true" :scroll-into-view="scrollInto" scroll-with-animation="true"><view v-for="(item,index) in tabBars" :key="index" class="scroll-row-item px-3 py-2 font-md " :id="'tab'+index":class="tabIndex===index?'text-main font-lg font-weight-bold':''" @click="doTab(index)">{{item.name}}</view></scroll-view>tabIndex:0,scrollInto:'',tabBars:[{name:'首页'},{name:'体育'},{name:'军事'},{name:'热点'},{name:'新闻'},{name:'娱乐'},{name:'电竞'},{name:'国际'},{name:'国家'}],doTab(index){this.tabIndex=index;this.scrollInto='tab'+index;}
    
  • 下面容器能做到切换与导航栏一样,容器也能拉取

    <swiper duration=150 @change="onChange" :current="tabIndex" :style="'height:'+scrollH+'px'"><swiper-item v-for="(item,index) in tabBars" :key="index"  ><scroll-view scroll-y="true" :style="'height:'+scrollH+'px'"><view v-for="i in 100">{{i}}</view></scroll-view></swiper-item></swiper>doTab(index){this.tabIndex=index;this.scrollInto='tab'+index;},onChange(e){this.doTab(e.detail.current);}onLoad() {const res = uni.getSystemInfoSync();this.scrollH=res.windowHeight-uni.upx2px(101);console.log(this.scrollH);},
    
  • 列表显示

    <swiper duration=150 @change="onChange" :current="tabIndex" :style="'height:'+scrollH+'px'"><swiper-item v-for="(item,index) in newList" :key="index"  ><scroll-view scroll-y="true" :style="'height:'+scrollH+'px'"><block v-for="(item2,index2) in item.list" :key="index"><commonList :item="item2" :index="index2" @follow="follow()" @doSupport="doSupport()"></commonList><divider></divider></block></scroll-view></swiper-item></swiper>getData(){let arr=[];for (var i = 0; i < this.tabBars.length; i++) {arr.push({list: [{userPic: '/static/common//nothing.png',username: '',newstime: '',isFollow: false,title: '我是标题',titlePic: '/static/demo/datapic/45.jpg',support: {type: 'support',support_count: 1,unsupport_count: 2},comment_count: 1,share_num: 0},{userPic: '/static/common//nothing.png',username: '',newstime: '',isFollow: false,title: '我是标题',titlePic: '',support: {type: 'unsupport',support_count: 2,unsupport_count: 2},comment_count: 1,share_num: 1},{userPic: '/static/common//nothing.png',username: '',newstime: '',isFollow: false,title: '我是标题',titlePic: '',support: {type: '',support_count: 2,unsupport_count: 2},comment_count: 1,share_num: 1}]})};this.newList=arr;},
    

上拉加载组件开发

  • 静态的开发

    <scroll-view scroll-y="true" :style="'height:'+scrollH+'px'" @scrolltolower="loadMore(index)"><block v-for="(item2,index2) in item.list" :key="index"><commonList :item="item2" :index="index2" @follow="follow()" @doSupport="doSupport()"></commonList><divider></divider></block><view class="py-2 flex justify-center align-center"><view class="text-light-muted">{{item.loading}}</view></view></scroll-view>
    
  • 触底函数的开发

    loadMore(index){let item=this.newList[index];item.loading='加载中.';setTimeout(()=>{//复制文本item.list=[...item.list,...item.list];},2000)}
    

封装上拉加载组件

  • 优化加载判断

    loadMore(index){let item=this.newList[index];if(!item==='上拉加载更多'){return;}item.loading='加载中...';setTimeout(()=>{item.list=[...item.list,...item.list];item.loading='上拉加载更多';},10000)}
    
  • 封装load-more.vue 并引入

    <template><view class="py-2 flex justify-center align-center"><view class="text-light-muted">{{loading}}</view></view>
    </template><script>export default{props:{loading:String}}
    </script>import loadMore from '@/components/common/load-more';export default {components: {commonList,loadMore},
    }
    

封装无数据默认组件

  • 无数据环境测试

    const demo=[{userPic: '/static/common//nothing.png',username: '',newstime: '',isFollow: false,title: '我是标题',titlePic: '/static/demo/datapic/45.jpg',support: {type: 'support',support_count: 1,unsupport_count: 2},comment_count: 1,share_num: 0},{userPic: '/static/common//nothing.png',username: '',newstime: '',isFollow: false,title: '我是标题',titlePic: '/static/demo/datapic/45.jpg',support: {type: 'unsupport',support_count: 2,unsupport_count: 2},comment_count: 1,share_num: 1},{userPic: '/static/common//nothing.png',username: '',newstime: '',isFollow: false,title: '我是标题',titlePic: '',support: {type: '',support_count: 2,unsupport_count: 2},comment_count: 1,share_num: 1}]getData() {let arr = [];for (var i = 0; i < this.tabBars.length; i++) {let obj = {loading:'上拉加载更多',list: []}if(i<2){obj.list=demo;}arr.push(obj)};this.newList = arr;},
    
  • 封装nothing.vue组件 全局引入

    <template v-if="item.list.length>0"><scroll-view scroll-y="true" :style="'height:'+scrollH+'px'" @scrolltolower="loadMore(index)"><block v-for="(item2,index2) in item.list" :key="index"><commonList :item="item2" :index="index2" @follow="follow()" @doSupport="doSupport()"></commonList><divider></divider></block><loadMore :loading="item.loading"></loadMore></scroll-view></template><template v-else><no-thing></no-thing></template>import noThing from '@/components/common/no-thing.vue';
    Vue.component('no-thing',noThing);
    

搜索页开发

  • 创建页面search,配置pages.json

          {"path": "pages/index/index","style": {"app-plus": {// 导航栏配置"titleNView":{// 搜索框配置"searchInput":{"align":"center","backgroundColor":"#F5F4F2","borderRadius":"4px","disabled":true,"placeholder":"搜索帖子","placeholderColor":"#6D6C67"},"buttons":[{"color":"#333333","colorPressed":"#FD597C","float":"right","fontSize":"20px","fontSrc":"/static/iconfont.ttf","text":"\ue668"}]}}}},{"path" : "pages/news/news","style" :                                                                                    {"navigationBarTitleText": "","enablePullDownRefresh": false}},{"path" : "pages/msg/msg","style" :                                                                                    {"navigationBarTitleText": "","enablePullDownRefresh": false}},{"path" : "pages/my/my","style" :                                                                                    {"navigationBarTitleText": "","enablePullDownRefresh": false}},{"path" : "pages/search/search","style": {"app-plus": {// 导航栏配置"titleNView":{// 搜索框配置"searchInput":{"align":"center","backgroundColor":"#F5F4F2","borderRadius":"4px","placeholder":"搜索帖子","placeholderColor":"#6D6C67"},"buttons":[{"color":"#333333","colorPressed":"#FD597C","float":"right","fontSize":"14px","text":"搜索"}]}}}}
    
  • 监听点击导航栏搜索框事件, 实现跳转,用官方api

    onNavigationBarSearchInputClicked() {uni.navigateTo({url: '../search/search'})},
    
  • 搜索历史开发

    <view><view class="py-2 font-md px-2">搜索历史</view><view class="flex flex-wrap"><view class="border rounded font mx-2 my-1 px-2 " v-for="(item,index) in list" :key="index"hover-class="bg-light">{{item}}</view></view></view>
    
  • 监听导航输入

    onNavigationBarSearchInputChanged(e) {this.searchText=e.text;}
    
  • 监听导航搜索按钮

    onNavigationBarButtonTap(e) {if(e.index===0){this.searchEvent();}},
    
  • 搜索事件, 收起键盘,处于loading状态, 展示搜索结果,隐藏loading提示框

    searchEvent(){uni.hideKeyboard();uni.showLoading({title:'加载中'})setTimeout(()=>{this.serachList=demo;uni.hideLoading();},3000)}
    
  • 搜索结果列表 引入commonlist,遍历,优化搜索历史与列表存在问题

    <view><template v-if="this.serachList.length===0"><view class="py-2 font-md px-2">搜索历史</view><view class="flex flex-wrap"><view class="border rounded font mx-2 my-1 px-2 " v-for="(item,index) in list" :key="index"hover-class="bg-light">{{item}}</view></view></template><template v-else><block v-for="(item,index) in serachList" :key="index" ><commonList :item="item" :index="index"></commonList></block></template></view>import commonList from '@/components/common/common-list.vue';export default {components:{commonList},
    }
    
  • 点击搜索历史的事件

    <view class="flex flex-wrap"><view class="border rounded font mx-2 my-1 px-2 " v-for="(item,index) in list" :key="index"hover-class="bg-light" @click="historyEvent(item)">{{item}}</view></view>historyEvent(item){console.log(item);this.searchText=item;this.searchEvent();}
    

发布表单页面开发

自定义导航栏开发

  • 新建发布页面add-input,取消原生导航

    {"path" : "pages/add-input/add-input","style" :                                                                                    {"app-plus": {"titleNView": false}}}
    
  • 首页导航按钮跳转页面

    onNavigationBarButtonTap() {uni.navigateTo({url:'../add-input/add-input'})},
    
  • 自定义导航栏,添加uni-nav-bar依赖, 根据官方文档调用

    <uni-nav-bar left-icon="back" statusBar><view class="flex justify-center align-center w-100">所有人可见<text class="iconfont icon-shezhi ml-1"></text></view></uni-nav-bar>
    

textarea组件使用

  • utextarea, 动态绑定

    <textarea v-model="content" placeholder="说一句话吧~" class="px-2 uni-textarea" />
    

底部操作条组件开发

<view style="height: 85rpx" class="fixed-bottom bg-white flex align-center"><view class="iconfont icon-caidan footer-btn"></view><view class="iconfont icon-huati footer-btn"></view><view class="iconfont icon-tupian footer-btn"></view><view class="bg-main text-white justify-center align-center ml-auto flex mr-2" style="width: 140rpx; height: 60rpx;">发送</view></view><style>
.footer-btn{width: 86rpx;height: 86rpx;justify-content: center;display: flex;align-items: center;font-size: 50rpx;
}
</style>

上传多图功能开发

  • upload-image组件开发, 引官方组件,对应引入也需要引入

  • 对官方组件的修改 添加mode压缩,修改内边距, 修改圆角

    <view class="px-2"><view class="uni-uploader"><view class="uni-uploader-head"><view class="uni-uploader-title">点击可预览选好的图片</view><view class="uni-uploader-info">{{imageList.length}}/9</view></view><view class="uni-uploader-body"><view class="uni-uploader__files"><block v-for="(image,index) in imageList" :key="index"><view class="uni-uploader__file"><image class="uni-uploader__img rounded" :src="data:image" :data-src="data:image"@tap="previewImage" mode="aspectFill"></image></view></block><view class="uni-uploader__input-box"><view class="uni-uploader__input rounded" @tap="chooseImage"></view></view></view></view></view></view>
    
  • 上传图片成功的内容保存 上传图片的回调success方法中

    success: (res) => {this.imageList = this.imageList.concat(res.tempFilePaths);this.$emit('choose',this.imageList);},<uploadImage @choose="choose"></uploadImage>choose(e){console.log(e);this.imageList=e;}
    

删除选中图片功能实现

  • 静态图标的实现

    <block v-for="(image,index) in imageList" :key="index"><view class="uni-uploader__file position-relative"><image class="uni-uploader__img rounded" :src="data:image" :data-src="data:image"@tap="previewImage" mode="aspectFill"></image><view class="bg-dark position-absolute top-0 right-0 rounded"style="padding: 0 15rpx; background-color: rgba(0, 0, 0, 0.5);"><text class="iconfont icon-shanchu text-white"></text></view></view></block>
    
  • 添加删除功能的函数, 通知父组件, 优化父组件方法, 给予交互反馈提示

    <text class="iconfont icon-shanchu text-white"  @click="deleteImage(index)"></text>deleteImage(index){uni.showModal({title:'提示',content:'是否要删除该图片',confirmText:'删除',cancelText:'不删除',success: (res) => {if(res.confirm){this.imageList.splice(index,1);this.$emit('change',this.imageList);}}})},
    

保存草稿功能开发

  • 添加返回首页方法

    <uni-nav-bar left-icon="back" statusBar @clickLeft="goBack"><view class="flex justify-center align-center w-100 font-weight-bold">所有人可见<text class="iconfont icon-shezhi ml-1"></text></view></uni-nav-bar>goBack(){uni.navigateBack({delta:1})},
    
  • 监听返回, 交互提示反馈 return true即能返回

    onBackPress() {if((this.content!==''||this.imageList.length>0)&&!this.showBack){uni.showModal({content: '是否保存为草稿',showCancel: true,cancelText: '不保存',confirmText: '保存',success: res => {if(res.confirm){console.log('保存');}//手动执行返回// goBack(){//  uni.navigateBack({//        delta:1//   })// },this.goBack();}});this.showBack=true;return true;}},
    
  • 保存的方法

    store(){let obj={content:this.content,imageList:this.imageList};uni.setStorage({key:'add-input',data:JSON.stringify(obj)})}
    
  • 取出的方法 用同步取出

    onLoad() {var res=uni.getStorageSync('add-input');if(res){var obj=JSON.parse(res);// console.log(result);this.content=obj.content;this.imageList=obj.imageList;}},
    
  • 优化图片的草稿功能, 上传图片的组件imageList要用props传值

    <uploadImage :list="imageList" @change="change"></uploadImage>//组件里面props: {list: Array},created(){this.imageList=this.list;},
    
  • 不保存草稿功能的实现, 清楚缓存

    onBackPress() {if((this.content!==''||this.imageList.length>0)&&!this.showBack){uni.showModal({content: '是否保存为草稿',showCancel: true,cancelText: '不保存',confirmText: '保存',success: res => {if(res.confirm){// console.log('保存');this.store();}else{uni.removeStorageSync('add-input');}//手动执行返回this.goBack();}});this.showBack=true;return true;}},
    
  • 下面图标插入图片的方法(优化不需要上传图片时隐藏上传图片组件)

    <view class="iconfont icon-tupian footer-btn" @click="iconClickEvent('uploadImage')"></view><uploadImage ref="uploadImage" :show="show"  :list="imageList" @change="change"></uploadImage>iconClickEvent(e){switch (e){case 'uploadImage': this.$refs.uploadImage.chooseImage();break;}}computed:{show(){return this.imageList.length>0;}},在子组件中加入v-if=“show”

动态列表页开发

导航栏tab导航开发

  • 自定义导航栏的静态开发

    <uni-nav-bar statusBar="true" border="false" ><view class="flex align-center justify-center font-weight-bold  w-100"><view class="font-lg text-main mx-1">关注</view><view class="font-md text-light-muted mx-1">话题</view></view><view slot="right" class="iconfont icon-fatie_icon"></view></uni-nav-bar>
    
  • 取消原生导航栏

    {"path": "pages/news/news","style": {"app-plus": {"titleNView": false}}},
    
  • 导航栏右边图标的单击事件

    <uni-nav-bar statusBar="true" border="false" @clickRight="openAddInput"><view class="flex align-center justify-center font-weight-bold  w-100"><view class="font-lg text-main mx-1">关注</view><view class="font-md text-light-muted mx-1">话题</view></view><view slot="right" class="iconfont icon-fatie_icon"></view></uni-nav-bar>openAddInput(){uni.navigateTo({url: '../add-input/add-input'})}
    
  • tabBar的动态循环渲染

    <uni-nav-bar statusBar="true" border="false" @clickRight="openAddInput"><view class="flex align-center justify-center font-weight-bold  w-100 font-md text-light-muted"><view v-for="(item,index) in tabBars" :key="index":class="tabIndex===index? 'text-main font-lg':''"@click="changeTab(index)" class="mx-1">{{item.name}}</view></view><view slot="right" class="iconfont icon-fatie_icon"></view></uni-nav-bar>data() {return {tabIndex:0,tabBars:[{name:'关注'},{name:'话题'}]}},changeTab(index){this.tabIndex=index;}
    

关注列表页开发

滑动滚动区域计算

  • 引入首页的swipper和scrollview组件, 对应修改即可

    <swiper duration=150 @change="onChange" :current="tabIndex" :style="'height:'+scrollH+'px'"><swiper-item><scroll-view scroll-y="true" :style="'height:'+scrollH+'px'"></scroll-view></swiper-item></swiper>
    
  • 计算区域高度

    onLoad() {const res = uni.getSystemInfoSync();this.scrollH=res.screenHeight-res.statusBarHeight-44;console.log(this.scrollH);},
    

导航列表联动实现

  • 有两个swipperitem 表示关注和话题

    <swiper duration=150 @change="onChange" :current="tabIndex" :style="'height:'+scrollH+'px'"><swiper-item><scroll-view scroll-y="true" :style="'height:'+scrollH+'px'"><view v-for=" (item,index) in 100" :key="index">{{item}}</view></scroll-view></swiper-item><swiper-item><view>话题</view></swiper-item></swiper>
    
  • 引入common-list组件

  • 分割线的使用

    <swiper-item><scroll-view scroll-y="true" :style="'height:'+scrollH+'px'"><block  v-for="(item,index) in list" :key="index" ><commonList :item="item" :index="index"></commonList><divider></divider></block></scroll-view></swiper-item><swiper-item><view>话题</view></swiper-item>
    
  • 导航与列表的联动实现

    <swiper duration=150 @change="onChangeTab" :current="tabIndex" :style="'height:'+scrollH+'px'"><swiper-item><scroll-view scroll-y="true" :style="'height:'+scrollH+'px'"><block  v-for="(item,index) in list" :key="index" ><commonList :item="item" :index="index"></commonList><divider></divider></block></scroll-view></swiper-item><swiper-item><view>话题</view></swiper-item></swiper>onChangeTab(e){// console.log(e.detail);this.tabIndex=e.detail.current;}
    

顶踩操作和下拉加载功能 copy首页即可

  • 移植顶踩操作
  • 下拉加载的开发

关注列表页开发

热门分类组件开发

  • 静态页面开发

    <swiper-item><view class="flex justify-between align-center px-2"><text class="font-md">热门分类</text><view class="flex align-center font text-secondary">更多<text class="iconfont icon-jinru"></text></view></view><view class="flex align-center border-bottom px-2 py-3"><view class="rounded border bg-light mx-1 px-2">关注</view><view class="rounded border bg-light mx-1 px-2">关注</view><view class="rounded border bg-light mx-1 px-2">关注</view><view class="rounded border bg-light mx-1 px-2">关注</view></view></swiper-item>
    
  • 添加点击动画效果

    <view class="rounded border bg-light mx-1 px-2 animated" hover-class="jello">关注</view>
    

封装热门分类组件

  • 热门分类对象数组构建

    hotCate:[{name:'关注'},{name:'推荐'},{name:'体育'},{name:'军事'}]
    
  • 封装组件, 导入组件,遍历输出, 父子传值

  • 留两个接口

    <hotCate :hotCate="hotCate"></hotCate><template><view><view class="flex justify-between align-center px-2"><text class="font-md">热门分类</text><view class="flex align-center font text-secondary animated" hover-class="jello" @click="openMore">更多<text class="iconfont icon-jinru"></text></view></view><view class="flex align-center border-bottom px-2 py-3"><view class="rounded border bg-light mx-1 px-2 animated" hover-class="jello"v-for="(item,index) in hotCate" :key="index" @click="openDetail">{{item.name}}</view></view></view>
    </template><script>export default{props:['hotCate'],methods:{openMore(){console.log("点击更多");},openDetail(){console.log("点击进入详情页");}}}
    </script><style>
    </style>

轮播图和搜索框的开发

  • 静态页面开发

    <view class="p-2"><view class="flex align-center justify-center py-2 rounded bg-light text-secondary"><text class="iconfont icon-sousuo mr-2"></text>搜索话题</view></view><swiper :indicator-dots="true" :autoplay="true" :interval="3000" :duration="1000" class="px-2 pb-2"><swiper-item><image src="/static/demo/banner3.jpg" class="w-100 rounded" style="height: 300rpx;"></image></swiper-item></swiper><divider></divider>
    

话题列表组件开发

  • 静态页面开发

    <view class="p-2 font-md"> 最近更新</view><view class="flex align-center p-2"><image src="../../static/demo/topicpic/1.jpeg" style="width: 150rpx; height: 150rpx;"class="rounded mr-2"></image><view class="flex flex-column "><text class="font-md text-dark">话题哈哈哈</text><text class="font text-secondary">话题描述</text><view class="flex align-center font text-secondary"><text class="mr-2">今日:0</text><text>关注:0</text></view></view></view>
    

封装话题列表组件

  • 声明topicList

    topicList: [{cover: '/static/demo/topicpic/1.jpeg',title: '话题标题',desc: '话题描述',news_count: '10',today_count: '10'},{cover: '/static/demo/topicpic/1.jpeg',title: '话题标题',desc: '话题描述',news_count: '10',today_count: '10'},{cover: '/static/demo/topicpic/1.jpeg',title: '话题标题',desc: '话题描述',news_count: '10',today_count: '10'},{cover: '/static/demo/topicpic/1.jpeg',title: '话题标题',desc: '话题描述',news_count: '10',today_count: '10'}]
    
  • 封装组件,引入组件

    <block v-for="(item,index) in topicList" :key="index"><topicList :item="item" :index="index"></topicList></block><view class="flex align-center p-2"><image :src="item.cover" style="width: 150rpx; height: 150rpx;"class="rounded mr-2"></image><view class="flex flex-column "><text class="font-md text-dark">{{item.title}}</text><text class="font text-secondary">{{item.desc}}</text><view class="flex align-center font text-secondary"><text class="mr-2">动态:{{item.news_count}}</text><text>今日:{{item.today_count}}</text></view></view></view>
    

话题分类页开发

  • 新建页面

    {"path" : "pages/topic-nav/topic-nav","style" :                                                                                    {"navigationBarTitleText": "话题分类"}}
  • 导航进入

    openMore(){uni.navigateTo({url:'../topic-nav/topic-nav'})},
    
  • 引入首页,修改topic—nav页面,修改common-list组件, 修改数据

    <template><view><scroll-view class="scroll-row border-bottom border-light-secondary" scroll-x="true":scroll-into-view="scrollInto" scroll-with-animation="true" style="height: 100rpx;"><view v-for="(item,index) in tabBars" :key="index" class="scroll-row-item px-3 py-2 font-md ":id="'tab'+index" :class="tabIndex===index?'text-main font-lg font-weight-bold':''"@click="doTab(index)">{{item.name}}</view></scroll-view><swiper duration=150 @change="onChange" :current="tabIndex" :style="'height:'+scrollH+'px'"><swiper-item v-for="(item,index) in newList" :key="index"><template v-if="item.list.length>0"><scroll-view scroll-y="true" :style="'height:'+scrollH+'px'" @scrolltolower="loadMore(index)"><block v-for="(item2,index2) in item.list" :key="index"><!-- <commonList :item="item2" :index="index2" @follow="follow()" @doSupport="doSupport()"></commonList> --><topicList :item="item2" :index="index2"></topicList></block><loadMore :loading="item.loading"></loadMore></scroll-view></template><template v-else><no-thing></no-thing></template></swiper-item></swiper></view>
    </template><script>import topicList from '@/components/news/topic-list';import loadMore from '@/components/common/load-more';const demo = [{cover: '/static/demo/topicpic/1.jpeg',title: '话题标题',desc: '话题描述',news_count: '10',today_count: '10'},{cover: '/static/demo/topicpic/1.jpeg',title: '话题标题',desc: '话题描述',news_count: '10',today_count: '10'},{cover: '/static/demo/topicpic/1.jpeg',title: '话题标题',desc: '话题描述',news_count: '10',today_count: '10'},{cover: '/static/demo/topicpic/1.jpeg',title: '话题标题',desc: '话题描述',news_count: '10',today_count: '10'},{cover: '/static/demo/topicpic/1.jpeg',title: '话题标题',desc: '话题描述',news_count: '10',today_count: '10'},{cover: '/static/demo/topicpic/1.jpeg',title: '话题标题',desc: '话题描述',news_count: '10',today_count: '10'},{cover: '/static/demo/topicpic/1.jpeg',title: '话题标题',desc: '话题描述',news_count: '10',today_count: '10'},{cover: '/static/demo/topicpic/1.jpeg',title: '话题标题',desc: '话题描述',news_count: '10',today_count: '10'}];export default {components: {topicList,loadMore},data() {return {scrollH: 200,tabIndex: 0,scrollInto: '',newList: [],tabBars: [{name: '首页'},{name: '体育'},{name: '军事'},{name: '热点'},{name: '新闻'},{name: '娱乐'},{name: '电竞'},{name: '国际'},{name: '国家'}]}},onNavigationBarSearchInputClicked() {uni.navigateTo({url: '../search/search'})},onLoad() {const res = uni.getSystemInfoSync();this.scrollH = res.windowHeight - uni.upx2px(101);this.getData();},onNavigationBarButtonTap() {uni.navigateTo({url:'../add-input/add-input'})},methods: {getData() {let arr = [];for (var i = 0; i < this.tabBars.length; i++) {let obj = {loading: '上拉加载更多',list: []}if (i < 2) {obj.list = demo;}arr.push(obj)};this.newList = arr;},follow(index) {this.list[index].isFollow = true;uni.showToast({title: '关注成功'})},doSupport(e) {let obj = this.list[e.index];if (obj.support.type === '') {//无操作obj.support[e.type + '_count']++;} else if (obj.support.type === 'support' && e.type === 'unsupport') {//之前是顶,顶减一,踩加一obj.support.support_count--;obj.support.unsupport_count++;} else if (obj.support.type === 'unsupport' && e.type === 'support') {//之前是踩,顶加一,踩减一obj.support.support_count++;obj.support.unsupport_count--;}obj.support.type = e.type;let msg = e.type === 'support' ? '顶' : '踩';uni.showToast({title: msg + '成功'})},doTab(index) {this.tabIndex = index;this.scrollInto = 'tab' + index;},onChange(e) {this.doTab(e.detail.current);},loadMore(index) {let item = this.newList[index];if ((item.loading) !== '上拉加载更多') {return;}item.loading = '加载中...';setTimeout(() => {item.list = [...item.list, ...item.list];item.loading = '上拉加载更多';}, 2000)}}}
    </script><style></style>

话题详情页开发

page.json配置

  • 新建topic-detail页面

  • 配置导航栏, 渐变式透明, 图标

    {"path" : "pages/topic-detail/topic-detail","style" :                                                                                    {"navigationBarTitleText": "","app-plus": {"titleNView": {"type": "transparent","buttons": [{"type": "menu"}]}}} }
    
  • 导航到话题详情页, 传递json字符串对象, 接受数据转换object

    <view class="flex align-center p-2" @click="openDetail(item)">openDetail(item){uni.navigateTo({url:'../topic-detail/topic-detail?detail='+JSON.stringify(item)})}onLoad(e){if(e.detail){var obj=JSON.parse(e.detail);// console.log(obj);}},
    

话题介绍组件开发

  • 图片模糊状态

  • 静态开发

    <view><view class="position-relative"><image src="/static/demo/topicpic/1.jpeg" mode="aspectFill"style="height: 300rpx;" class="w-100 filter"></image></view><view class=" px-2 bg-white position-relative" style="z-index: 10;"><view class="flex align-center"><image src="/static/demo/topicpic/1.jpeg" class="w-100" style="height: 150rpx; width: 150rpx;margin-top: -75rpx;"></image><text class="font-md">#话题标题#</text></view><view class="flex align-center font text-secondary mt-2"><text class="mr-1">动态:0</text><text>今日:0</text></view><view class="font text-secondary">话题描述</view></view></view><style>
    .filter{filter: blur(10px);
    }
    </style>
    

封装话题介绍组件

  • 新建topic-info组件

  • 动态替换, 数据渲染

    <template><view><view class="position-relative"><image :src="info.cover" mode="aspectFill" style="height: 300rpx;" class="w-100 filter"></image></view><view class=" px-2 bg-white position-relative pb-1" style="z-index: 10;"><view class="flex align-center"><image :src="info.cover" class="w-100" style="height: 150rpx; width: 150rpx;margin-top: -75rpx;"></image><text class="font-md">{{info.title}}</text></view><view class="flex align-center font text-secondary mt-2"><text class="mr-1">动态:{{info.news_count}}</text><text>今日:{{info.today_count}}</text></view><view class="font text-secondary">{{info.desc}}</view></view></view>
    </template><script>export default {props:['info']}
    </script><style>
    </style><topicInfo :info="info"></topicInfo><divider></divider>
    

精华帖子列表组件开发

<view class="flex p-2 border-bottom"><text class="iconfont icon-xihuan text-main"></text><text class="font text-darker text-ellipsis"> 【新人必读】uni-app实战项目第四季社区交友开发</text></view><view class="flex p-2 border-bottom"><text class="iconfont icon-xihuan text-main"></text><text class="font text-darker text-ellipsis"> 【新人必读】uni-app实战项目第四季社区交友开发</text></view>

tab选项卡组件开发

  • 优化精华帖子列表开发, 用循环

    <block v-for="(item,index) in hotList" :key="index"><view class="flex p-2 border-bottom"><text class="iconfont icon-xihuan text-main"></text><text class="font text-darker text-ellipsis">{{item.title}}</text></view></block>hotList: [{title: '【新人必读】uni-app实战项目第四季社区交友开发'},{title: '【新人必读】Hillky社区规范'}]
    
  • tab选项开发

    <view class="flex align-center py-2"><text class="flex-1 flex align-center justify-center font-weight-bold font-lg text-main">默认</text><text class="flex-1 flex align-center justify-center font-weight-bold font-md text-dark">最新</text></view>
    
  • 列表开发, 引入公共列表, 声明两个数组list1,2

    <block v-for="(item,index) in list1" :key="index"><commonList :item="item" :index="index"></commonList></block>
    
  • tab切换实现

    <view class="flex align-center py-2" ><text class="flex-1 flex align-center justify-center"v-for="(item,index) in tabBar" :key="index":class="tabIndex===index?'font-lg text-main font-weight-bold':'font-md text-dark'"@click="changeTab(index)">{{item.name}}</text></view>tabIndex: 0,tabBar:[{name:'默认'},{name:'最新'}]
    

利用计算属性实现列表切换

  • 用计算属性切换数组

    computed: {listData() {if (this.tabIndex === 0) {return this.list1;}if (this.tabIndex === 1) {return this.list2;}}},
    
  • 遍历列表要分割线

  • 判断数组长度, 用nothing组件

    <template v-if="listData.length>0"><block v-for="(item,index) in listData" :key="index"><commonList :item="item" :index="index"></commonList><divider></divider></block></template><template v-else><no-thing></no-thing></template>
    

话题详情上拉加载实现

  • 触底事件

    onReachBottom() {this.loadMore();},
    
  • 引入上拉加载组件

     import loadMore from '@/components/common/load-more';<loadMore :loading="loadText"></loadMore>
    
  • loadText计算属性区分是哪个列表的上拉加载

    loadText1:'上拉加载更多',
    loadText2:'上拉加载更多'loadText(){if(this.tabIndex===0){return this.loadText1}else{return this.loadText2}}
    
  • 上拉加载更多事件

    loadMore(){let index =this.tabIndexif(this['loadText'+(index+1)]!=='上拉加载更多'){return;}this['loadText'+(index+1)]='加载中...'setTimeout(()=>{this['loadText'+(index+1)]='上拉加载更多';this['list'+(index+1)]=[...this['list'+(index+1)],...this['list'+(index+1)]];},2000)}
    

消息列表页面开发

page.json配置

  • 配置顶部导航栏, 配置左右图标

     {"path": "pages/msg/msg","style": {"navigationBarTitleText": "消息列表","app-plus": {"titleNView": {"buttons": [{"color": "#333333","colorPressed": "#FD597C","float": "left","fontSize": "20px","fontSrc": "/static/iconfont.ttf","text": "\ue611"},{"color": "#333333","colorPressed": "#FD597C","float": "right","fontSize": "20px","fontSrc": "/static/iconfont.ttf","text": "\ue649"}]}}}

消息列表组件开发

  • 静态开发

  • 引入数字脚标组件

    <view><view class="flex align-center justify-center p-2 border-bottom border-light-secondary"><image src="../../static/default.jpg" style="height: 80rpx; width: 80rpx;" class="rounded-circle mr-2"></image><view class="flex-column flex flex-1"><view class="flex align-center justify-between"><text class="font-md text-dark">昵称</text><text class="font-sm text-secondary">17:00</text></view><view class="py-1 flex align-center justify-between"><view class=" font-sm text-secondary">内容</view><uni-badge text="1" type="error"></uni-badge></view></view></view></view>
    

封装消息列表组件

  • 优化内容, 添加对应css和最大宽度

    <view class="pt-1 flex align-center justify-between"><view class=" font-sm text-secondary text-ellipsis" style="max-width: 500rpx;">内容内容内容内容内容内容内容内容内容内容内容内容内容</view><uni-badge text="1" type="error"></uni-badge></view>
    
  • 封装数据,封装组件, 时间使用在线时间戳

  • 引入time.js, 使用对应库,使用过滤器

    import $T from '@/common/time.js'filters:{formatTime(value){return $T.gettime(value);}},
    
  • 组件分离

    <block v-for="(item,index) in list" :key="index"><msgList :item="item" :index="index"></msgList></block><template><view class="flex align-center justify-center p-2 border-bottom border-light-secondary"><image :src="item.avatar" style="height: 80rpx; width: 80rpx;" class="rounded-circle mr-2"></image><view class="flex-column flex flex-1"><view class="flex align-center justify-between"><text class="font-md text-dark">{{item.username}}</text><text class="font-sm text-secondary">{{item.update_time | formatTime}}</text></view><view class="pt-1 flex align-center justify-between"><view class=" font-sm text-secondary text-ellipsis" style="max-width: 500rpx;">{{item.data}}</view><uni-badge :text="item.noread" type="error"></uni-badge></view></view></view>
    </template><script>import $T from '@/common/time.js'export default {props:{item:Object,index:Number},filters: {formatTime(value){// console.log(value);return $T.gettime(value);}}}
    </script><style>
    </style>

下拉刷新功能实现

  • page.json配置

    "enablePullDownRefresh": true,
    
  • 监听下拉刷新, 写入方法

    onPullDownRefresh() {this.refresh();},refresh(){setTimeout(()=>{this.list=demo;uni.stopPullDownRefresh();},2000);}
    
  • 引入nothing组件, v-if判断

    <template><view><template v-if="this.list.length>0"><block v-for="(item,index) in list" :key="index"><msgList :item="item" :index="index"></msgList></block></template><template v-else><no-thing></no-thing></template></view>
    </template><script>const demo=[{avatar:'../../static/default.jpg',username:'昵称',update_time:1648458088,data:'内容内容内容内容内容内容内容内容内容内容内容内容内容',noread:20},{avatar:'../../static/default.jpg',username:'昵称',update_time:1648458088,data:'内容内容内容内容内容内容内容内容内容内容内容内容内容',noread:20},{avatar:'../../static/default.jpg',username:'昵称',update_time:1648458088,data:'内容内容内容内容内容内容内容内容内容内容内容内容内容',noread:20},{avatar:'../../static/default.jpg',username:'昵称',update_time:1648458088,data:'内容内容内容内容内容内容内容内容内容内容内容内容内容',noread:20}];import msgList from '@/components/msg/msg-list';export default {components:{msgList},data() {return {list:[]}},onLoad() {this.list=demo;console.log(this.list);},onPullDownRefresh() {this.refresh();},methods: {refresh(){setTimeout(()=>{this.list=[...this.list,...this.list];uni.stopPullDownRefresh();},2000);}}}
    </script><style></style>

下拉弹出层组件使用

  • 使用uni-poup组件,

  • 监听原生导航栏按钮事件,弹出弹出层

    <uni-popup ref="popup" type="top" background-color="#fff">123</uni-popup>onNavigationBarButtonTap(e) {switch (e.index){case 0:break;case 1:this.$refs.popup.open();break;}},
    

下拉弹出选项完善

  • 静态开发

  • 添加点击事件

    <uni-popup ref="popup" type="top" background-color="#fff"><view class="flex justify-center align-center font-md border-bottom py-2" hover-class="bg-light"@click="popupEvent('findFriend')"><text class="iconfont icon-sousuo mr-2" ></text>搜索好友</view><view class="flex justify-center align-center font-md py-2" hover-class="bg-light"@click="popupEvent('deleteList')"><text class="iconfont icon-shanchu mr-2"></text>删除列表</view></uni-popup>popupEvent(event){switch (event){case 'findFriend':{console.log('findFriend');this.$refs.popup.close();break;}case 'deleteList':{console.log('deleteList');this.$refs.popup.close();break;}}}

我的好友列表页开发

page.json配置

  • 新建user-list, 导航进入该页面

    onNavigationBarButtonTap(e) {switch (e.index){case 0:uni.navigateTo({url:'../user-list/user-list'})break;case 1:this.$refs.popup.open();break;}},
    
  • 配置page.json

    {"path": "pages/user-list/user-list","style": {"navigationBarTitleText": "","app-plus": {"animationType": "slide-in-left","titleNView": {"autoBackButton": true,"searchInput": {"align": "center","backgroundColor": "#F5F4F2","borderRadius": "4px","disabled": true,"placeholder": "搜索用户","placeholderColor": "#6D6C67"},"buttons": [{"color": "#333333","colorPressed": "#FD597C","float": "right","fontSize": "14px","text": "取消"}]}}}
    
  • 监听点击输入框事件, 监听取消按钮事件

    onNavigationBarSearchInputClicked() {// console.log('跳转');uni.navigateTo({url:'../search/search'})},onNavigationBarButtonTap() {uni.navigateBack({delta: 1})},
    

tab导航组件再次优化

  • 引入tabBar导航

  • 条件渲染数字

    <view class="flex align-center py-2"><text class="flex-1 flex align-center justify-center" v-for="(item,index) in tabBar" :key="index":class="tabIndex===index?'font-lg text-main font-weight-bold':'font-md text-dark'"@click="changeTab(index)">{{item.name}} <text v-if="item.num>0" class="ml-1">{{item.num}}</text> </text></view>

好友列表组件开发

  • 引入首页的scrollview, 下拉, 对应修改和引入

  • 列表样式静态开发

    <swiper duration=150 @change="onChange" :current="tabIndex" :style="'height:'+scrollH+'px'"><swiper-item v-for="(item,index) in newList" :key="index"><template v-if="item.list.length>0"><scroll-view scroll-y="true" :style="'height:'+scrollH+'px'" @scrolltolower="loadMore(index)"><block v-for="(item2,index2) in item.list" :key="index2"><view class="flex align-center p-2 border-bottom border-light-secondary"><image src="../../static/default.jpg" class="rounded-circle mr-2" style="width: 100rpx; height: 100rpx;"></image><view class="flex flex-column flex-1"><text class="font-md text-dark">昵称</text><text class="font-sm mt-1">性别</text></view><view class="uni-icon uni-icon-checkbox-filled text-light-muted "></view></view></block><loadMore :loading="item.loading"></loadMore></scroll-view></template><template v-else><no-thing></no-thing></template></swiper-item></swiper>getData() {let arr = [];for (var i = 0; i < this.tabBars.length; i++) {let obj = {loading: '上拉加载更多',list: []}if (i < 2) {obj.list = [1,2,3,4];}arr.push(obj)};this.newList = arr;},changeTab(index){this.tabIndex=index;},onChange(e){this.changeTab(e.detail.current);},loadMore(index) {let item = this.newList[index];if ((item.loading) !== '上拉加载更多') {return;}item.loading = '加载中...';setTimeout(() => {item.list = [...item.list, ...item.list];item.loading = '上拉加载更多';}, 2000)}
    

强化badge组件开发

  • 使用uni-badge, 插入图标, 优化性别显示

    <view><text class="iconfont icon-nv text-secondary"style="font-size: 18rpx;"></text><uni-badge type="error" text="24"></uni-badge></view>
    

封装好友列表组件

  • 测试demo数据

    const demo=[{avatar:'../../static/default.jpg',username:'昵称',sex:1,age:24,isFollow:false},{avatar:'../../static/default.jpg',username:'昵称',sex:2,age:24,isFollow:true}];
    
  • 数据渲染,动态绑定性别class, 点击灰色

  • 封装组件, 引入组件

    <template><view><view class="flex align-center p-2 border-bottom border-light-secondary " hover-class="bg-light"><image :src="item.avatar" class="rounded-circle mr-2" style="width: 100rpx; height: 100rpx;"></image><view class="flex flex-column flex-1"><text class="font-md text-dark">{{item.username}}</text><view v-if="item.sex>0"><text class="iconfont text-secondary" :class="item.sex===1?'icon-nv':'icon-nan'"   style="font-size: 18rpx;"></text><uni-badge :type="item.sex===1?'error':'primary'" :text="item.age"></uni-badge></view></view><view class="uni-icon uni-icon-checkbox-filled  " :class="item.isFollow?'text-light-muted':'text-main'"></view></view></view>
    </template><script>export default {name:"user-list",props:{item:Object,index:Number},data() {return {};}}
    </script><style></style>import userList from '@/components/user-list/user-list.vue';<userList :item="item2" :index="index2"></userList>
    

优化我的好友列表页面

  • 优化scrollH问题,引入首页方法

    onLoad() {this.getData();const res = uni.getSystemInfoSync();this.scrollH = res.windowHeight - uni.upx2px(101);// console.log(this.scrollH);},
    
  • 隐藏上拉加载组件

     <loadMore :loading="item.loading" v-if="item.list.length>10"></loadMore>
    

聊天界面开发

page.json配置

  • 新建页面user-chat, 导航进入

  • 配置导航栏

    {"path" : "pages/user-chat/user-chat","style" :{"app-plus": {"titleNView": {"buttons": [{"color": "#333333","colorPressed": "#FD597C","float": "right","fontSize": "20px","fontSrc": "/static/iconfont.ttf","text": "\ue628"}]}}}

聊天输入框组件开发

  • 底部操作条开发

    <view class="flex fixed-bottom align-center bg-white border-top" style="height: 100rpx;"><view class="flex-1"><input type="text" placeholder="请文明发言" class="rounded ml-2 bg-light p-1" /></view><view class="iconfont icon-fabu flex align-center justify-center font-lg animated" style="width: 100rpx;"hover-class="jello text-main"></view></view>
    

聊天列表组件开发

  • scrollH获取

    <scroll-view :style="'height: '+this.scrollH+'px;'" scroll-y="true"><view v-for="i in 100" :key="i">{{i}}</view></scroll-view>onLoad() {const res = uni.getSystemInfoSync();this.scrollH = res.windowHeight - uni.upx2px(101);},
    
  • 聊天列表组件开发

  • 右边气泡的开发

            <scroll-view :style="'height: '+this.scrollH+'px;'" scroll-y="true"><view class="flex align-start px-2 my-2"><image src="../../static/default.jpg" class="rounded-circle"style="height: 100rpx; width: 100rpx;"></image><view class="bg-light mx-2 p-2 rounded mt-1" style="max-width: 400rpx;  min-width: 100rpx;">你好啊</view></view><view class="flex align-start px-2 my-2" style="flex-direction: row-reverse;"><image src="../../static/default.jpg" class="rounded-circle"style="height: 100rpx; width: 100rpx;"></image><view class="bg-light mx-2 p-2 rounded mt-1" style="max-width: 400rpx; min-width: 100rpx;">你好啊</view></view></scroll-view>
    

封装聊天列表组件完善时间显示

  • 新建user-chat-list, 封装数据

  • 计算属性, 是否本人

    isShelf(){return this.item.userId===1},
    
  • 时间显示开发

    <view class="my-2 flex align-center justify-center text-secondary font-sm">{{shortTime}}</view>
    
  • 引入time.js, 优化时间显示, 用计算属性

    shortTime(){return $T.getChatTime(this.item.create_time,this.preTime);}<userChatList :item="item" :index="index" :preTime=" index>0 ? list[index-1].create_time : 0"></userChatList>
    

完善聊天页功能

  • 输入框绑定内容, 绑定发送事件, 发送功能实现

    sendMessage(){let obj={userId:1,avatar: '../../static/default.jpg',data: this.content,type: 'text',create_time: (new Date()).getTime()};if(obj.data===''){uni.showToast({title:"请输入内容"});return;}this.list.push(obj);this.content=''}
    
  • 优化功能, 最小宽度去掉, 键盘推页面false, 清空输入框, 丢弃scrollH

    <input type="text" placeholder="请文明发言" class="rounded ml-2 bg-light p-1" v-model="content" adjust-position="false" /><scroll-view style="position: absolute; left: 0 ; top: 0; right: 0; bottom: 100rpx;" scroll-y="true">
    
  • 滚动到底部实现

    <scroll-view style="position: absolute; left: 0 ; top: 0; right: 0; bottom: 100rpx;" scroll-y="true":scroll-into-view="scrollInto" scroll-with-animation><block v-for="(item,index) in list" :key="index"><userChatList :id="'chat'+index" :item="item" :index="index" :preTime=" index>0 ? list[index-1].create_time : 0"></userChatList></block></scroll-view>pageToBottom(){let lastIndex=this.list.length-1;if(lastIndex < 0){return}this.scrollInto='chat'+lastIndex;console.log(this.scrollInto);}onReady() {this.pageToBottom();},
    

搜索列表页开发

搜索列表功能完善

  • 添加搜索标识

    onNavigationBarSearchInputClicked() {uni.navigateTo({url: '../search/search?type=post'})},
    
  • 获取类型, 修改搜索占位, 添加如果说是app端

    if (e.type) {this.type = e.type;}let pageTitle='';switch (this.type) {case 'post':pageTitle='搜索帖子'break;case 'topic':pageTitle='搜索话题'break;case 'friend':pageTitle='搜索好友'break;}console.log(this.type);// #ifdef APP-PLUSlet currentWebview=this.$scope.$getAppWebview();let tn=currentWebview.getStyle().titleNView;tn.searchInput.placeholder=pageTitle;console.log(tn);currentWebview.setStyle({titleNView:tn})// #e
    
  • 搜索结果完善优化, 根据不同搜索,组件,数据都要不同

    searchEvent() {uni.hideKeyboard();uni.showLoading({title: '加载中'})setTimeout(() => {switch (this.type) {case 'post':this.serachList = demo1;break;case 'topic':this.serachList = demo2;break;case 'friend':this.serachList = demo3;break;}uni.hideLoading();}, 3000)},<block v-for="(item,index) in serachList" :key="index"><template v-if="type==='post'"><commonList :item="item" :index="index"></commonList></template><template v-if="type==='topic'"><topicList :item="item" :index="index"></topicList></template><template v-if="type==='friend'"><userList :item="item" :index="index"></userList></template></block>
    

文章详情页开发

page.json配置

  • 新建页面,detail, 导航入口

    ,{"path" : "pages/detail/detail","style" :                                                                                    {"app-plus": {"titleNView": {"buttons": [{"float": "right","type": "menu"}]}}}}
    
  • 把对象作为参数传过去,初始化

    openDetail(){console.log("打开详情页");uni.navigateTo({url:'../../pages/detail/detail?detail='+JSON.stringify(this.item)})},onLoad(e){if(e.detail){this.__init(JSON.parse(e.detail));}},methods: {__init(data){uni.setNavigationBarTitle({title:data.title})}}
    

强化公共列表组件功能

  • 修改公共列表组件, 添加isDetail, prop, 评论和分享功能

    props: {item: Object,index: {type: Number,default: -1},isDetail: {type: Boolean,default: false}},doComment(){if(!this.isDetail){return this.openDetail();}this.$emit('doComment');},doShare(){if(!this.isDetail){return this.openDetail();}this.$emit('doShare');}
    <commonList :item="this.item" :isDetail="true" @doComment="doComment" @doShare="doShare">帖子详请</commonList>

完善详情页关注顶踩功能

  • 关注事件, 修改index默认值

    follow() {this.info.isFollow = true;}index: {type: Number,default: -1}
    
  • 顶踩方法改写

    doSupport(e) {let obj = this.infoif (obj.support.type === e.type) {uni.showToast({title: '你已经操作过了'})return;}if (obj.support.type === '') {//无操作obj.support[e.type + '_count']++;} else if (obj.support.type === 'support' && e.type === 'unsupport') {//之前是顶,顶减一,踩加一obj.support.support_count--;obj.support.unsupport_count++;} else if (obj.support.type === 'unsupport' && e.type === 'support') {//之前是踩,顶加一,踩减一obj.support.support_count++;obj.support.unsupport_count--;}obj.support.type = e.type;let msg = e.type === 'support' ? '顶' : '踩';uni.showToast({title: msg + '成功'})}
    
  • 增加content,image

    content:"Hillky正在开发ing.....",images:[{url:"https://tupian.qqw21.com/article/UploadPic/2020-5/20205622141239876.jpg"},{url:"https://tse1-mm.cn.bing.net/th/id/R-C.df1d553893d9b7888c725b8dbcbcf439?rik=hpbIzO6xZ3Qchw&riu=http%3a%2f%2fwww.chabeichong.com%2fimages%2f2016%2f11%2f12-04122113.jpg&ehk=%2fe971CgX%2bMeAgZuGCVac3td74wDOd1%2bWzz0q4IsP1Lc%3d&risl=&pid=ImgRaw&r=0&sres=1&sresct=1"}]
    
  • 增加图片预览功能

    <image v-for="(item,index) in info.images" :src="item.url" class="w-100" mode="widthFix" @click="preview(index)"></image>preview(index){// console.log(this.imageList);uni.previewImage({urls:this.imageList,current:index})}computed:{imageList(){return this.info.images.map(item=>item.url);}},
    

评论输入框组件封装

  • 先对聊天室底部操作条的封装,测试是否成功

    <template><view class="flex fixed-bottom align-center bg-white border-top" style="height: 100rpx;"><view class="flex-1"><input type="text" placeholder="请文明发言" class="rounded ml-2 bg-light p-1" v-model="content"adjust-position="false" /></view><view class="iconfont icon-fabu flex align-center justify-center font-lg animated" style="width: 100rpx;"hover-class="jello text-main" @click="sendMessage"></view></view>
    </template><script>export default {data(){return{content:''}},methods:{sendMessage(){if (this.content === '') {uni.showToast({title: "请输入内容",icon:"none"});return;}this.$emit('submit',this.content);this.content = '';}}}
    </script><style>
    </style><bottomBtn @submit="submit"></bottomBtn>submit(content) {let obj = {userId: 1,avatar: '../../static/default.jpg',data: content,type: 'text',create_time: (new Date()).getTime()};this.list.push(obj);this.pageToBottom();},
    
  • 再到detail页面使用该组件,需要占位

列表评论组件开发

  • 使用官方评论界面,进行静态开发

    <view class="px-2"><!-- 评论区 start --><view class="uni-comment"><view class="uni-comment-list"><view class="uni-comment-face" style="margin-top: 15rpx;"><image src="https://img-cdn-qiniu.dcloud.net.cn/uniapp/images/uni@2x.png" mode="widthFix"></image></view><view class="uni-comment-body"><view class="uni-comment-top"><text>网友</text></view><view class="uni-comment-date"><text>08/10 08:12</text></view><view class="uni-comment-content">很酷的HBuilderX和uni-app,开发一次既能生成小程序,又能生成App</view></view></view></view></view>
    

分享功能组件开发

  • 弹出层,底部弹出, 监听导航栏按钮触发, 层级关系的修改-z-index

    <uni-popup ref="popup" type="bottom" background-color="#fff"><view style="height: 300rpx;">123</view></uni-popup>onNavigationBarButtonTap() {this.$refs.popup.open();},uni-popup {position: fixed;/* #ifndef APP-NVUE */z-index: 9999;
    
  • 监听返回事件,隐藏弹出层

    onBackPress() {this.$refs.popup.close();},
    
  • 静态开发

    <view class="font-md border-bottom border-light-secondary text-center py-2">分享到</view><view class="flex align-center "><view class="flex flex-1 flex-column justify-center align-center py-2"><view class="iconfont icon-QQ rounded-circle bg-primary text-white flex align-center justify-center font-lg" style="width: 100rpx; height: 100rpx;"></view><view class="font mt-1 text-light-muted">QQ好友</view></view>...</view><view class="font-md border-top border-light-secondary text-center py-2">取消</view>
    
  • 遍历图标

    <block v-for="(item,index) in btnList" :key="index"><view class="flex flex-1 flex-column justify-center align-center py-2"><viewclass="iconfont  rounded-circle bg-primary text-white flex align-center justify-center font-lg":class="item.icon+' '+item.color "style="width: 100rpx; height: 100rpx;"></view><view class="font mt-1 text-light-muted">{{item.name}}</view></view></block>
    
  • 封装组件 more-share.vue

    <template><view><uni-popup ref="popup" type="bottom" background-color="#fff"><view class="font-md border-bottom border-light-secondary text-center py-2">分享到</view><view class="flex align-center "><block v-for="(item,index) in btnList" :key="index"><view class="flex flex-1 flex-column justify-center align-center py-2"><viewclass="iconfont  rounded-circle bg-primary text-white flex align-center justify-center font-lg":class="item.icon+' '+item.color " style="width: 100rpx; height: 100rpx;"></view><view class="font mt-1 text-light-muted">{{item.name}}</view></view></block></view><view class="font-md border-top border-light-secondary text-center py-2">取消</view></uni-popup></view>
    </template><script>export default {data(){return{btnList: [{"icon": 'icon-QQ',"color": 'bg-primary',"name": 'QQ好友'},{"icon": 'icon-QQ',"color": 'bg-primary',"name": 'QQ好友'},{"icon": 'icon-QQ',"color": 'bg-primary',"name": 'QQ好友'},{"icon": 'icon-QQ',"color": 'bg-primary',"name": 'QQ好友'}],}},methods:{open(){this.$refs.popup.open();},close(){this.$refs.popup.close();}}}
    </script><style>
    </style>
     <moreShare ref="share"></moreShare>onNavigationBarButtonTap() {this.$refs.share.open();},onBackPress() {this.$refs.share.close();},
    
  • 用官方组件分享动态渲染数据, 子组件用created()

    created(){uni.getProvider({service: 'share',success: (e) => {console.log(e);let data = []for (let i = 0; i < e.provider.length; i++) {switch (e.provider[i]) {case 'weixin':data.push({name: '微信好友',id: 'weixin',icon:'icon-weixin',color:'bg-success',sort:0})data.push({name: '朋友圈',id: 'weixin',icon:'icon-huati',color:'bg-dark',type:'WXSenceTimeline',sort:1})break;case 'sinaweibo':data.push({name: '新浪微博',icon:'icon-xinlangweibo',color:'bg-danger',id: 'sinaweibo',sort:2})break;case 'qq':data.push({name: 'QQ好友',id: 'qq',icon:'icon-QQ',color:'bg-primary',sort:3})break;default:break;}}this.providerList = data.sort((x,y) => {return x.sort - y.sort});},fail: (e) => {console.log('获取分享通道失败', e);uni.showModal({content:'获取分享通道失败',showCancel:false})}});},
    
  • 分享方法

    async share(e) {console.log('分享通道:'+ e.id +'; 分享类型:' + this.shareType);if(!this.shareText && (this.shareType === 1 || this.shareType === 0)){uni.showModal({content:'分享内容不能为空',showCancel:false})return;}if(!this.image && (this.shareType === 2 || this.shareType === 0)){uni.showModal({content:'分享图片不能为空',showCancel:false})return;}let shareOPtions = {provider: e.id,scene: e.type && e.type === 'WXSenceTimeline' ? 'WXSenceTimeline' : 'WXSceneSession', //WXSceneSession”分享到聊天界面,“WXSenceTimeline”分享到朋友圈,“WXSceneFavorite”分享到微信收藏     type: this.shareType,success: (e) => {console.log('success', e);uni.showModal({content: '已分享',showCancel:false})},fail: (e) => {console.log('fail', e)uni.showModal({content: e.errMsg,showCancel:false})},complete:function(){console.log('分享操作结束!')}}switch (this.shareType){case 0:shareOPtions.summary = this.shareText;shareOPtions.imageUrl = this.image;shareOPtions.title = '欢迎体验uniapp';shareOPtions.href = 'https://uniapp.dcloud.io';break;case 1:shareOPtions.summary = this.shareText;break;case 2:shareOPtions.imageUrl = this.image;break;case 5:shareOPtions.imageUrl = this.image ? this.image : 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/b6304f00-5168-11eb-bd01-97bc1429a9ff.png'shareOPtions.title = '欢迎体验uniapp';shareOPtions.miniProgram = {id:'gh_33446d7f7a26',path:'/pages/tabBar/component/component',webUrl:'https://uniapp.dcloud.io',type:0};break;default:break;}if(shareOPtions.type === 0 && plus.os.name === 'iOS'){//如果是图文分享,且是ios平台,则压缩图片 shareOPtions.imageUrl = await this.compress();}if(shareOPtions.type === 1 && shareOPtions.provider === 'qq'){//如果是分享文字到qq,则必须加上href和titleshareOPtions.href = 'https://uniapp.dcloud.io';shareOPtions.title = '欢迎体验uniapp';}uni.share(shareOPtions);},
    

个人中心页面开发

page.json配置

  • 配置page.json

    {"path": "pages/my/my","style": {"navigationBarTitleText": "我的","app-plus": {"titleNView": {"buttons": [{"type": "menu"}]}}}},
    

个人中心ui构建

  • 静态开发第一个view

    <view class="flex align-center p-2"><image src="../../static/default.jpg" style="width: 100rpx; height: 100rpx;" class="rounded-circle"></image><view class="flex flex-column flex-1 px-2"><text class="font-lg font-weight-bold text-dark ">昵称</text><text class="font text-muted mt-1"> 总帖子10 今日发帖0</text></view><view class="iconfont icon-jinru"></view></view>
    
  • 第二个view开发,使用遍历方式

    <view class="flex align-center px-3 py-2"><view class="flex-1 flex-column flex align-center justify-center" v-for="(item,index) in this.itemList " :key="index"><text class="font-lg text-dark">{{item.num}}</text><text class="text-muted fony">{{item.name}}</text></view></view>
    
  • 第三个view, 广告位的开发

    <view class="px-3 py-2"><image src="/static/demo/banner1.jpg" style="height: 300rpx; width: 100%;" mode="aspectFill" class="rounded"></image></view>
    
  • 引入uni-list-item

    <uni-list-item title="浏览历史" :showExtraIcon="true" :extra-icon="extraIcon1" link :border="false"></uni-list-item><uni-list-item title="社区认证" :showExtraIcon="true" :extra-icon="extraIcon2" link :border="false"></uni-list-item><uni-list-item title="审核帖子" :show-extra-icon="true" link :border="false"><text slot="icon" class="iconfont icon-keyboard font-lg"></text></uni-list-item>import uniListItem from '@/components/uni-list-item/uni-list-item.vue';extraIcon1: {type: 'eye',color: '#000000',size: 20},extraIcon2: {type: 'vip',color: '#000000',size: 20},
    

设置页面开发

  • 新建页面,导航进入

  • 退出登录静态开发

    <template><view><uni-list-item title="账号与安全" link :border="false" ></uni-list-item><uni-list-item title="资料编辑" link :border="false" ></uni-list-item><uni-list-item title="清楚缓存" link :border="false"></uni-list-item><uni-list-item title="意见反馈" link :border="false"></uni-list-item><uni-list-item title="关于社区" link :border="false"></uni-list-item><view class="py-2 px-3"><button class="bg-main text-white" style="border-radius: 50rpx;">退出登录</button></view></view>
    </template><script>import uniListItem from '@/components/uni-list-item/uni-list-item.vue';export default {components:{uniListItem},data() {return {}},methods: {}}
    </script><style></style>

修改密码页面开发

修改密码UI界面开发

  • 新建页面,导航进入

    <uni-list-item title="账号与安全" link :border="false" @click="open"></uni-list-item>uni.navigateTo({url:'../userPassword/userPassword'})
    
  • 静态页面开发

    <view class="px-1"><input class="uni-input" value=""  type="text" placeholder="输入旧密码"/><input class="uni-input" value=""  type="text" placeholder="输入新密码"/><input class="uni-input" value=""  type="text" placeholder="输入确认密码"/><view class="py-2 px-3"><button class="bg-main text-white" style="border-radius: 50rpx;">设置</button></view></view>
    

表单验证功能实现

  • 输入框绑定vue, disabled属性绑定

    computed:{disable(){return this.oldPassword===''||this.newPassword===''||this.renewPassword==='';}},<button class="bg-main text-white" style="border-radius: 50rpx;" :disabled="disable">设置</button>
    
  • 验证功能实现

    check(){if(this.newPassword!==this.renewPassword){uni.showToast({title:'两次输入密码不一致',icon:"none"})return false;}return true;},submit(){if(this.check()){console.log('提交成功');}}
    

修改邮箱页面开发

修改邮箱页UI界面开发

  • 新建页面, 配置page.json

    ,{"path" : "pages/userEmail/userEmail","style" :                                                                                    {"navigationBarTitleText": "设置邮箱"}}
    
  • 拼接字符串, 配置导航,引号不一样用1左边的那个,${}拼接

    open(path){uni.navigateTo({url:`../${path}/${path}`,fail(e) {console.log(e);}})}
    
  • 静态页面开发,与修改密码差不多的功能,禁用

    <template><view><input type="text" class="uni-input" placeholder="请输入邮箱" v-model="email"/><input type="text" class="uni-input" placeholder="请输入密码" v-model="password"/><button class="bg-main text-white mt-1" style="border-radius: 50rpx;" :disabled="disable">绑定邮箱</button></view>
    </template><script>export default {data() {return {email:'',password:''}},computed:{disable(){return this.email===''||this.password===''}},methods: {}}
    </script><style></style>

表单验证功能实现

  • 利用正则表达式完成邮箱功能验证js常用正则表达式

    methods: {check(){var ePattern = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;if(!ePattern.test(this.email)){uni.showToast({title:'邮箱格式不正确',icon:"none"})return false;}return true;},submit(){if(this.check()){console.log("提交成功");}return;}}
    

编辑资料页面开发

编辑资料UI界面实现

  • 新建页面,配置page.json,配置导航

    ,{"path" : "pages/userInfo/userInfo","style" :                                                                                    {"navigationBarTitleText": "资料编辑"}}
    
  • 使用uni-list-item实现静态页面,使用插槽修改

    <template><view><uni-list-item title="头像" :border="false" ><view slot="right" class="flex"><image class="rounded" style="width: 100rpx; height: 100rpx;" src="../../static/default.jpg"></image><text class="flex align-center iconfont icon-bianji1 ml-2" ></text></view></uni-list-item><uni-list-item title="昵称" :border="false"><view slot="right" class="flex ">哈哈<text class="flex align-center iconfont icon-bianji1 ml-2 " ></text></view></uni-list-item><uni-list-item title="性别" :border="false"><view slot="right" class="flex ">未知<text class="flex align-center iconfont icon-bianji1 ml-2 " ></text></view></uni-list-item><uni-list-item title="生日" :border="false"><view slot="right" class="flex ">2021-4-1<text class="flex align-center iconfont icon-bianji1 ml-2 " ></text></view></uni-list-item><uni-list-item title="情感" :border="false"><view slot="right" class="flex ">已婚<text class="flex align-center iconfont icon-bianji1 ml-2 " ></text></view></uni-list-item><uni-list-item title="职业" :border="false"><view slot="right" class="flex align-center">程序员<text class="flex align-center iconfont icon-bianji1 ml-2 " ></text></view></uni-list-item><uni-list-item title="家乡" :border="false"><view slot="right" class="flex ">广东广州<text class="flex align-center iconfont icon-bianji1 ml-2 " ></text></view></uni-list-item><view class="py-2 px-3"><button class="bg-main text-white" style="border-radius: 50rpx;">完成</button></view></view>
    </template><script>import uniListItem from '@/components/uni-list-item/uni-list-item.vue';export default {components:{uniListItem},data() {return {}},methods: {}}
    </script><style></style>

修改头像功能

  • 添加点击事件, 动态绑定userPIc

    <uni-list-item title="头像" :border="false"><view slot="right" class="flex"><image class="rounded" style="width: 100rpx; height: 100rpx;" :src="userPic"></image><text class="flex align-center iconfont icon-bianji1 ml-2"  @click="changePic" ></text></view></uni-list-item>
    
  • uni.chooseImage的使用, 修改头像功能实现

    changePic(){uni.chooseImage({count:1,sizeType:["compressed"],sourceType:["album","camera"],success:(e)=>{this.userPic=e.tempFilePaths[0];}})}
    

showActionSheet接口使用

  • 修改昵称,用输入框

    <input v-model="nickname" class="text-right"/>
    
  • 修改性别, 使用showActionSheet,使用计算属性渲染

    <uni-list-item title="性别" :border="false"><view slot="right" class="flex ">{{sexText}}<text class="flex align-center iconfont icon-bianji1 ml-2 " @click="changeSex"></text></view></uni-list-item>const sexArray=["保密","男","女"];sex:0,sexText(){return sexArray[this.sex];},changeSex(){uni.showActionSheet({itemList:sexArray,success:(e)=>{// this.sex=sexArray[e.tapIndex];this.sex=e.tapIndex;}})},
    
  • 修改情感, 使用一样的方法

  • 修改职业, 使用一样的方法

    changeJob(){uni.showActionSheet({itemList:jobArray,success:(e)=>{this.job=jobArray[e.tapIndex];}})}
    

修改生日功能实现

  • 使用picker,完成该功能

    <picker mode="date" :value="birthday" @change="onDateChange"><uni-list-item title="生日" :border="false"><view slot="right" class="flex ">{{birthday}}<text class="flex align-center iconfont icon-bianji1 ml-2 "></text></view></uni-list-item></picker>onDateChange(e){this.birthday=e.detail.value;}
    

三级城市联动多列选择器选择城市

  • 使用官方组件mpvueCityPicker

    <uni-list-item title="家乡" :border="false"><view slot="right" class="flex ">{{pickerText}}<text class="flex align-center iconfont icon-bianji1 ml-2 " @click="showCityPicker"></text></view></uni-list-item><mpvue-city-picker :themeColor="themeColor" ref="mpvueCityPicker" :pickerValueDefault="cityPickerValueDefault"@onConfirm="onConfirm"></mpvue-city-picker>import mpvueCityPicker from '@/components/mpvue-citypicker/mpvueCityPicker.vue'mpvueCityPickerthemeColor:'#007AFF',cityPickerValueDefault:[0, 0, 1],pickerText:'广东广州'onBackPress() {if (this.$refs.mpvueCityPicker.showPicker) {this.$refs.mpvueCityPicker.pickerCancel();return true;}},onUnload() {if (this.$refs.mpvueCityPicker.showPicker) {this.$refs.mpvueCityPicker.pickerCancel()}},onConfirm(e){this.pickerText = e.label;},showCityPicker(){this.$refs.mpvueCityPicker.show()}
    

帮助反馈页面开发

帮助反馈UI界面实现

  • 新建页面,配置page.json

  • 使用组件uni-collapse

    <view><uni-collapse accordion><uni-collapse-item title="默认开启" ><text>折叠内容</text></uni-collapse-item><uni-collapse-item title="默认开启" ><text>折叠内容</text></uni-collapse-item></uni-collapse><view class="py-2 px-3"><button class="bg-main text-white" style="border-radius: 50rpx;">意见反馈</button></view></view>
    

关于页面开发

关于页面UI界面

  • 新建页面,配置page.json

  • 静态页面开发

    <view><view class="flex align-center justify-center flex-column pt-4 pb-3"><image src="../../static/common/nothing.png" style="width: 300rpx; height: 300rpx;" class="rounded-circle"></image><text class="font text-muted mt-2">version 1.0.1</text></view><uni-list-item title="新版本检测" :border="false" link></uni-list-item><uni-list-item title="社区用户协议" :border="false" link></uni-list-item></view>
    

登录页开发

page.json配置

  • 新建页面,取消原生导航,导航进入

    ,{"path" : "pages/login/login","style" :                                                                                    {"navigationBarTitleText": "","app-plus": {"titleNView": false}}}<navigator url="../login/login"><view class="flex align-center p-2" hover-class="bg-light"><image src="../../static/default.jpg" style="width: 100rpx; height: 100rpx;" class="rounded-circle"></image><view class="flex flex-column flex-1 px-2"><text class="font-lg font-weight-bold text-dark ">昵称</text><text class="font text-muted mt-1"> 总帖子10 今日发帖0</text></view><view class="iconfont icon-jinru"></view></view></navigator>
    
  • x的样式开发

    <view class="flex iconfont icon-guanbi algin-center justify-center font-lg " style="width: 100rpx; height: 100rpx;position: fixed; left: 0;":style="'top:'+statusBarHeight+'px;'" hover-class="bg-light" @click="back"></view>var res=uni.getSystemInfoSync();this.statusBarHeight=res.statusBarHeight;back(){uni.navigateBack({delta:1})}
    

登录页UI界面构建

  • 对之前的开发进行修改,引用一个view代替状态栏即可

    <template><view><view class="status_bar"><!-- 这里是状态栏 --></view><view> 状态栏下的文字 </view></view>
    </template>
    <style>.status_bar {height: var(--status-bar-height);width: 100%;}
    </style>
    
  • 静态页面开发

    <view class="flex iconfont icon-guanbi algin-center justify-center font-lg " style="width: 100rpx; height: 100rpx;position: fixed; left: 0;" hover-class="bg-light" @click="back"></view><view class="flex algin-center justify-center " style="margin-top: 300rpx;"><text class="text-secondary " style="font-size: 60rpx;">账号密码登录</text></view><view class="flex  algin-center border-bottom py-3 px-2 " style="margin-top: 100rpx;"><input type="text" placeholder="昵称/手机号/邮箱" class="" /></view><view class="flex  algin-center border-bottom"><input type="text" placeholder="请输入密码" class="py-3 px-2  flex-1" /><text style="width: 150rpx;" class="text-muted py-3">忘记密码</text></view><view class="py-2 px-3 " style="margin-top: 100rpx;"><button class="bg-main text-white" style="border-radius: 50rpx;">登录</button></view><view class="mt-5 flex algin-center justify-center"><view class="text-primary pr-2">验证码登录</view><view class="text-secondary">|</view><view class="text-primary pl-2">登录遇到问题</view></view><view class="flex algin-center justify-center mt-5"><view style="width: 100rpx; border-bottom: solid #ddd ;" class="mb-2" ></view><view class="text-muted mx-2">社交账号登录</view><view style="width: 100rpx; border-bottom: solid #ddd ; "class="mb-2" ></view></view>
    

登录类型切换效果实现

  • 静态开发图标列表

    <view class="flex align-center px-5 py-3" style="padding-left: 100rpx; padding-right: 100rpx;"><view class="flex-1 flex align-center justify-center"><viewclass="iconfont icon-QQ font-lg bg-primary  text-white flex align-center justify-center rounded-circle "style="width: 100rpx;height: 100rpx;"></view></view><view class="flex-1 flex align-center justify-center "><viewclass="iconfont icon-QQ font-lg bg-primary  text-white flex align-center justify-center rounded-circle"style="width: 100rpx;height: 100rpx;"></view></view><view class="flex-1 flex align-center justify-center "><viewclass="iconfont icon-QQ font-lg bg-primary  text-white flex align-center justify-center rounded-circle"style="width: 100rpx;height: 100rpx;"></view></view></view><view class="flex algin-center justify-center px-5 text-muted">注册即代表同意<text class="text-primary">《xxx社区协议》</text></view>
    
  • 切换验证码的静态显示

    <view class="flex algin-center justify-center " style="margin-top: 300rpx;"><text class="text-secondary " style="font-size: 60rpx;">{{status?'账号密码登录':'验证码登录'}}</text></view><template v-if="status"><view class="flex  algin-center border-bottom py-3 px-2 " style="margin-top: 100rpx;"><input type="text" placeholder="昵称/手机号/邮箱" class="" /></view><view class="flex  algin-center border-bottom"><input type="text" placeholder="请输入密码" class="py-3 px-2  flex-1" /><text style="width: 150rpx;" class="text-muted py-3">忘记密码</text></view></template><template v-else><view class="flex  algin-center border-bottom py-3 px-2 " style="margin-top: 100rpx;"><text class="text-dark mr-2">+86</text><input type="text" placeholder="手机号" class="" /></view><view class="flex  algin-center border-bottom px-2"><input type="text" placeholder="请输入验证码" class="py-3 px-2  flex-1" /><text style="width: 200rpx;" class="text-white bg-main py-3 flex justify-center">获取验证码</text></view></template>changeStatus(){this.status=!this.status}
    

表单基础功能实现

  • 输入框绑定内容,计算属性disable要对于账号密码与手机验证码都ok

    <input type="text" placeholder="昵称/手机号/邮箱" v-model="username" class="" />disabled(){if((this.username===''||this.password==='')&&(this.phone===''||this.code==='')){return true;}return false;}<button class="bg-main text-white" style="border-radius: 50rpx;" :disabled="disabled">登录</button>
    
  • 切换登录方式要初始化表单

    initForm(){this.username='';this.password='';this.phone='';this.code='';},changeStatus(){this.initForm();this.status=!this.status}
    
  • 获取验证码的功能, 倒计时的功能

    getCode(){if(this.codeTime>0){return;}this.codeTime=60;let  timer=setInterval(()=>{if(this.codeTime>=1){this.codeTime--;}else{this.codeTime=0;clearInterval(timer);}},1000)}<text style="width: 200rpx;" class="text-white  py-3 flex justify-center" @click="getCode":class="codeTime>0?'bg-main-disable':'bg-main'">{{codeTime>0?this.codeTime+'s':'获取验证码'}}</text>
    
  • 验证手机号规则编写,用正则表达式验证, 提交方法绑定

    getCode() {if (this.codeTime > 0) {return;}if(!this.validate()){return;}this.codeTime = 60;let timer = setInterval(() => {if (this.codeTime >= 1) {this.codeTime--;} else {this.codeTime = 0;clearInterval(timer);}}, 1000)},validate() {var mPattern = /^1[34578]\d{9}$/;var flag = mPattern.test(this.phone)// console.log(flag);if (!flag) {uni.showToast({title: '手机格式不正确',icon: "none"})return false;}return true;},submit() {if(!this.validate()){return;}console.log('验证成功');this.validate();}
    

第三方登录组件功能实现

  • 新建other-login组件,实现第三方登录

    <template><view class="flex align-center px-5 py-3" style="padding-left: 100rpx; padding-right: 100rpx;"><view class="flex-1 flex align-center justify-center" v-for="(item,index) in this.resultList" :key="index"><view :class="item.icon+' '+item.bgColor"class="iconfont  font-lg   text-white flex align-center justify-center rounded-circle "style="width: 100rpx;height: 100rpx;"></view></view></view>
    </template><script>export default{data(){return {providerList: [],resultList:[]}},mounted() {uni.getProvider({service: 'oauth',success: (result) => {this.providerList = result.provider.map((value) => {let providerName = '';let icon='';let bgColor='';switch (value) {case 'weixin':providerName = '微信登录'icon='icon-weixin';bgColor='bg-success';break;case 'qq':providerName = 'QQ登录';icon='icon-QQ';bgColor='bg-primary';break;case 'sinaweibo':providerName = '新浪微博登录'icon='icon-xinlangweibo';bgColor='bg-danger';break;default:break;}return {name: providerName,id: value,icon:icon,bgColor:bgColor}});console.log(this.providerList);for(var i=0;i<this.providerList.length;i++){if(this.providerList[i].id==='weixin'||this.providerList[i].id==='qq'||this.providerList[i].id==='sinaweibo'){this.resultList.push(this.providerList[i]);}}console.log(this.resultList);},fail: (error) => {console.log('获取登录通道失败', error);}});}}
    </script><style>
    </style>

个人空间开发

page.json配置

  • 新建页面, 配置导航栏按钮,导航进入

     ,{"path" : "pages/user-space/user-space","style" :                                                                                    {"navigationBarTitleText": "","app-plus": {"titleNView": {"titleText": "个人空间","buttons": [{"type": "menu"}]}}}}openSapce() {uni.navigateTo({url:'../../pages/user-space/user-space'})},
    

个人空间头部开发

  • 静态开发

    <view class="flex align-center justify-center p-3 border-bottom border-light-secondary"><image src="../../static/default.jpg" class="rounded " style="width: 180rpx; height: 180rpx;"></image><view class="flex flex-column flex-1 align-center justify-center " ><view class="flex align-center justify-center " style="width: 400rpx;"><view class=" flex-1 flex  align-center justify-center flex-column "><text class="font-lg font-weight-bold">1</text><text class="font text-muted">粉丝</text></view><view class=" flex flex-1 align-center justify-center flex-column"><text class="font-lg font-weight-bold">1</text><text class="font text-muted">粉丝</text></view><view class=" flex flex-1 align-center justify-center flex-column"><text class="font-lg font-weight-bold">1</text><text class="font text-muted">粉丝</text></view></view><view class="flex align-center justify-center pt-2"><button class="bg-main text-white" style="width: 400rpx;">关注</button></view></view></view>
    

个人空间UI界面实现

  • 借用好友列表的tabBar

    <view class="flex align-center py-4" style="height: 100rox;"><text class="flex-1 flex align-center justify-center" v-for="(item,index) in tabBars" :key="index":class="tabIndex===index?'font-lg text-main font-weight-bold':'font-md text-dark'"@click="changeTab(index)">{{item.name}}</text></view>data() {return {tabIndex:0,tabBars: [{name: '主页',},{name: '帖子',},{name: '动态',}]}},changeTab(index){this.tabIndex=index;}
    
  • 主页的实现

    <template v-if="tabIndex===0"><view class="px-3 border-bottom py-2"><view class="font-md">账号信息</view><view class="font">账号年龄:12个月</view><view class="font">账号id:1</view></view><view class="px-3 border-bottom py-2"><view class="font-md">个人信息</view><view class="font">星座:天蝎座</view><view class="font">职业:IT</view><view class="font">故乡:中国</view><view class="font">情感:未婚</view></view></template><template v-else><text>帖子/动态</text></template>
    
  • 帖子动态的实现, 引入commonlist组件,loadMore组件,引入方法,添加动画效果

    <view class="animated fast fadeIn"><block v-for="(item,index) in list" :key="index"><commonList :item="item" :index="index" @follow="follow" @doSupport="doSupport"></commonList><divider></divider></block><loadMore :loading="loading"></loadMore></view>follow(index) {let obj=this.tabBars[this.tabIndex].list[index];obj.isFollow=true;uni.showToast({title: '关注成功'})},doSupport(e) {let obj=this.tabBars[this.tabIndex].list[e.index]console.log(obj);if (obj.support.type === '') {//无操作obj.support[e.type + '_count']++;} else if (obj.support.type === 'support' && e.type === 'unsupport') {//之前是顶,顶减一,踩加一obj.support.support_count--;obj.support.unsupport_count++;} else if (obj.support.type === 'unsupport' && e.type === 'support') {//之前是踩,顶加一,踩减一obj.support.support_count++;obj.support.unsupport_count--;}obj.support.type = e.type;let msg = e.type === 'support' ? '顶' : '踩';uni.showToast({title: msg + '成功'})},
    

个人空间操作菜单

  • 使用弹出层,进行修改即可

    <uni-popup ref="popup" type="top" background-color="#fff"><view class="flex justify-center align-center font-md border-bottom py-2" hover-class="bg-light"@click="popupEvent('findFriend')"><text class="iconfont icon-sousuo mr-2" ></text>加入黑名单</view><view class="flex justify-center align-center font-md py-2" hover-class="bg-light"@click="popupEvent('deleteList')"><text class="iconfont icon-shanchu mr-2"></text>聊天</view></uni-popup>onNavigationBarButtonTap() {this.$refs.popup.open();},
    

全局功能开发

清楚缓存的功能

  • 添加点击事件,清除缓存的方法

==文档只有一些功能缺失,但源码已经完善所有功能,详情请点击码云地址下载源码学习 https://gitee.com/HelLichu/friend ==

使用uniapp开发社区交友网站的项目教程相关推荐

  1. uni-app开发社区交友类项目

    本项目使用uni-app开发社区交友类项目源码

  2. uni-app实战社区交友

    前言 本文是针对<uni-app实战社区交友>系列视频教程的笔记和补充说明, 帮助编程新手快速找到捷径 2021.2.16更新 提示:着重说明比较难的部分,比较简单的教程不详述 免费资源在 ...

  3. java项目交友网如何实现,基于jsp的交友网站-JavaEE实现交友网站 - java项目源码

    基于jsp+servlet+pojo+mysql实现一个javaee/javaweb的交友网站, 该项目可用各类java课程设计大作业中, 交友网站的系统架构分为前后台两部分, 最终实现在线上进行交友 ...

  4. uniapp开发h5微信授权登录(详细教程)

    uniapp开发h5微信授权登录 文章目录 uniapp开发h5微信授权登录 前言 一.前期准备--申请测试账号 二.正式开发--前端代码 三.打包发布 总结 前言 我也是第一次做h5授权微信登录,网 ...

  5. Uni-app 实战社区交友类app开发

    环境搭建和创建项目 开发环境搭建 工具的使用 创建uniapp项目 开发环境搭建 工具的使用 dhttps://www.dcloud.io/hbuilderx.html ,输入网址下载. 插件安装 : ...

  6. 网易云课堂uni-app实战社区交友类app开发笔记

    文章目录 前言 代码展示 前言 提示:可以在这里引入话题,记得删除示例哦. 例如:我们在进行项目开发的时候可能会遇到一些获取屏幕宽度,dp px的相互转换等问题,我们当然不能每用一次就复制粘贴一次.这 ...

  7. 学习笔记(2):uni-app实战社区交友类app开发-引入css动画库

    立即学习:https://edu.csdn.net/course/play/28009/381722?utm_source=blogtoedu 1.  百度搜索并打开  animate.css  . ...

  8. 学习笔记(1):uni-app实战社区交友类app开发-引入自定义图标库

    立即学习:https://edu.csdn.net/course/play/28009/381721?utm_source=blogtoedu 1. 在iconfont.cn图标库中打包下载图标文件压 ...

  9. 中国最大同性交友网站--Gitee入门教程

    你好,我是江潮 你有没有遇到过这种情况: 在开发项目的时候,我们会不断地去修改代码,但是有时候会遇到,想查看某一时间的代码这种情况,如果没有版本控制器,你可能需要不断地定时备份代码,但这样显然是很麻烦 ...

最新文章

  1. xubuntu 19.10安装tensorflow-gpu-2.0(本文很乱,供自己参考)
  2. maven 主工程 java_Maven创建Java Application工程(既jar包)
  3. 我是发起人Sumtec
  4. jsp 中forward 和 Redirect 的用法区别
  5. linux父子进程同步实验,Linux-父子进程的简单同步
  6. Spring MVC——ConverterltString, Dategt DEMO
  7. boost::fruchterman_reingold_force_directed_layout用法的测试程序
  8. .NET 泛型,详细介绍
  9. 中南大学c语言试题期末考试,2011年中南大学C语言期末试题卷A
  10. JavaScript---DOM事件
  11. hash存储结构【六】
  12. db2 控制台执行创建函数语句_Python函数定义及调用
  13. 全程2分钟!教你如何免费下载Windows 10
  14. CVPR学习(三):CVPR2019-各个方向
  15. glassfish3新建domain
  16. CCFTF17(上海):认知计算产业化如何落地(知识图谱、智能问答等)
  17. ISO国家和地区代码
  18. 类型函数(type function)
  19. 硬盘检测重映射扇区计数失败
  20. 【python】LOFTER抽奖程序

热门文章

  1. 计算机系统中设置保护系统还原,如何对电脑进行系统还原
  2. 南京工资个税计算机,2017南京工资交税标准及个税起征点
  3. 输入法/非输入法切换 无法取消快捷键问题 以及 shift按键关闭CapsLock问题
  4. python校园失物招领系统毕业设计开题报告
  5. ActiveMQ——消息的生产和消费
  6. 火山引擎云原生大数据在金融行业的实践
  7. 阿噗啊噗服务器维护,这些App我能笑一年!阿噗整理的20个奇葩App,没玩过你就OUT了!...
  8. 织梦文章发布 html仅动态,织梦dedecms采集文章后导出为仅动态的解决方案
  9. win2008找不到无线网络
  10. NLP模型集锦----pynlp