[uni-app+unicloud]诗歌起名小程序开发到上线

830 阅读18分钟

起名小程序

这是款uni-app + unicloud上线的起名小程序(诗歌起名)

1通过古诗词匹配生成姓名

1.1创建项目

1.2uni-app前端配置

组件选择

单选框 radio

输入框 input

按钮 button

    <view class="content">        <view class="radio-list">            <radio-group class="radio-group" @change="radioChange">                <label class="radio" v-for="(item, index) in array" :key="index">                    <view style="display: flex; flex-wrap: nowrap;">                        <radio :value="item" color="#000000" :checked="index === current" />                        <view>{{ item }}</view>                    </view>                </label>            </radio-group>        </view>​        <view class="form-item">            <image class="img" src="../../static/icon_search.png"></image>            <input confirm-type="search" v-model="userName" focus placeholder="输入姓氏" />​            <button class="button" type="primary" size="mini" @click="subName">起名</button>        </view>                <view class="name-list">            <view class="name-container" v-for="item in nameList" :key="item._id">                <view class="name-info">                    {{userName}}{{item.name}}                </view>                <view class="sentence">[{{item.sentence}}]</view>                <view class="name-other">                    <view>{{item.book}} ● {{item.title}}</view>                    <view>[{{item.dynasty}}] {{item.author}}</view>                </view>            </view>                    </view>

插入数据

array: ['唐诗', '宋词', '诗经', '楚辞', '乐府', '古诗词'],

Vue event.target.value( ) 获取当前文本框的值(由事件触发时)

情景描述:假设当前有一个文本框,当我输入内容之后,回车或者点击一个按钮,

             我们在这个input 上或者这个按钮上绑定事件,触发事件之后执行相应的methods中​             的处理函数,在methods中的函数中是如何获取文本框中的值的呢?

1.3 起名 form组件

前端逻辑

不能为空

不能超过两位数

不能为汉字以外的字母\数字

**Object.keys()** 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致

es5 非对象 -> typeError

es6 转 对象- > 身可枚举属性组成的数组

判断汉字正则

/^([\u4E00-\u9FA5])*$/

1.4unicloud端getName云函数

1.5正则表达式教程

大家好,我是王大合

什么是正则表达式?

正则表达式是对字符串操作的一种逻辑公式,

就是用事先定义好的一些特定字符、及这些特定字符的组合,

组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑

为什么使用正则?

就是在表单验证时,准确的判断一个字符串是不是某种固定格式。比如邮箱的验证、手机号的验证等。目的是避免恶意用户的乱输入,使表单的收集是我们想要的格式!

正则表达式语法支持情况非常广

正则表达式用在哪些地方?

一、开发常用,特殊需求表达式

  1. Email地址:^\w+([-+.]\w+)

    @\w+([-.]\w+)

    .\w+([-.]\w+)*$

  2. 域名:a-zA-Z0-9{0,62}(/.a-zA-Z0-9{0,62})+/.?

  3. InternetURL:[a-zA-z]+://\s* 或 ^http://([\w-]+.)+[\w-]+(/[\w-./?%&=]*)?$

  4. 手机号码:^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$

  5. 电话号码("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX- XXXXXXXX"、"XXXXXXX"和"XXXXXXXX):^((\d{3,4}-)|\d{3.4}-)?\d{7,8}$

  6. 国内电话号码(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7}

  7. 身份证号(15位、18位数字):^\d{15}|\d{18}$

  8. 短身份证号码(数字、字母x结尾):^([0-9]){7,18}(x|X)? 或 ^\\d{8,18}|\[0-9x\]{8,18}|\[0-9X\]{8,18}?

  9. 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^a-zA-Z{4,15}$

  10. 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):^[a-zA-Z]\w{5,17}$

  11. 强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间):^(?=.

\\d)(?=.
\[a-z\])(?=.\*\[A-Z\]).{8,10}$

12. 日期格式:^\d{4}-\d{1,2}-\d{1,2}

  1. 一年的12个月(01~09和1~12):^(0?[1-9]|1[0-2])$

  2. 一个月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$

  3. xml文件:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\.x|X[l|L]$

  4. 中文字符的正则表达式:[\u4e00-\u9fa5]

  5. 双字节字符:\x00-\xff (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))

  6. 空白行的正则表达式:\n\s*\r (可以用来删除空白行)

  7. HTML标记的正则表达式:<(\S

?)\>
\>.

?</\\1>|<.

? /> (网上流传的版本太糟糕,上面这个也仅仅能部分,对于复杂的嵌套标记依旧无能为力)

20. 首尾空白字符的正则表达式:^\s

|\\s

$或(^\\s

)|(\\s

$) (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)

21. 腾讯QQ号:1-9{4,} (腾讯QQ号从10000开始)

  1. 中国邮政编码:[1-9]\d{5}(?!\d) (中国邮政编码为6位数字)

  2. IP地址:\d+.\d+.\d+.\d+ (提取IP地址时有用)

  3. IP地址:((?:(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d))

二、校验字符的表达式

  1. 汉字:^[\u4e00-\u9fa5]{0,}$

  2. 英文和数字:^[A-Za-z0-9]+ 或 ^\[A-Za-z0-9\]{4,40}

  3. 长度为3-20的所有字符:^.{3,20}$

  4. 由26个英文字母组成的字符串:^[A-Za-z]+$

  5. 由26个大写英文字母组成的字符串:^[A-Z]+$

  6. 由26个小写英文字母组成的字符串:^[a-z]+$

  7. 由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$

  8. 由数字、26个英文字母或者下划线组成的字符串:^\w+ 或 ^\\w{3,20}

  9. 中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$

  10. 中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+ 或 ^\[\\u4E00-\\u9FA5A-Za-z0-9\]{2,20}

  11. 可以输入含有^%&',;=?"等字符:"等字符:%&',;=?\x22+ 12 禁止输入含有的字符:\x22+

三、校验数字的表达式

  1. 数字: ^[0-9]*$

  2. n位的数字:^\d{n}$

  3. 至少n位的数字:^\d{n,}$

  4. m-n位的数字:^\d{m,n}$

  5. 零和非零开头的数字:^(0|1-9*)$

  6. 非零开头的最多带两位小数的数字:^(1-9*)+(.[0-9]{1,2})?$

  7. 带1-2位小数的正数或负数:^(-)?\d+(.\d{1,2})?$

  8. 正数、负数、和小数:^(-|+)?\d+(.\d+)?$

  9. 有两位小数的正实数:^[0-9]+(.[0-9]{2})?$

  10. 有1~3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$

  11. 非零的正整数:^[1-9]\d

$ 或 ^([1-9](#)
){1,3}$ 或 ^+?[1-9](#)\*$

12. 非零的负整数:^-1-90-9"

$ 或 ^-\[1-9\]\\d

$

13. 非负整数:^\d+ 或 ^\[1-9\]\\d\*|0

  1. 非正整数:^-[1-9]\d*|0((d+)(0+)) 或 ^((-\\d+)|(0+))

  2. 非负浮点数:^\d+(.\d+)?$ 或 ^[1-9]\d

.\\d
|0.\\d

\[1-9\]\\d

|0?.0+|0$

16. 非正浮点数:^((-\d+(.\d+)?)|(0+(.0+)?))$ 或 ^(-([1-9]\d

.\\d

|0.\\d

\[1-9\]\\d

))|0?.0+|0$

17. 正浮点数:^[1-9]\d

.\\d

|0.\\d

\[1-9\]\\d

$ 或 ^((\[0-9\]+.\[0-9\]

[1-9](#)

)|(\[0-9\]

[1-9](#)

.\[0-9\]+)|(\[0-9\]

[1-9](#)

))$

18. 负浮点数:^-([1-9]\d

.\\d

|0.\\d

\[1-9\]\\d

)$ 或 ^(-((\[0-9\]+.\[0-9\]

[1-9](#)

)|(\[0-9\]

[1-9](#)

.\[0-9\]+)|(\[0-9\]

[1-9](#)

)))$

19. 浮点数:^(-?\d+)(.\d+)?$ 或 ^-?([1-9]\d

.\\d

|0.\\d

\[1-9\]\\d

|0?.0+|0)$

1.6正则匹配诗词

1先清洗数据

过程中...大量使用正则

                    const List = res.result.data                    const Result = []                                        List.forEach((item,index) => {                                                var object = {}                        object = item.content                        object = object.replace(/\s|<br>|<p>|<\/p>| |”|“/g, '')                        object = object.replace(/\(.+\)/g, '')                        object = object.replace(/!|。|?|;/g, object => `${object}|`)                        object = object.replace(/\|$/g, '')                        let arr = object.split('|');                            arr = arr.filter(item => item.length >= 2);                            const sentence = arr[this.randBetween(0, arr.length)];                        const cleanSentence = this.cleanPunctuation(sentence)                        const name = this.randCharFromStr(cleanSentence, 2)                        var str = {}                        str.sentence = sentence                        str.name = name                        str.title = item.title                        str.author = item.author ? item.author : '佚名'                        str.book = item.book                        str.dynasty = item.dynasty                        Result.push(str)                    })                    this.nameList = Result                })

2提前诗文和姓名关键字

// 选取诗文        randBetween(min, max) {           // [min,max)  max is not included           return min + Math.floor(Math.random() * (max - min));         },         // 清理标点符号         cleanPunctuation(str) {             const puncReg = /[<>《》!*\(\^\)\$%~!@#…&%¥—\+=、。,?;‘’“”:·`]/g;             return str.replace(puncReg, '');           },                     // 取两个字           randCharFromStr(str, num, ordered) {               if (typeof ordered === 'undefined') {                 ordered = true;               }               let randNumArr = this.genRandNumArr(str.length, num);               if (ordered) {                 randNumArr = randNumArr.sort((a, b) => a - b);               }               let res = '';               for (let i = 0; i < randNumArr.length; i++) {                 res += str.charAt(randNumArr[i]);               }               return res;             },              genRandNumArr(max, num) {              if (num > max) {                num = max;                console.log(`max=${max} num = ${num}`);                // throw new Error('too large num');              }              const orderedNum = [];              for (var i = 0; i < max; i++) {                orderedNum.push(i);              }              const res = [];              for (var i = 0; i < num; i++) {                const randIndex = this.randBetween(0, orderedNum.length);                const randNum = orderedNum[randIndex];                res.push(randNum);                orderedNum.splice(randIndex, 1);                // console.log('i=' + i + 'rand=' + rand, orderedNum);              }              return res;            },

3后前端数据

<view class="name-list">            <view class="name-container" v-for="item in nameList" :key="item._id">                <view class="name-info">                    {{userName}}{{item.name}}                </view>                <view class="sentence">[{{item.sentence}}]</view>                <view class="name-other">                    <view>{{item.book}} ● {{item.title}}</view>                    <view>[{{item.dynasty}}] {{item.author}}</view>                </view>            </view>                    </view>

4 美化样式

.name-list {    display: flex;    flex-direction: column;            .name-container {        margin: 10px 20px;        padding: 5px 5px;        background-color: #f1f1f1;        border: #333333 solid 1px;        .name-info {            font-size: 26px;            font-weight:bold        }        .sentence {            padding-top:5px;            padding-bottom: 5px;            padding-left: 30px;            display: flex;            flex-wrap: nowrap;        }        .name-other {                        pading:2px 2px                    }    }

1.7uni-app使用wxs模板

目标是改变 诗句参数中 name关键字的颜色

因为要使用indexOf匹配关键字,但是小程序是不支持indexOf函数

小程序原生的解决方案是创建一个wxs的模板文件,引入indexOf

这样就需要uni-app也要支持wxs,索性,目前uni-app已经支持wxs

所以小程序这边就可以继续玩下去,但是这样就要考虑uni-app在多端的兼容性

1我把获取到的数据,拆成单字的数组

str.sentence = sentence.split("")                        str.name = name.split("")

2因为无法引用indexOf,所以创建 wxs模板解决这个问题

<script module="tools" lang="wxs">    function fn(arr, value) {        if(arr.indexOf(value) < 0) {            return false;        } else {            return true;        }    }    module.exports = {        fn:fn    };</script>

3 使用v-for循环展示 诗句和姓名

<view class="name-info">                    <view>                        {{userName}}                    </view>                    <view  v-for="(name,index) in item.name" :key="index"                    >{{name}}</view>                </view>                <view class="sentence">                    <view>[</view>                    <view  v-for="(sentence,index) in item.sentence" :key="index"                    :class="tools.fn(item.name, sentence)?'active':'black'">{{sentence}}</view>                    <view>]</view>                </view>

4最后改变下样式即可

.name-list {    display: flex;    flex-direction: column;            .name-container {        margin: 10px 20px;        padding: 5px 5px;        background-color: #f1f1f1;        border: #333333 solid 1px;        .name-info {            font-size: 26px;            font-weight:bold;            display: flex;            flex-wrap: nowrap;        }        .sentence {            padding-top:5px;            padding-bottom: 5px;            padding-left: 30px;            display: flex;            flex-wrap: nowrap;            .active {                color: #007AFF;            }            .black {                color: #333333;            }        }                .name-other {                        pading:2px 2px                    }    }    }

1.8unicloud白名单配置

各家小程序平台,均要求在小程序管理后台配置小程序应用的联网服务器域名,否则无法联网。

使用uniCloud后,开发者将不再需要自己购买、备案域名,直接将uniCloud的域名填写在小程序管理后台即可。

根据下表,在小程序管理后台设置request合法域名、uploadFile合法域名(如没有上传文件业务,可不设置)。下表的域名均为阿里云或腾讯云自有域名,并非DCloud所属域名。

服务提供商

request合法域名

uploadFile合法域名

download合法域名|

阿里云

api.bspapp.com

bsppub.oss-cn-shanghai.aliyuncs.com

需要从云存储下载文件的时候才需要配置,不同服务空间域名不同,可以在web控制台查看文件详情里面看到

腾讯云

tcb-api.tencentcloudapi.com

cos.ap-shanghai.myqcloud.com

需要从云存储下载文件的时候才需要配置,不同服务空间域名不同,可以在web控制台查看文件详情里面看到

如果需要用uni.request请求云存储内的文件,需要将云存储域名(即上表中的download合法域名)配置到request合法域名内

小程序开发工具的真机预览功能,必须添加上述域名白名单,否则无法调用云函数。模拟器的PC端预览、真机调试不受此影响。

如果遇到正确配置了合法域名但是依然报url not in domain list,请尝试删除手机上的小程序、清理小程序所在的客户端缓存、重启对应的小程序开发工具后重试