1、前言
之前做了个恋爱话术微信小程序,满足了日常聊天的须要,实现高情商的恋爱聊天。最近也实现了话术库的优化更新,新增30万条话术数据,同时应用了分词技术,匹配更欠缺。
但最近忽然发现,每天早上给女朋友发一段柔美情话能够让她开心一整天,但无奈本人的语言程度的确无限,不能顺手拈来,着实让人有点不爽。
不过方法总比艰难多,作为高情商的程序猿,来源于日常生活的需要往往是咱们最大的能源,必须盘他,所以想着在之前的恋爱话术小程序上在加一个每日情话举荐的性能。
心愿这个程序对其余独身或者恋爱中的兄弟们有所帮忙,也心愿兄弟们关注加三连反对一波哈~~~
2、举荐接口简介
==辣鸡服务器,兄弟们轻点调哈==
浪漫举荐情话凋谢接口
接口地址:https://yin-feng.top/open/getRecommendLove/open/getRecommendLove
申请形式:POST
申请数据类型:application/json
响应数据类型:*/*
申请参数:
{}
响应参数:
| 参数名称 | 参数阐明 | 类型 | schema |
| ——– | ——– | —– |—– |
|content|内容|string||
|id|id|integer(int64)|integer(int64)|
|score|分数|integer(int32)|integer(int32)|
|title|题目|string||
响应示例:
[
{
"content": "",
"id": 0,
"score": 0,
"title": ""
}
]
3、前端页面开发
老样子,咱们还是应用uniapp框架来开发,uniapp的介绍就不多说了哈。
3.1 配置pages.json文件
咱们这次打算配两个菜单,包含浪漫情话举荐和话术搜寻。次要在pages.json外面就行配置。
==pages.json== 文件用来对 uni-app 进行全局配置,决定页面文件的门路、窗口款式、原生的导航栏、底部的原生tabbar 等。它相似微信小程序中app.json的页面治理局部。
在 ==pages.json== 中提供 tabBar 配置,不仅仅是为了不便疾速开发导航,更重要的是在App和小程序端晋升性能。在这两个平台,底层原生引擎在启动时无需期待js引擎初始化,即可间接读取 pages.json 中配置的 tabBar 信息,渲染原生tab。
官网文档参考tabBar
特地留神
- 当设置 position 为 top 时,将不会显示 icon
- tabBar 中的 list 是一个数组,只能配置起码2个、最多5个 tab,tab 按数组的程序排序。
- tabbar 切换第一次加载时可能渲染不及时,能够在每个tabbar页面的onLoad生命周期里先弹出一个期待雪花(hello uni-app应用了此形式)
- tabbar 的页面展示过一次后就保留在内存中,再次切换 tabbar 页面,只会触发每个页面的onShow,不会再触发onLoad。
- 顶部的 tabbar 目前仅微信小程序上反对。须要用到顶部选项卡的话,倡议不应用 tabbar 的顶部设置,而是本人做顶部选项卡。
新增浪漫情话页面配置
{
"path": "pages/recommend/recommend",
"style": {
"navigationBarTitleText": "浪漫情话",
"backgroundColor": "#eeeeee",
"enablePullDownRefresh": false
}
}
增加两个tab标签
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#0055ff",
"borderStyle": "black",
"backgroundColor": "#ffffe1",
"height":"60px",
"fontSize":"18px",
"list": [
{
"pagePath": "pages/recommend/recommend",
"iconPath": "static/imgs/love1.png",
"selectedIconPath": "static/imgs/love2.png",
"text": "浪漫情话"
},
{
"pagePath": "pages/index/index",
"iconPath": "static/imgs/爱心1.png",
"selectedIconPath": "static/imgs/爱心2.png",
"text": "话术搜寻"
}
]
}
残缺的page.json文件
{
"pages": [ //pages数组中第一项示意利用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/recommend/recommend",
"style": {
"navigationBarTitleText": "浪漫情话",
"backgroundColor": "#eeeeee",
"enablePullDownRefresh": false
}
},
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "恋爱话术",
"backgroundColor": "#eeeeee",
"enablePullDownRefresh": false
}
}, {
"path": "component/WebView/WebView",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
}
],
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#0055ff",
"borderStyle": "black",
"backgroundColor": "#ffffe1",
"height":"60px",
"fontSize":"18px",
"list": [
{
"pagePath": "pages/recommend/recommend",
"iconPath": "static/imgs/love1.png",
"selectedIconPath": "static/imgs/love2.png",
"text": "浪漫情话"
},
{
"pagePath": "pages/index/index",
"iconPath": "static/imgs/爱心1.png",
"selectedIconPath": "static/imgs/爱心2.png",
"text": "话术搜寻"
}
]
},
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "恋爱话术",
"navigationBarBackgroundColor": "#ffffe1",
"backgroundColor": "#f5ffff"
}
}
3.2 封装api接口
次要在==http.api.js==外面配置,这个文件之前也蕴含了咱们的话术搜寻接口
import service from './http.interceptor.js'
const api = {
// 话术搜寻
getLoveChat: params => service.post('/open/getLoveChat', params),
getBanner: () => service.post('/open/getBanner'),
// 浪漫情话举荐
getRecommendLove: () => service.post('/open/getRecommendLove'),
loveScore: params => service.post('/open/loveScore', params),
}
export default api
3.3 编写浪漫情话页面
咱们还是应用vue3加uniapp的语法进行页面开发,同时为了使页面更柔美,封装一个瀑布流组件进行渲染数据。下图就是咱们要实现的大抵成果
3.3.1 封装瀑布流组件
<template>
<view class="u-waterfall">
<view id="u-left-column" class="u-column">
<slot name="left" :leftList="leftList"></slot>
</view>
<view id="u-right-column" class="u-column">
<slot name="right" :rightList="rightList"></slot>
</view>
</view>
</template>
<script>
export default {
name: "waterfall",
props: {
value: {
// 瀑布流数据
type: Array,
required: true,
default: function() {
return [];
}
}
},
data() {
return {
leftList: [],
rightList: [],
tempList: []
}
},
watch: {
copyFlowList(nVal, oVal) {
this.tempList = this.cloneData(this.copyFlowList);
this.leftList = []
this.rightList = []
this.splitData();
}
},
mounted() {
this.tempList = this.cloneData(this.copyFlowList);
this.splitData();
},
computed: {
// 毁坏flowList变量的援用,否则watch的后果新旧值是一样的
copyFlowList() {
return this.cloneData(this.value);
}
},
methods: {
async splitData() {
if (!this.tempList.length) return;
let leftRect = await this.$uGetRect('#u-left-column');
let rightRect = await this.$uGetRect('#u-right-column');
// 如果右边小于或等于左边,就增加到右边,否则增加到左边
let item = this.tempList[0];
// 解决屡次疾速上拉后,可能数据会乱的问题,因为通过下面的两个await节点查问阻塞肯定工夫,加上前面的定时器烦扰
// 数组可能变成[],导致此item值可能为undefined
if (!item) return;
if (leftRect.height < rightRect.height) {
this.leftList.push(item);
} else if (leftRect.height > rightRect.height) {
this.rightList.push(item);
} else {
// 这里是为了保障第一和第二张增加时,左右都能有内容
// 因为增加第一张,理论队列的高度可能还是0,这时须要依据队列元素长度判断下一个该放哪边
if (this.leftList.length <= this.rightList.length) {
this.leftList.push(item);
} else {
this.rightList.push(item);
}
}
// 移除长期列表的第一项
this.tempList.splice(0, 1);
// 如果长期数组还有数据,持续循环
if (this.tempList.length) {
this.splitData();
} else {
// 在这里模仿触发 咱们定义的全局事件 实现数据通信的目标
let height = (leftRect.height > rightRect.height ? leftRect.height : rightRect.height) + 120
uni.$emit('swiperHeightChange', height + 'px')
}
},
// 复制而不是援用对象和数组
cloneData(data) {
return JSON.parse(JSON.stringify(data));
},
}
}
</script>
<style lang="scss" scoped>
@mixin vue-flex($direction: row) {
/* #ifndef APP-NVUE */
display: flex;
flex-direction: $direction;
/* #endif */
}
.u-waterfall {
@include vue-flex;
flex-direction: row;
align-items: flex-start;
}
.u-column {
@include vue-flex;
flex: 1;
flex-direction: column;
height: auto;
}
.u-image {
width: 100%;
}
</style>
3.3.2 template代码编写
这里在引入瀑布流组件之后可间接在html外面应用
<template>
<view>
<view class="change" @click="changeContent">
没找到想要的?连忙点击这里
<text class="change-btn">换一批</text>
<view class="card">
点击下方卡片可间接复制
</view>
</view>
<waterfall :value="dataList">
<template v-slot:left="left">
<view v-for="item in left.leftList" :key="item.id" class="left-content" @click="copy(item)">
<view class="item">
{{item.content}}
</view>
</view>
</template>
<template v-slot:right="right">
<view v-for="item in right.rightList" :key="item.id" class="right-content" @click="copy(item)">
<view class="item">
{{item.content}}
</view>
</view>
</template>
</waterfall>
</view>
</template>
3.3.3 js外围办法编写
要害代码也不多,次要是一些申请数据的办法和响应式变量的定义。
<script>
import {
toRefs,
reactive,
onMounted
} from 'vue'
import waterfall from '../../component/waterfall/index.vue'
import api from '../../axios/http.api.js'
export default {
name: 'content',
components: {
waterfall
},
setup() {
const state = reactive({
dataList: [],
loading: false,
})
const methods = reactive({
getRecommendLove: async () => {
state.loading = true
let res = await api.getRecommendLove()
state.loading = false
if (res.code) {
uni.showToast({
title: res.msg,
icon: 'none',
position: 'top'
})
}
state.dataList = res.data
},
copy(item) {
// 复制话术到剪切板
uni.setClipboardData({
data: item.content
})
methods.score(item.id)
},
// 换一批
changeContent() {
methods.getRecommendLove()
},
// 打分
async score(id) {
let res = await api.loveScore({
id
})
if (res.code) {
uni.showToast({
title: res.msg,
icon: 'none',
position: 'top'
})
}
}
})
onMounted(() => {
methods.getRecommendLove()
// 分享菜单
wx.showShareMenu({
withShareTicket: true,
menus: ['shareAppMessage', 'shareTimeline']
})
})
return {
...toRefs(state),
...toRefs(methods)
}
}
}
</script>
3.3.4 css款式代码编写
咱们毕竟不是业余的前端,所以款式就轻易应酬一下就行,兄弟们不要介意哈
<style lang="less" scoped>
.change {
width: 100%;
height: 120px;
border-bottom: 2px #aaaaff solid;
border-radius: 0 0 50px 50px;
background-size: 100% 100%;
opacity: 0.8;
padding-top: 45px;
text-align: center;
font-size: 20px;
color: #000000;
background-image: url(../../static/imgs/img4.png);
.change-btn {
display: inline-block;
padding: 2px;
color: red;
}
.card {
padding-top: 12px;
font-size: 13px;
}
}
.left-content {
margin: 15px 5px 15px 10px;
padding: 8px;
border-radius: 6px;
background: #aaffff linear-gradient(44deg, #aaffff 0%, #F4F8FF 100%);
font-size: 16px;
letter-spacing: 5px;
.item {
margin-bottom: 10px;
}
}
.right-content {
margin: 15px 10px 15px 5px;
padding: 8px;
border-radius: 6px;
background: #aaffff linear-gradient(44deg, #aaffff 0%, #F4F8FF 100%);
font-size: 16px;
letter-spacing: 5px;
.item {
margin-bottom: 10px;
}
}
</style>
4、公布微信小程序
公布流程参考这篇博客恋爱话术微信小程序
兄弟们能够扫描上面的太阳码进行体验哈
5、总结
源码地址在这哈,会放弃始终开源,心愿兄弟们多多反对,==下了源码的老铁麻烦点个star哈==
// 下了源码的老铁麻烦点个star哈
https://gitee.com/yinfeng-code/love-chat-wx.git
肝文不易,心愿对其余独身或者恋爱中的兄弟们有所帮忙,也心愿兄弟们==关注加三连==反对一波哈
发表回复