# uni-ui
宫格布局+proxy代理+弹出层
http://www.codeboy.com:9999/data/product/list.php
功能点:
请求接口加载数据列表形式展示
触底加载 翻页 发送请求翻页数据 传参页数
- 提示文字
加载中...
ui-load
组件 status控制显示的文字 - 触底事件 发送请求 拼接数据
- 提示文字
下拉刷新 更新最新数据 请求第一页数据
页面下拉刷新需要开启
pages.json
pages.json
开启下拉操作下拉事件
onPullDownRefresh
发送请求 加载第一页
回到顶部 当数据列表较长 从底部快速回到顶部方式
- 当页面滚动到一定位置的时候,再出现回到顶部的按钮
- 点击按钮,滚动到页面的初始位置 顶部位置
<template>
<view v-if="data">
<uni-list>
<uni-list-item v-for="(item,index) in data.data" :key="index" :clickable="true" :showArrow="true">
<!--使用插槽的方式写入内容 否则不能够显示 -->
<template slot="body">
<view class="item">
<image :src="`http://www.codeboy.com:9999/${item.pic}`" mode=""></image>
<view>
<view>{{item.title}}</view>
<view>¥{{item.price}}</view>
</view>
</view>
</template>
</uni-list-item>
</uni-list>
<!-- 加载更多组件 -->
<!-- status属性只有三个 more loading noMore 是固定只能传这三个值-->
<uni-load-more :status="status"></uni-load-more>
<!-- 回到顶部按钮 -->
<!-- @ vue中的事件绑定 -->
<view class="btn-gotop" v-show="showBtn" @click="goTop">
<uni-icons type="arrow-up"></uni-icons>
</view>
</view>
</template>
<script>
export default {
data() {
return {
data: null,
// 加载更多组件 状态管理
status:'more',
showBtn:false
}
},
// 下拉事件
onPullDownRefresh() {
// console.log('下拉事件触发了')
// 下拉刷新 就是加载第一页数据
this.getData(1)
// 停止下拉刷新的状态
},
// 监听滚动位置
onPageScroll(e) {
console.log(e.scrollTop)
// 当滚动距离顶部>1500 设置回到顶部按钮显示状态为true
// if(e.scrollTop>1500){
// this.showBtn = true
// }else{
// this.showBtn = false
// }
// 比较运算符的返回值就是bool类型 刚好前面bool值
this.showBtn = e.scrollTop >1500
},
// 触底事件
onReachBottom() {
// console.log('到底了');
// 加载翻页数据
// 获取当前页数 获取当前是第几页 总页数
// es6 解构语法
const {pno,pageCount} =this.data
// console.log(pno)
// 判断当前页数是最大页数, 说明后续没有数据了 不进行后续操作
if(pno == pageCount){
// 加载更多的组件的状态修改为 noMore
this.status = 'noMore'
// return 后续代码都不执行
return;
}
// 请求接口 翻页
// 请求数据时,把加载更多组件的状态修改为加载中
this.status = "loading"
this.getData(pno+1)
},
// 发请求 拿数据 存本地 做展示
// onLoad或者mounted中发送请求
mounted() {
this.getData()
},
methods:{
// 回到顶部处理
goTop(){
uni.pageScrollTo({
// 0 回到顶部
scrollTop:0,
duration:100
})
},
// 请求数据
// 默认第一页
getData(pno = 1){
const url = 'http://www.codeboy.com:9999/data/product/list.php'
uni.request({
url,
method: 'GET',
// {pno:pno}
data: {pno},
success: res => {
console.log(res);
// 确认请求数据成功后 停止下拉
uni.stopPullDownRefresh()
// 拼接数据 旧数据+新数据
// 非第一页拼接
if(pno>1){
// es6 []数组合并 ...展开
// 拼接数据 旧数据+新数据
res.data.data = [...this.data.data,...res.data.data]
}
this.data = res.data
},
fail: () => {},
complete: () => {}
});
}
}
}
</script>
<!-- scss 安装scss插件 -->
<style scoped lang="scss">
.item{
// 布局方式 弹性盒子
display: flex;
image{
width: 180rpx;
height:180rpx;
// 方式1设置最小宽度
// min-width: 180rpx;
// 方法2:flex none 不压缩 不收缩
flex: none;
}
>view{
display: flex;
flex-direction: column;
// 主轴对其方式
justify-content: space-between;
// frist-of-type
>view:first-of-type{
// 两行折行 不显示 ...代替
text-overflow: -o-ellipsis-lastline;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
line-clamp: 2;
-webkit-box-orient: vertical;
}
>view:last-of-type{
font-size: 1.1em;
font-weight: bold;
color: #ff0000;
}
}
}
.btn-gotop{
width:100rpx;
height:100rpx;
background-color: rgba(0,0,0,0.3);
position: fixed;
right:30rpx;
bottom: 100rpx;
display: flex;
justify-content: center;
border-radius: 50%;
align-items:center ;
}
</style>
# 宫格布局
常用来实现多个数据的布局
<template>
<view>
<!-- ugrid 宫格 -->
<!-- hightlight 点击高亮 showBorder显示边框 square 方形 -->
<uni-grid :column="2" :highlight="false" :showBorder="false" :square="false">
<uni-grid-item v-for="(item,index) in skills" :key="index">
{{item}}
</uni-grid-item>
</uni-grid>
</view>
</template>
<script>
export default {
data() {
return {
skills: ['html','css','javascript','Jquery','vue','react','angular']
}
},
}
</script>
<style scoped>
</style>
# 案例:斗鱼直播房间列表 双列布局
实现思路:
发送请求 接收回数据
https://m.douyu.com/api/room/list?page=1&type=yz
对于数据进行存储,并展示到页面中
客户端浏览器由于
同源策略
的影响,会出现跨域问题。 同源策略它是浏览器的基本安全策略,目的是保障用户信息的安全。 不同域之间不能够相互请求和操作对应的数据(cookie) 协议不同 http https http://www.a.com https://www.a.com 域名不同;http://www.a.com http://bbb.a.com 端口的不同: http://www.a.com:3000 http://www.a.com:8080
解决跨域问题
:常见的方式:
jsonp
需要服务端配置返回数据src
或scriptsrc
非官方的 存在安全注入风险 不流行cors中间件
服务端直接配置允许跨域 服务端人员配置 实际业务运营
proxy
代理 启动一个代理服务 请求数据返回 底层是http-middeware-proxy
插件 基于NodeJS 开发过程中 业务运营
uni-app基于vue开发的,之前学习的vue proxy代理方式 在这里也同样使用
HBX内置浏览器自带解决跨域问题
跨域问题由浏览器限制
建立配置文件
vue.config.js
// vue.config.js 项目包根目录下
// es6的导出模块 模块暴露 外面才可以调用
module.exports={
// 配置开发服务器
devServer:{
// 代理
proxy:{
// https://m.douyu.com/api/room/list?type=yz
// 配合proxy 请求地址需要进行修改
// /douyu/api/room/list?type=yz 代理修改地址
// https://m.douyu.com/douyu/api/room/list?type=yz
// 代理段
// 标识头
"/douyu":{
// 代理到的远程地址
target:'https://m.douyu.com',
// 域名变化的 不一致的 大部分情况都是不一样的
changeOrigin:true,
// 根据协议配置secure https 要配置为true
secure:true,
// 路径重写
pathRewrite:{
// ^ 正则 以xx开头
"^/douyu":""
}
}
}
}
}
2.接口地址也需要修改
getDate(page = 1) {
// proxy代理需要告知哪个接口地址需要代理
// 加一个表示信息 /douyu
const url = '/douyu/api/room/list?type=yz'
uni.request({
url,
method: 'GET',
// {page:page}缩写 {page}
data: {page},
success: res => {
console.log(res);
},
fail: () => {},
complete: () => {}
});
}
3.重启项目包 让配置文件生效
全部的代码如下
<template>
<view v-if="data">
<!-- ugrid -->
<!-- square 正方形 -->
<uni-grid :column="2" :square="false" :highlight="false" :showBorder="false">
<uni-grid-item v-for="(item,index) in data.list" :key="index">
<view class="item">
<view>
<image :src="item.roomSrc"></image>
<view><uni-icons type="person" color="white"></uni-icons>{{item.nickname}}</view>
<view><uni-icons type="fire" color="white"></uni-icons>{{item.hn}}</view>
</view>
<view>{{item.roomName}}</view>
</view>
</uni-grid-item>
</uni-grid>
<uni-load-more :status="status"></uni-load-more>
<button type="default" class="goTopBtn" @click="goTop" v-show="goTopBtn">
<uni-icons type="arrow-up" color="white" :size="30"></uni-icons>
</button>
</view>
</template>
<script>
export default {
data() {
return {
data: null,
status:"more",
goTopBtn:false
}
},
//监听页面滚动 页面滚动生命周期函数
onPageScroll(e){
console.log(e.scrollTop)
this.goTopBtn = e.scrollTop>1000
},
// 触底加载
onReachBottom() {
console.log("到底部了")
const {nowPage,pageCount} = this.data
if(nowPage == pageCount){
this.status = 'noMore'
return
}
this.status = 'loading'
this.getDate(nowPage+1)
},
// 下拉刷新
onPullDownRefresh() {
console.log("下拉了")
this.getDate(1)
},
// 发请求 拿数据 存本地 做展示
mounted() {
this.getDate()
},
methods: {
// 回到顶部
goTop(){
uni.pageScrollTo({
scrollTop:0,
duration:500
})
},
getDate(page = 1) {
// proxy代理需要告知哪个接口地址需要代理
// 加一个表示信息 /douyu
const url = '/douyu/api/room/list?type=yz'
uni.request({
url,
method: 'GET',
// {page:page}缩写 {page}
data: {page},
success: res => {
console.log(res);
uni.stopPullDownRefresh()
if(page>1){
res.data.data.list = [...this.data.list,...res.data.data.list]
}
this.data = res.data.data
},
fail: () => {},
complete: () => {}
});
}
},
}
</script>
<style scoped lang="scss">
.goTopBtn{
position: fixed;
right: 10rpx;
bottom: 10rpx;
width: 100rpx;
height: 100rpx;
border-radius: 50%;
background-color: rgba(0,0,0,0.3);
display: flex;
justify-content: center;
align-items: center;
}
.item{
padding: 10rpx;
image{
width: 100%;
height: 250rpx;
border-radius: 4px;
display: block;
}
>view:first-of-type{
position: relative;
view:first-of-type{
position: absolute;
left: 0;
bottom: 0;
color: white;
font-size: 0.9em;
border-radius: 4px;
background-color:rgba(0,0,0,0.3)
}
view:last-of-type{
position: absolute;
right: 0;
top: 0;
color: white;
font-size: 0.9em;
border-radius: 4px;
background-color:rgba(0,0,0,0.3)
}
}
>view:last-of-type{
font-size:1.2em;
// 一行折行隐藏 ...代替
white-space:nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
</style>
# 弹出层
popup
vue
this.$refs
<template>
<view>
<!-- popup 弹出层 -->
<!-- ref 绑定子元素 方便 再父元素 调用到子元素的方法 -->
<!-- ref绑定后找子元素对象 this.$refs.popup 绑定的名称 -->
<uni-popup ref="popup" type="top">
<view style="background-color: white;font-size: 35rpx;padding: 10rpx;">
<!-- 我是弹出层的内容 -->
<image src="/static/c1.png" mode=""></image>
</view>
</uni-popup>
<!-- 预置样式 提示message -->
<!-- 代码执行过程中 ref会被覆盖 这里就不改名了 -->
<uni-popup ref="popup" type="message">
<uni-popup-message type="success" message="恭喜你成功了!" :duration="2000"></uni-popup-message>
</uni-popup>
<uni-popup ref="popup" type="share">
<uni-popup-share title="分享到" @select="select"></uni-popup-share>
</uni-popup>
<!-- 制作一个按钮 点击触发弹出层 -->
<button type="primary" size="mini" @click="clickOpen">点击这里</button>
</view>
</template>
<script>
export default {
methods:{
clickOpen(){
// 找到uni-popup组件 ref绑定找
console.log(this.$refs.popup)
// 弹出层的效果
this.$refs.popup.open()
},
select(e){
// index 通过下标 选择对应的分享
console.log(e)
}
}
}
</script>
<style scoped>
</style>