从0到1,完成恋爱话术微信小程序的开发到发布(开源,看了就懂~,2万字真香警告)

1、前言

在大家眼中,有没有觉得女神就像冰山美人一样?在聊天中对你是很高冷,或者是忽冷忽热,爱理不理。很多男生面对这个问题都束手无策,或者女神不理你时,又急着发短消息过去了,结果女神根本不理睬你。那怎么办呢?

其实女神也一样,是情绪动物,她的情感由情绪控制着,不会像男人那样理性、讲逻辑。你说服不了她喜欢你,但通过调动她的情绪,你可以让她喜欢你。所以会一些调情幽默的恋爱话术尤为重要,如果你能做到,让女人快乐,开怀大笑,有时候又会悲伤,让她的情绪为你所动,那么她对于你投入的情感会是有很多的。

2、技术栈

  1. uniApp
  2. vue3
  3. 微信开发者工具
  4. Hbuilder X
  5. axios
  6. uView ui框架

3、uniApp简介

uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台。
uni-app在手,做啥都不愁。即使不跨端,uni-app也是更好的小程序开发框架(详见)、更好的App跨平台框架、更方便的H5开发框架。不管领导安排什么样的项目,你都可以快速交付,不需要转换开发思维、不需要更改开发习惯。

我们这里主要将一套代码分别部署到h5和微信小程序上。

4、vue3简介

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统,只关注视图层,易于上手。所有东西都是响应式的。

4.1 vue3的优势

  1. 响应式系统提升
  2. 虚拟DOM重写
  3. 更快,性能比Vue2快1.2~2倍(diff方法优化、静态提升、时间侦听器缓存、ssr渲染)
  4. 更小,按需编译,体积比Vue2更小
  5. 组合API,加强API设计一致性,实现逻辑模块化和重用
  6. 加强TypeScript支持
  7. 暴露了自定义渲染API
  8. 提高自身可维护性

5、微信开发者工具简介

以下来自微信官方文档:

为了帮助开发者简单和高效地开发和调试微信小程序,我们在原有的公众号网页调试工具的基础上,推出了全新的 微信开发者工具,集成了公众号网页调试和小程序调试两种开发模式。
使用公众号网页调试,开发者可以调试微信网页授权和微信JS-SDK 详情
使用小程序调试,开发者可以完成小程序的 API 和页面的开发调试、代码查看和编辑、小程序预览和发布等功能。
为了更好的开发体验,我们从视觉、交互、性能等方面对开发者工具进行升级,推出了 1.0 版本 下载。使用过程中若有问题或建议,可前往 #微信开发者工具社区 发帖反馈交流。

在这里插入图片描述

6、Hbuilder X

HBuilderX,H是HTML的首字母,Builder是构造者,X是HBuilder的下一代版本。我们也简称HX。 HX是轻如编辑器、强如IDE的合体版本。

让我们简单了解下HX的特点

  1. 轻巧 仅10余M的绿色发行包(不含插件)
  2. 极速 不管是启动速度、大文档打开速度、编码提示,都极速响应 C++的架构性能远超Java或Electron架构
  3. vue开发强化 HX对vue做了大量优化投入,开发体验远超其他开发工具 详见
  4. 小程序支持 国外开发工具没有对中国的小程序开发优化,HX可新建uni-app 小程序等项目,为国人提供更高效工具
  5. markdown利器 HX是唯一一个新建文件默认类型是markdown的编辑器,也是对md支持最强的编辑器 HX为md强化了众多功能,请务必点击【菜单-帮助-markdown语法示例】,快速掌握md及HX的强化技巧!
  6. 清爽护眼 HX的界面比其他工具更清爽简洁,绿柔主题经过科学的脑疲劳测试,是最适合人眼长期观看的主题界面
  7. 强大的语法提示 HX是中国唯一一家拥有自主IDE语法分析引擎的公司,对前端语言提供准确的代码提示和转到定义(Alt+鼠标左键)
  8. 高效极客工具 更强大的多光标、智能双击...让字处理的效率大幅提升 详见,
  9. 更强的json支持 现代js开发中大量json结构的写法,HX提供了比其他工具更高效的操作

7、axios

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。

特性

  1. 从浏览器中创建 XMLHttpRequests
  2. 从 node.js 创建 http 请求
  3. 支持 Promise API
  4. 拦截请求和响应
  5. 转换请求数据和响应数据
  6. 取消请求
  7. 自动转换 JSON 数据
  8. 客户端支持防御 XSRF

8、uView ui框架

uView是uni-app生态专用的UI框架,uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码, 可发布到iOS、Android、H5、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉)等多个平台(引言自uni-app网)。

9、创建微信小程序项目

9.1 注册账号

在微信公众平台注册小程序,官网微信公众平台

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

按之前填的邮箱进去激活,然后完善相关信息
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

到此为止,我们的小程序算是注册完成

9.2 查看小程序AppID(小程序ID),后面项目提交代码需要用到

在这里插入图片描述

在这里插入图片描述

10、创建uniapp项目

10.1 在Hbuilder X新建一个uniapp项目

在这里插入图片描述

在这里插入图片描述

10.2 配置vue3语法

在这里插入图片描述

10.3 配置微信小程序appId

appId获取参考9.2步骤

在这里插入图片描述

10.4 安装axios依赖

npm i axios

在控制台执行以上代码

在这里插入图片描述

在这里插入图片描述

11、引入uView ui框架

11.1 导入uView插件

插件官网uView

在这里插入图片描述

11.2 main.js 引入 vk-uview-ui

import App from './App'

// #ifndef VUE3
import Vue from 'vue'
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
    ...App
})
app.$mount()
// #endif

// #ifdef VUE3
import {
    createSSRApp
} from 'vue'
// 引入 uView UI
import uView from './uni_modules/vk-uview-ui';
export function createApp() {
    const app = createSSRApp(App)
    // 使用 uView UI
    app.use(uView)
    return {
        app
    }
}
// #endif

11.3 App.vue 引入基础样式(注意style标签需声明scss属性支持)

<script>
    export default {
        onLaunch: function() {
            console.log('App Launch')
        },
        onShow: function() {
            console.log('App Show')
        },
        onHide: function() {
            console.log('App Hide')
        }
    }
</script>

<style lang="scss">

    /* 引入uview */
    @import "./uni_modules/vk-uview-ui/index.scss";

    /*每个页面公共css */
    html,
    body {
        width: 100%;
        height: 100%;
    }
</style>

在这里插入图片描述

11.4 uni.scss 引入全局 scss 变量文件

/**
 * 这里是uni-app内置的常用样式变量
 *
 * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
 * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
 *
 */

/**
 * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
 *
 * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
 */

/* 引入uview */
@import "@/uni_modules/vk-uview-ui/theme.scss";
/* 颜色变量 */

/* 行为相关颜色 */
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;

/* 文字基本颜色 */
$uni-text-color:#333;//基本色
$uni-text-color-inverse:#fff;//反色
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
$uni-text-color-placeholder: #808080;
$uni-text-color-disable:#c0c0c0;

/* 背景颜色 */
$uni-bg-color:#ffffff;
$uni-bg-color-grey:#f8f8f8;
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色

/* 边框颜色 */
$uni-border-color:#c8c7cc;

/* 尺寸变量 */

/* 文字尺寸 */
$uni-font-size-sm:12px;
$uni-font-size-base:14px;
$uni-font-size-lg:16;

/* 图片尺寸 */
$uni-img-size-sm:20px;
$uni-img-size-base:26px;
$uni-img-size-lg:40px;

/* Border Radius */
$uni-border-radius-sm: 2px;
$uni-border-radius-base: 3px;
$uni-border-radius-lg: 6px;
$uni-border-radius-circle: 50%;

/* 水平间距 */
$uni-spacing-row-sm: 5px;
$uni-spacing-row-base: 10px;
$uni-spacing-row-lg: 15px;

/* 垂直间距 */
$uni-spacing-col-sm: 4px;
$uni-spacing-col-base: 8px;
$uni-spacing-col-lg: 12px;

/* 透明度 */
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度

/* 文章场景相关 */
$uni-color-title: #2C405A; // 文章标题颜色
$uni-font-size-title:20px;
$uni-color-subtitle: #555555; // 二级标题颜色
$uni-font-size-subtitle:26px;
$uni-color-paragraph: #3F536E; // 文章段落颜色
$uni-font-size-paragraph:15px;

在这里插入图片描述

12、配置axios

12.1 创建axios适配器,适用于uniapp

import axios from 'axios';
import settle from 'axios/lib/core/settle';
import buildURL from 'axios/lib/helpers/buildURL';

// axios适配器
axios.defaults.adapter = function(config) { 
    return new Promise((resolve, reject) => {
        uni.request({
            method: config.method.toUpperCase(),
            url: config.baseURL + buildURL(config.url, config.params, config.paramsSerializer),
            header: config.headers,
            data: config.data,
            dataType: config.dataType,
            responseType: config.responseType,
            sslVerify: config.sslVerify,
            complete: function complete(response) {
                response = {
                    data: response.data,
                    status: response.statusCode,
                    errMsg: response.errMsg,
                    header: response.header,
                    config: config
                };

                settle(resolve, reject, response);
            }
        })
    })
}

export default axios
在这里插入图片描述

12.2 创建axios拦截器

//封装axios拦截器
import axios from './axios-adaptor.js'

const service = axios.create({
    baseURL: 'https://yin-feng.top',
    timeout: 5000, // request timeout
    crossDomain: true,
    headers: {
        'Content-Type': 'application/json; charset=utf-8'
    }
})
// 添加请求拦截器 
service.interceptors.request.use(
    config => {
        config.headers['source'] = 'wx'
        return config
    },
    error => {
        return Promise.reject(error)
    }
)
// 添加响应拦截器 
service.interceptors.response.use(
    response =>
    response.data,
    error => {
        return Promise.resolve(error)
    }
)
export default service

在这里插入图片描述

12.3 封装后端api接口

import service from './http.interceptor.js'

// 封装后端api接口
const api = {
    // 话术获取
    getLoveChat: params => service.post('/open/getLoveChat', params),
    // 获取轮播图
    getBanner: () => service.post('/open/getBanner')
}

export default api

在这里插入图片描述

12.4 后端接口文档

参考这篇博客撩妹神器恋爱话术库,主要用到恋爱话术获取接口。

13、编写核心页面

13.1 template html代码编写

<template>
    <view class="content">
        <u-swiper :list="bannerList" :effect3d="true" @click="clickBanner" height="245" bg-color="#e7f6ff"
            img-mode="aspectFit">
        </u-swiper>
        <view class="search">
            <u-search bg-color="#fff" v-model="searchValue" shape="round" placeholder="请输入女生说的话" :clearabled="true"
                :show-action="true" @search="getLoveChat" @custom="getLoveChat" @clear="clear"
                :action-style="searchStyle" />
        </view>
        <view class="tag" v-if="!list.length">
            <u-tag text="恋爱话术" shape="circle" @click="tagClick('恋爱话术')" />
            <u-tag text="土味情话" shape="circle" color="#ff0000" @click="tagClick('土味情话')" />
            <u-tag text="情侣助手" shape="circle" @click="tagClick('情侣助手')" />
        </view>
        <view class="list">
            <view v-for="item in list" :key="item.female" class="item">
                <view class="title">
                    <u-icon :style="iconStyle" size="1.5rem" name="/static/imgs/question.png" />:
                    <text class="female">{{item.female}}</text>
                </view>
                <view class="answer" v-for="answer in item.answers" :key="answer.answer">
                    <u-icon :style="iconStyle" v-if="answer.gender==1" size="1.5rem" name="/static/imgs/man.png" />
                    <u-icon :style="iconStyle" v-if="answer.gender==2" size="1.5rem" name="/static/imgs/woman.png" />
                    <text class="answerItem">: {{answer.answer}}</text>
                    <u-button class="answerBtn" type="primary" plain size="mini" @click="copy(answer)">复制</u-button>
                </view>
            </view>
        </view>
    </view>
</template>

13.2 核心方法编写,主要使用vue3语法

<script>
    import {
        toRefs,
        reactive,
        onMounted
    } from 'vue'
    import api from '../../axios/http.api.js'
    export default {
        name: 'index',
        setup() {
            const state = reactive({
                // 输入框的值
                searchValue: '',
                // 输入框样式
                searchStyle: {
                    color: '#ff0000',
                    border: '1px solid #DD6161',
                    fontWeight: '500',
                    padding: '1px',
                    borderRadius: '15%',
                },
                // 图标样式
                iconStyle: {
                    position: 'relative',
                    top: '6px'
                },
                // 话术列表
                list: [],
                loading: false,
                // banner图片数组
                bannerList: [],
            })
            const methods = reactive({
                // 获取话术列表
                getLoveChat: async () => {
                    state.loading = true
                    let res = await api.getLoveChat({
                        "count": 16,
                        "key": state.searchValue,
                        "page": 1
                    })
                    state.loading = false
                    if (!res.code) {

                    }
                    state.list = res.data
                    console.log(res)
                },
                // 复制话术到剪切板
                copy(item) {
                    uni.setClipboardData({
                        data: item.answer
                    })
                },
                // 标签点击
                tagClick(value) {
                    state.searchValue = value
                    methods.getLoveChat()
                },
                // 轮播图点击
                clickBanner(index) {
                    // 跳转到内部窗口并且传递链接
                    uni.navigateTo({
                        url: `/component/WebView/WebView?url=${state.bannerList[index].hrefUrl}`
                    })
                },
                // 清空输入框
                clear() {
                    state.searchValue = ''
                    state.list = []
                }

            })
            onMounted(async () => {
                // 获取剪切板内容
                uni.getClipboardData({
                    success: function(res) {
                        state.searchValue = res.data;
                    }
                });
                // 获取banner
                let res = await api.getBanner()
                if (!res.code) {
                    return
                }
                state.bannerList = res.data.map(item => {
                    return {
                        image: item.imgUrl,
                        ...item,
                    }
                })
                
                // 只在微信小程序才显示分享菜单
                // #ifdef MP-WEIXIN
                wx.showShareMenu({
                    withShareTicket: true,
                    menus: ['shareAppMessage', 'shareTimeline']
                })
                // #endif

            })
            return {
                ...toRefs(state),
                ...toRefs(methods)
            }
        }
    }
</script>

13.3 css样式代码编写

<style lang="less" scoped>
    .content {
        background-color: #f5ffff;
        padding: 10px 18px 0;
        font-size: 15px;
        font-family: cursive;
        height: 100%;

        .search {
            padding-top: 18px;
        }

        .tag {
            padding: 10px;
            display: flex;
            justify-content: space-between;
        }

        .list {
            height: calc(100vh - 230px);
            overflow-y: auto;
            margin-top: 10px;
            padding-top: 5px;

            .item {
                box-shadow: 0 2px 6px 2px rgba(255, 0, 0, 0.3);
                padding: 8px 0 10px;
                line-height: 27px;
                background-color: #ffebeb;
                margin-bottom: 15px;
                border-radius: 8px;
                letter-spacing: 2px;

                .title {
                    padding-left: 10px;

                    .female {
                        font-weight: 500;
                        color: #DD6161;
                        font-size: 19px;
                    }
                }

                .answer {
                    position: relative;
                    padding: 0 50px 0 10px;

                    .answerBtn {
                        position: absolute;
                        bottom: 0;
                        right: 5px;
                    }
                }
            }
        }
    }
</style>

14、封装webView,用于轮播图页面跳转

<template>
    <view>
        <web-view :src="url"></web-view>
    </view>
</template>

<script>
    import {
        toRefs,
        reactive,
        onMounted
    } from 'vue'
    export default {
        name: 'web',
        data() {
            return {
                url: ''
            }
        },
        onLoad(e) {
            // 获取传递过来的链接
            this.url = e.url
        }
    }
</script>

<style>

</style>

在这里插入图片描述

15、pages.json配置页面路由

15.1 配置核心页面路由

{
    "path": "pages/index/index",
    "style": {
        "navigationBarTitleText": "恋爱话术",
        "backgroundColor": "#eeeeee",
        "enablePullDownRefresh": false
    }
}

15.2 配置webView路由

{
    "path" : "component/WebView/WebView",
    "style" :                                                                                    
    {
        "navigationBarTitleText": "",
        "enablePullDownRefresh": false
    }
    
}

15.3 完整路由配置如下

在这里插入图片描述

16、微信小程序测试

16.1 编译并启动

在这里插入图片描述

在这里插入图片描述

16.2 在微信开发者工具测试下功能

在这里插入图片描述

17、h5页面测试

17.1 编译并启动h5页面

在这里插入图片描述

17.2 在浏览器点击测试下功能,F12打开调试模式

在这里插入图片描述

18、发布微信小程序

18.1 编译代码

在这里插入图片描述

在这里插入图片描述

18.2 微信开发者工具上传代码

在这里插入图片描述

18.3 小程序后台提交审核

在这里插入图片描述

在这里插入图片描述

18.4 审核过后即可在这里点击发布

在这里插入图片描述

在这里插入图片描述

18.4 配置小程序合法域名

在这里插入图片描述

在这里插入图片描述

19、发布h5页面进行托管

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

兄弟们可以打开以下链接体验一下

https://static-d3218181-4117-4af2-8b08-5fa0b2dc6760.bspapp.com

20、源码地址

// 下了源码的老铁麻烦点个star哈
https://gitee.com/yinfeng-code/love-chat-wx.git

肝文不易,老铁们==三连一波==支持下吧,谢谢大家了~
下了源码的老铁麻烦点个star哈

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容