派大星

vuePress-theme-reco 派大星    2021 - 2022
派大星 派大星
主页
博客
  • 前端
  • JavaScript文章
  • 三级目录
  • 笔记
  • 学习笔记
  • 页面
  • CSS
  • HTML
  • 技术
  • 技术文档
  • GitHub技巧
  • 技术笔记
  • 实用工具
  • Nodejs
  • 博客搭建
  • 更多
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • JavaScript
  • 浏览器&网络
  • 前端框架
  • 资源工具
  • 持续集成
  • 小程序
  • 杂谈
  • React
  • Mysql
  • 面试题
  • uniapp
  • 《ES6 教程》笔记
  • 《Git》学习笔记
  • 《JavaScript教程》笔记
  • 《React》笔记
  • 核心概念
  • 高级指引
  • Hook
  • 案例演示
  • 《TypeScript 从零实现 axios》
  • 初识 TypeScript
  • TypeScript 常用语法
  • ts-axios 项目初始化
  • ts-axios 基础功能实现
  • ts-axios 异常情况处理
  • ts-axios 接口扩展
  • ts-axios 拦截器实现
  • ts-axios 配置化实现
  • ts-axios 取消功能实现
  • ts-axios 更多功能实现
  • ts-axios 单元测试
  • ts-axios 部署与发布
  • 《Vue》笔记
  • 基础
  • 组件
  • 过渡&动画
  • 工具
  • 规模化
  • 可复用性&组合
  • 其他
  • Vuex
标签
时间轴
关于
author-avatar

派大星

272

文章

69

标签

主页
博客
  • 前端
  • JavaScript文章
  • 三级目录
  • 笔记
  • 学习笔记
  • 页面
  • CSS
  • HTML
  • 技术
  • 技术文档
  • GitHub技巧
  • 技术笔记
  • 实用工具
  • Nodejs
  • 博客搭建
  • 更多
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • JavaScript
  • 浏览器&网络
  • 前端框架
  • 资源工具
  • 持续集成
  • 小程序
  • 杂谈
  • React
  • Mysql
  • 面试题
  • uniapp
  • 《ES6 教程》笔记
  • 《Git》学习笔记
  • 《JavaScript教程》笔记
  • 《React》笔记
  • 核心概念
  • 高级指引
  • Hook
  • 案例演示
  • 《TypeScript 从零实现 axios》
  • 初识 TypeScript
  • TypeScript 常用语法
  • ts-axios 项目初始化
  • ts-axios 基础功能实现
  • ts-axios 异常情况处理
  • ts-axios 接口扩展
  • ts-axios 拦截器实现
  • ts-axios 配置化实现
  • ts-axios 取消功能实现
  • ts-axios 更多功能实现
  • ts-axios 单元测试
  • ts-axios 部署与发布
  • 《Vue》笔记
  • 基础
  • 组件
  • 过渡&动画
  • 工具
  • 规模化
  • 可复用性&组合
  • 其他
  • Vuex
标签
时间轴
关于

uni-app组件的使用 第二篇

vuePress-theme-reco 派大星    2021 - 2022

uni-app组件的使用 第二篇

派大星 2021-12-30 微信小程序uni-appHBuilderXDCloud下拉刷新触底加载proxy代理

# uni-ui宫格布局+proxy代理+弹出层

http://www.codeboy.com:9999/data/product/list.php

功能点:

  • 请求接口加载数据列表形式展示

  • 触底加载 翻页 发送请求翻页数据 传参页数

    • 提示文字 加载中... ui-load 组件 status控制显示的文字
    • 触底事件 发送请求 拼接数据
  • 下拉刷新 更新最新数据 请求第一页数据

    • 页面下拉刷新需要开启pages.json

      ​ pages.json开启下拉操作

      image-20211230114635057

    • 下拉事件 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

对于数据进行存储,并展示到页面中

image-20211230152910680

客户端浏览器由于同源策略的影响,会出现跨域问题。 同源策略它是浏览器的基本安全策略,目的是保障用户信息的安全。 不同域之间不能够相互请求和操作对应的数据(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内置浏览器自带解决跨域问题 跨域问题由浏览器限制

  1. 建立配置文件

    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

image-20211230184859574

<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>