乐趣区

关于javascript:微信小程序实战用vue3实现每日浪漫情话推荐

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

特地留神

  1. 当设置 position 为 top 时,将不会显示 icon
  2. tabBar 中的 list 是一个数组,只能配置起码 2 个、最多 5 个 tab,tab 按数组的程序排序。
  3. tabbar 切换第一次加载时可能渲染不及时,能够在每个 tabbar 页面的 onLoad 生命周期里先弹出一个期待雪花(hello uni-app 应用了此形式)
  4. tabbar 的页面展示过一次后就保留在内存中,再次切换 tabbar 页面,只会触发每个页面的 onShow,不会再触发 onLoad。
  5. 顶部的 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

肝文不易,心愿对其余独身或者恋爱中的兄弟们有所帮忙,也心愿兄弟们 == 关注加三连 == 反对一波哈

退出移动版