uni-app小程序开发 基础知识2

news/2025/2/21 7:16:52

目标:

构建一个文章发表平台。

我们先来写一个静态框架。

以下是

首页初代码+文章列表页代码:

<template>
	<view class="content">
		<!-- 轮播图 -->
		<swiper  class="swiper-container" autoplay="true" interval="3000" circular="true">
			<!-- 每个item里循环 -->
			<swiper-item >
				<!-- 这是自己的轮播内容 img -->
				<image src="" class="swiper-image"></image>
			</swiper-item>
		</swiper>
		<!-- 中间icon图标 -->
		<view class="icon-container">
			<!-- 每个icon-row里循环 -->
				<view class="icon-row" >
					<view class="icon-item" >
						<!-- icon图标 -->
						<image src="" class="icon-image"></image>
						<!-- 底部文字 -->
						<text class="icon-text"></text>
					</view>
				</view>
		</view>
		<!-- 热门文章 -->
		<view class="article">
			<view style="display: flex;justify-content: space-between;margin: 0 50rpx;">
				<text style="font-weight: bold;">热门文章</text>
				<text style="font-size: 12px;color:#ccc">查看全部></text>
			</view>
			<!-- 文章内容 -->
			<view class="article-img"  >
				<!-- 文章图片 -->
				<img src="" alt="" class="img"/>
				<!-- 文章标题 -->
				<view class="hot-word">
					
				</view>
			</view>

		</view>
	</view>
</template>

<script>

	export default {
		data() {
			return {
				// 轮播图内容
				swiperItems: [
					{
						id:1,
						url:"https://img-blog.csdnimg.cn/2021051521244130.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl81MzQ0Nzc3Ng==,size_16,color_FFFFFF,t_70"
					},
					{
						id:2,
						url:"https://ts1.cn.mm.bing.net/th/id/R-C.9881613a29f26488b40938427aa585e4?rik=fim4XvDejjHE%2fQ&riu=http%3a%2f%2fn.sinaimg.cn%2fsinakd20220516ac%2f797%2fw2048h1149%2f20220516%2fb0aa-5aca29fe2dfa69c385118bbc74d039de.jpg&ehk=tzq%2bJP6uMipI0aIHY3bMSVO7lS7ZQM6TKMlwZ5CFP4s%3d&risl=&pid=ImgRaw&r=0"
					},
					{
						id:3,
						url:"https://ts1.cn.mm.bing.net/th/id/R-C.1ba7730f131b89278f37af053abd305c?rik=4ZdRDx%2bBrDRsgA&riu=http%3a%2f%2fpic.bizhi360.com%2fbbpic%2f90%2f10190.jpg&ehk=BEPnflW%2bZdQGggy286CG%2bpJrPop%2b92UEVILUX%2bnbV18%3d&risl=&pid=ImgRaw&r=0"
					}
				],
				// 字体图标内容
				iconRows: [
					{		id:1,
							url: '/static/icon1.png',
							text: '添加文章',
							path:'/pages/article/article'
						},
						{
							id:2,
							url: '/static/icon.png',
							text: '代码帮助'
						},
						{
							id:3,
							url: '/static/call.png',
							text: '联系我们'
						},
						{
							id:4,
							url: '/static/liuyan.png',
							text: '我要留言'
						}
				],
				// 热门文章内容
				hotWord:{
					text:"标题",
					img:"http://contentcms-bj.cdn.bcebos.com/cmspic/96bfd5a4a25940d636812bae6737697d.jpeg?x-bce-process=image/crop,x_0,y_0,w_1597,h_877"
				},
				hot_list:[]
			}
		},
		onLoad() {
			
		},
		methods: {
			
		}
	}
</script>

<style>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.swiper-container {
		width: 90%;
		/* 针对于移动端小程序专门用的单位 */
		height: 300rpx;
		margin: 0 auto;
		/* 根据需要调整高度 */
	}

	.swiper-image {
		width: 100%;
		height: 100%;
		object-fit: cover;
	}

	.icon-container {
		width: 100%;
		margin: 50rpx 0;
		display: flex;
		align-items: center;
	}

	.icon-row {
		flex: 1;
		margin-bottom: 20rpx;
	}

	.icon-item {
		display: flex;
		flex-direction: column;
		align-items: center;
	}

	.icon-image {
		width: 80rpx;
		height: 80rpx;
	}

	.icon-text {
		margin-top: 10rpx;
		font-size: 24rpx;
		color: #8f8f94;
	}

	.text-area {
		display: flex;
		justify-content: center;
	}

	.title {
		font-size: 36rpx;
		color: #8f8f94;
	}

	.article {
		width: 100%;
	}
	.article-img{
		width: 100%;
	}
	.img{
		margin:50rpx 50rpx 10rpx 50rpx;
		width: 650rpx;
		height: 400rpx;
	}
	.hot-word{
		margin-left: 50rpx;
	}
</style>

文章列表页初代码,静态图片自己加入。:

<template>
	<view class="content">
		<!-- 每一个文章卡片,在这里循环 -->
		<view class="index-card" >
			<!-- 封面 -->
			<image class="index-img" src="" mode=""></image>
			<view class="ellipsis">
				<!-- 文章标题 -->
				<text>
				
				</text>
			</view>
			<!-- 文章时间 -->
			<view class="index-small">
				
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				listData: [{
						title: "暴走萝莉·金克丝,是MOBA竞技网游《英雄联盟》中的英雄角色,定位为射手。",
						img: "/static/img1.jpg",
						id: 1,
						content: '是英雄联盟历史上第一个拥有宣传视频的英雄。\n金克丝在团战初期就能输出大量伤害。金克丝的攻击距离以及伤害使得她能够与远距离poke型阵容融合。\n 神经狂躁、冲动任性、劣迹斑斑……金克丝出身自祖安,生来就爱不计后果地大搞破坏。她就是一座人形自走军火库,所经之处必定会留下夺目的火光和震耳的爆炸。金克丝最讨厌无聊,所以不管她去到哪里,混乱和骚动就会如期而至,这就是她留下的“到此一游”。'
					},
					{
						title: "逆羽·霞,是MOBA竞技网游《英雄联盟》中的一位英雄角色,是一个极具输出与收割能力的射手英雄",
						img: "/static/img2.jpg",
						id: 2,
						content: '她能凭借着具有穿刺效果的羽毛,同时对敌方前排与后排造成大量伤害。霞最擅长的就是使用羽毛,合理的运用羽毛的停留,能让她收获出乎意料的效果。 \n 身为瓦斯塔亚的志士,霞要掀起一场革命来拯救她的族群。她身法敏捷又慧心独具,凭借锋芒逼人的羽刃,扫除任何异己。霞与她的灵魂伴侣洛并肩作战,共同守护他们日渐衰落的部族,同时韬光养晦,希望终有一天能率领全族重夺昔日荣光.'
					},
					{
						title: "封魔剑魂·永恩,是MOBA竞技网游《英雄联盟》中第150位登场的英雄角色,英雄定位为战士、刺客",
						img: "/static/img3.jpg",
						id: 3,
						content: '生前的永恩,恪守着忠义师道。从很小的时候,他就开始为心爱的家庭扮演保护者的角色,不得不说这很大程度上是因为幼年丧父对他的影响。与他形成鲜明对比的,是他同母异父的弟弟——亚索。与亚索的冲动、鲁莽相反,永恩充满了耐心和自律。\n 生前,他是永恩,是亚索同母异父的哥哥,是故乡剑术道场的知名弟子。但当他死在弟弟手下以后,却发现自己被精神领域中的恶毒灵体所侵扰,不得不用它自己的刀剑将它弑杀。如今,被诅咒的永恩戴上了它的恶魔面具,开始了不懈的追猎,他要猎尽所有同种的恶魔,从而查清自己究竟成为了什么。'
					},
					{
						title: "刀锋舞者·艾瑞莉娅,是MOBA竞技网游《英雄联盟》中的英雄角色,定位为战士。",
						img: "/static/img4.jpg",
						id: 4,
						content: '时而似平静的海面,时而似汹涌的风暴。艾瑞莉娅是艾欧尼亚勇猛的捍卫者,她接受过祖辈传承的舞蹈训练,并将舞艺化为战斗的技法。伴随着她优雅的动作,锋利的刀刃在空中组成夺命的阵列翩翩起舞,这位刀锋舞者将斩除任何想要扮演征服者的蠢货。\n 诺克萨斯对艾欧尼亚的占领催生了许多英雄,但没有谁像纳沃利的艾瑞莉娅一般令人意外。她将家乡的古老舞艺化为战技,以精心修习的优雅身姿操控着致命的刀丛。在她证明了自己的战斗实力后,被众人推举为反抗军的领袖和首脑,为了守卫家园而奋斗至今。'
					},
					{
						title: "探险家·伊泽瑞尔,是MOBA竞技网游《英雄联盟》中的一名英雄角色,定位为射手、法师",
						img: "/static/img5.jpg",
						id: 5,
						content: '伊泽瑞尔是一名非常灵活飘逸的英雄,双加成的技能使他不但可以走AD路线,也能作为法师走AP路线。\n 神采奕奕的冒险家伊泽瑞尔拥有自己不知道的魔法天赋,他搜刮失落已久的古墓,触碰古老的诅咒,还举重若轻地挑战常人不可能完成的极限。他的勇气和壮举无边无际,总是喜欢随机应变地解决任何情况,一定程度上依赖他的小聪明,但更主要是依赖他神秘的恕瑞玛护手,在他的操控下释放出破坏性的奥术爆弹。有一件事可以肯定——只要伊泽瑞尔出现,那么麻烦一定接踵而至。或是还没走远。范围大概是随时随地。'
					}
				]
			}
		},
		onLoad() {

		},
		methods: {

		}
	}
</script>

<style>
	.content {
		width: 90%;
		margin: 0 auto;
	}

	.index-card {
		width: 100%;
		height: 500rpx;
		margin-bottom: 10rpx;
	}

	.index-img {
		width: 100%;
		height: 400rpx;
		border-radius: 15rpx 15rpx 0rpx 0rpx;
	}

	.ellipsis {
		padding: 0 10rpx;
		white-space: nowrap;
		/*超出的空白区域不换行*/
		overflow: hidden;
		/*超出隐藏*/
		text-overflow: ellipsis;
		/*文本超出显示省略号*/
		margin-bottom: 5rpx;
	}

	.index-small {
		text-align: right;
		font-size: 14px;
		color: #cfccc9;
	}
</style>

首先是我们的

轮播图:

相关代码我们可以从官网的swipe中找到案例:

我们的每一个相片都是一个swipe-item。

我们所有的相片地址都写在了export default里面了,所以我们接下来使用v-for来调用我们数组里面的元素。

接下来是我们下面的

功能图标:

是我们的数组里嵌套对象,我们接着用v-for调用元素。

然后是

热门文章:

因为我们先写的是假数据(死数据),我们渲染的话是用我们渲染对象的方式

假数据:就是提前写好的,一般于我们的用户没有交互的数据内容。

我们接下来给我们的查看全部设置点击事件:

<text style="font-size: 12px;color:#ccc" @click="toText">查看全部></text>

			toText(){
				uni.navigateTo({
					url: '/pages/text/text',
				});
			}
			

然后利用v-for调死数据就可以完成我们的文章列表页的渲染(时间函数暂时未写):


动态数据

与后端的交互模式,一般是我们向后端发送请求,然后后端给我们返还相应的指令,我们再检查指令是否是我们想要的,如果是我们就使用。

我们的网络请求如下,我们使用的是Axios,其是Ajax的二次开发。

首先需要

安装的俩个库:

pip install flask

pip install flask_cors

request.js和api.js源码

首先我们的Ajax请求封装在了,request.js里面,代码如下:

// const baseUrl = 'http://127.0.0.1:5005' /* 根域名 */
// const baseUrl = 'http://192.168.1.167:5005'
// 动态配置根域名 main.js
const baseUrl = uni.getStorageSync('rootDomain5000')
// const baseUrl = uni.getStorageSync('rootDomain5005')
// const baseUrl = uni.getStorageSync('rootDomain')
const request = (url = '', options = {}, contentType = 'application/json') => {
  return new Promise((resolve, reject) => {
    uni.showLoading({
      title: '加载中',
      mask: true,
    })
	// let baseUrl = url.includes('/login') ? rootDomain5005 : rootDomain5000
	// console.log(rootDomain5005,'111')
    uni
      .request({
        method: options.method,
        url: baseUrl + url,
        data: options.data,
        header: {
          'Content-Type': contentType,
          Authorization: uni.getStorageSync('token'),
        },
        dataType: 'json',
      })
      .then((response) => {
        uni.hideLoading()
        let {
          statusCode,
          data,
          errMsg
        } = response
        if (statusCode === 200) {
          resolve(data)
        } else {
          uni.showToast({
            title: errMsg,
            icon: 'none',
          })
          reject(errMsg)
        }
      })
      .catch((error) => {
        reject(error)
      })
  })
}
const get = (url, data) => {
  return request(url, {
    method: 'GET',
    data: data,
  })
}

const post = (url, data) => {
  return request(url, {
    method: 'POST',
    data: data,
  })
}

const postQuery = (url, data) => {
  return request(
    url, {
      method: 'POST',
      data: data,
    },
    'application/x-www-form-urlencoded'
  )
}

const put = (url, data) => {
  return request(url, {
    method: 'PUT',
    data: data,
  })
}

module.exports = {
  get,
  post,
  postQuery,
  put,
}

然后api.js里面装着我们的接口。

代码如下:

const requests = require('@/utils/request.js')

// 登录接口
export const loginGet = (param) => {
  return requests.get('/loginxcx', param)
}

// 首页轮播图
export const home_switch = () =>{
	return requests.get('/switch',)
}

// 文章列表
export const listShow = (param) => {
  return requests.get('/article_list', param)
}

// 获取文章详情
export const article_details = (id) => {
  return requests.get(`/article_details?id=${id}`)
}

// 添加文章
export const add_article = (data) => {
  return requests.post(`/add_article`,data)
}

我们所有的Ajax请求全部写在我们的request.js里面,所以在接口文件里面,我们仅需要去调用request里面的Ajax请求就可以了。

小知识:

如果另一个文件需要调用该文件,该文件需要导出,另一个文件需要导入。

然后我们来介绍

api的结构:

request先不用管,因为大多数小程序,该后端代码依旧适用。

const是定义变量的关键词。

箭头函数导出的固定形式:

export const 函数名 = (形参)=> {

return requests.get(导出的文件地址,形参)

注意:我们的请求方式,参数等都是需要严格和后端代码相对于,否则会报错。

在app.py中我们可以看到我们的后端代码:

现在我们来启动一下后端代码:

直接运行app.py,然后它就在后台运行了。

1,用后端代码运行轮播图。

所以,我们现在index里面导入该文件

@/表示在根目录,及我文件的my_Blog,这样会方便写我们的相对路径。

先导入我们的函数:import { home_switch } from '@/pages/apis/api.js'

注意:该导入位置与我们的export default平行。

我们的下方去调用它:

            getSwiper()
            {
                home_switch().then((res)=>{
                    console.log(res);
                })
            }
            注意我们的写法,home_switch().then()语法,是说当我们调用了前者函数,就执行我们then后面括号里面的内容,然后上面是我们then后面又写了一个箭头函数。注意,我们res如果只有一个参数,括号可以省略。

然后我们操作一下

非手动点击的函数调用。(进入则调用)

我们的onLoad函数就是这样的功能:

一进入页面就执行onLoad函数,所以我们在onLoad函数里面调用 getSwiper(),就可以打印出来res里面的信息了。(调用要用this哦!!!

调用后,我们的res内容是:     而我们需要其中的data里面的数据,这个data里面的内容也恰好与我们的轮播图数组里面的内容结构一致,那么我们就可以直接使用res.data去调用我们的后端活数据(来源于数据库),不去用死数据了。

2,后端代码导入文章列表页。

与上述同样的方式,我们在文章列表页重新操作一次:   便可得到我们想要的结果。

我们可以等于(第9行)的原因是俩者结构完全相同。

time的实时化

{{ item.time}}调用即可。

3,添加文章事件的点击事件。

因为我们的图标是以循环的方式添加的,所以我们添加点击事件就是给每一个图标都添加点击事件。而且我们也不能跳转到同一个页面。

我的的图标结构如下:       所以我们的uni.navigateto中的url不能写死,需要往函数里面传参,就是path

函数的构建:                              -------->点击事件的创建。

 然后就完成了点击事件。

那现在我们的任务就是给我们的添加文章页面添加功能,使其能够将数据传输到我们的后端接口,完成文章的添加。

先设置容器,保存我们的数据:

然后再去设置点击事件。


       

(1)表单控件的数据绑定:

指令:v-model       双向数据绑定:在输入框里面修改的内容在下方里面的title等里面的内容也会跟着进行改变。   写在input里面.

比如:


我们给title和content绑定了数据后:       再去考虑选择图片按钮。使其能够打开本地图片并且选择

(2)选择本地图片并上传
步骤一:打开相册,选择图片。

关于相关代码,可以在官网寻找:

相关的属性:

我们对示例进行修改后,便可进行修改。其中res的内容是:

“0”:是我们的本地临时路径,只能在本地访问,浏览器无法访问。这也是我们上传的文件的本地路径。但我们需要把这个图片理由后端存到某个地方(一般是服务器),我们没有服务器,所以我们目前操作是把我们的本地图片传给后端文件,然后将该图片文件存储到我们的本地数据库里。

步骤二:上传图片

我们仿照如下示例进行操作:

真实后端接口=  后端启动IP + 上传图片的接口名  。这里我们后端的接口名是upload_img

打印一下我们的success回调函数后,可以发现,我们的图片地址在后端发生了地址的拼接,这个拼接后的地址,就是我们将文件存入后,所在的后端服务器地址,我们需要获得他

打印回调函数里面的data后发现其是一个字符串(如果是对象,则是可折叠的)

我们需要对其进行进行转化,

语法JSON.parse(转换的对象)

转换成功:

我们需要的地址是其中的data。

所以我们写 let realpath = data.data   就可以了。

步骤三:图片回显

注意:如果我们想要在函数里面使用this ,我们的函数必须是箭头函数,否则我们的下面无法访问this里面的对象。

整体函数如下。

		handleImg(){
			    uni.chooseImage({
				count: 1, 
				sizeType: ['original', 'compressed'], 
				sourceType: ['album'], //从相册选择
				success: res =>{
							const path = res.tempFilePaths[0]
							uni.uploadFile({
							url: 'http://127.0.0.1:5000/upload_img', //仅为示例,非真实的接口地址
							filePath: path,
			     				name: 'file',
			    				success: (uploadFileRes) => {
							// uploadFileRes.data是一个json字符串,我们需要进行转换
								let data = JSON.parse(uploadFileRes.data)
			     				this.img=data.data
								let real_path = data.data
								// 将图片回显
								this.img = real_path
								
							}
						});
				}
			});
步骤四:完成文章的添加

在我们导入函数后调用时,出现了以下的报错。

原因是:我们的后端代码是带参数的,所以我们需要给我们的函数传参。

      ----》   文章添加成功

我们的参数也可以在外面用变量包括,然后参数写对象就行了。

现在我们设置点击添加文章后返回首页就可以了。

但是我们的首页在tab-bar里面,所以,我们需要更改跳转方式:

因为我们的页面值更改了一次,所以我们可以选择:

将其处理好之后,我们就完成了文章的添加。


http://www.niftyadmin.cn/n/5860437.html

相关文章

【python】网页批量转PDF

安装wkhtmltopdf 网站&#xff1a;wkhtmltopdf wkhtmltopdf http://www.baidu.com/ D:website1.pdf 安装pdfkit库 pip install pdfkit 批量转换代码 import os import pdfkit path_wkthmltopdf rE:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe config pdfkit.configu…

Nginx WebSocket 长连接及数据容量配置

WebSocket 协议是实现实时通信的关键技术。相比于传统的 HTTP 请求-响应模式&#xff0c;WebSocket 提供了双向、持久化的通信方式。Nginx 作为一个高性能的反向代理服务器&#xff0c;可以非常有效地处理 WebSocket 连接&#xff0c;但要正确处理 WebSocket 长连接和传输大数据…

云计算如何解决延迟问题?

在云计算中&#xff0c;延迟&#xff08;latency&#xff09;指的是从请求发出到收到响应之间的时间间隔。延迟过高可能会严重影响用户体验&#xff0c;特别是在需要实时响应的应用中&#xff0c;如在线游戏、视频流、金融交易等。云计算服务如何解决延迟问题&#xff0c;通常依…

第四章:高级特性与最佳实践 - 第四节 - Tailwind CSS CSS 提取和打包优化

在现代前端工程中&#xff0c;CSS 的提取和打包优化对于项目性能至关重要。本节将详细介绍如何在使用 Tailwind CSS 的项目中实现 CSS 的高效提取和打包优化。 CSS 提取策略 MiniCssExtractPlugin 配置 // webpack.config.js const MiniCssExtractPlugin require(mini-css-…

常用电脑,护眼软件推荐 f.lux 3400K | 撰写论文 paper

常用电脑&#xff1f;平均每天用 5 个小时&#xff1f;你就要考虑用一个护眼软件了&#xff0c;对皮肤也好。因为电脑屏幕有辐射&#xff0c;比如蓝光。 f.lux 作为一款专业护眼软件&#xff0c;值得使用。之前用了三年的 Iris Pro&#xff0c;现在 f.lux 做的更好了。 使用…

数仓搭建(hive):DWB层(基础数据层)

维度退化: 通过减少表的数量和提高数据的冗余来优化查询性能。 在维度退化中&#xff0c;相关的维度数据被合并到一个宽表中&#xff0c;减少了查询时需要进行的表连接操作。例如&#xff0c;在销售数据仓库中&#xff0c;客户信息、产品信息和时间信息等维度可能会被合并到一…

分布式文本多语言翻译存储平台

分布式文本多语言翻译存储平台 地址&#xff1a; Gitee&#xff1a;https://gitee.com/dreamPointer/zza-translation/blob/master/README.md 一、提供服务 分布式文本翻译服务&#xff0c;长文本翻译支持流式回调&#xff08;todo&#xff09;分布式文本多语言翻译结果存储服…

Elasticsearch 自动补全搜索 - autocomplete

作者&#xff1a;来自 Elastic Amit Khandelwal 探索处理自动完成的不同方法&#xff0c;从基础到高级&#xff0c;包括输入时搜索、查询时间、完成建议器和索引时间。 在本文中&#xff0c;我们将介绍如何避免严重的性能错误、Elasticsearch 默认解决方案为何不适用以及重要的…