HBuilderX

HBuilderX

极客开发工具
uni-app

uni-app

开发一次,多端覆盖
uniCloud

uniCloud

云开发平台
HTML5+

HTML5+

增强HTML5的功能体验
MUI

MUI

上万Star的前端框架

test

iOS12

test44444444444444444444444

test44444444444444444444444

小说网站源码+全自动采集规则+H5手机版页面

源码分享

  小说网站源码是一个基于web的系统,使用PHP、BootStrap、CSS、JavaScript和MySQL为数据库开发。它包含两个方面,即管理员端和用户端。这个PHP/MySQLi环境下的在小说站旨在帮助管理员一个简单的方法来更新和维护所有的在线图书,以供阅读者查阅。
  
  源码:xsymz.icu
  
  PHP中的在线小说站源码是一个使用PHP、JavaScript和CSS开发的简单项目。该项目包含管理员和用户端。管理员端管理所有的管理,如添加书籍、删除书籍和编辑书籍的详细信息,管理员在这个小说站系统的管理中扮演着重要的角色。
  
  对于用户部分,如果用户已经有账号,可以以用户身份登录,否则,他/她必须填写注册表以注册为用户。用户可以浏览已发行书籍的详细信息及其归还状态。该项目为学生和小说站做好图书记录、借阅和归还工作提供了方便。
  
  我们中的许多人最有可能的一天是通过阅读一本书来度过的,无论它是一个幻想系列、小说、惊悚片、浪漫和更多的选择。获得所有这些资源的最佳地点是在线小说站。我们都知道管理一个小说是不容易的,无论是资源站还是搜索站,这时,一套稳定高效的小说网站源码就是至关重要的。在这个PHP/MySQLi环境下的小说管理系统,管理员有权在所有交易中从借书、还书和图书类别。他还拥有管理所有书籍、管理借贷者和管理所有用户的能力。同时,用户可以根据自己想要的图书类型,方便地通过网上借阅图书,甚至可以在登录系统后更新自己的个人资料。
  
  小说网站源码系统结构:
  
  管理端
  
  1、仪表板
  
  2、借来的书
  
  3、还书
  
  4、图书种类
  
  5、管理书籍
  
  6、管理借款人
  
  7、管理用户
  
  8、登录和注销
  
  阅读段
  
  1、加书
  
  2、图书过滤
  
  3、关于我们
  
  4、联系人管理
  
  5、简况
  
  6、借书
  
  7、借阅图书一览表
  
  8、登录和注销
  
  小说站源码的安装方法:
  
  1、下载zip文件;
  
  2、下载并安装XAMPP;
  
  3、运行XAMPP控制面板并启动MySQL和Apache;
  
  4、去C:\xampp\htdocs并提取下载的zip文件(图书馆系统)在文件夹内;
  
  5、打开浏览器并转到localhost/phpmyadmin/创建数据库;
  
  6、单击新建以创建数据库;
  
  7、命名数据库数据库库;
  
  8、单击“导入”以导入sql语言文件;
  
  9、单击“选择文件”,然后选择可以在图书馆系统文件夹;
  
  10、单击go;
  
  11、打开浏览器并转到localhost/LibrarySystem/admin/
  
  访问管理员帐户
  
  用户名:admin
  
  密码:admin
  
  12、打开浏览器并转到localhost/LibrarySystem/
  
  访问管理员帐户
  
  你可以注册。
  
  关于源码
  
  这个小说网站源码使用PHP、JavaScript和CSS,并自动集成了多套采集规则。在介绍本系统的特点时,它包括管理部分和用户部分。所有的编辑更新,管理书籍作者都来自管理部门,这套源码的设计很简单,所以用户在工作时不会遇到任何困难。

继续阅读 »

  小说网站源码是一个基于web的系统,使用PHP、BootStrap、CSS、JavaScript和MySQL为数据库开发。它包含两个方面,即管理员端和用户端。这个PHP/MySQLi环境下的在小说站旨在帮助管理员一个简单的方法来更新和维护所有的在线图书,以供阅读者查阅。
  
  源码:xsymz.icu
  
  PHP中的在线小说站源码是一个使用PHP、JavaScript和CSS开发的简单项目。该项目包含管理员和用户端。管理员端管理所有的管理,如添加书籍、删除书籍和编辑书籍的详细信息,管理员在这个小说站系统的管理中扮演着重要的角色。
  
  对于用户部分,如果用户已经有账号,可以以用户身份登录,否则,他/她必须填写注册表以注册为用户。用户可以浏览已发行书籍的详细信息及其归还状态。该项目为学生和小说站做好图书记录、借阅和归还工作提供了方便。
  
  我们中的许多人最有可能的一天是通过阅读一本书来度过的,无论它是一个幻想系列、小说、惊悚片、浪漫和更多的选择。获得所有这些资源的最佳地点是在线小说站。我们都知道管理一个小说是不容易的,无论是资源站还是搜索站,这时,一套稳定高效的小说网站源码就是至关重要的。在这个PHP/MySQLi环境下的小说管理系统,管理员有权在所有交易中从借书、还书和图书类别。他还拥有管理所有书籍、管理借贷者和管理所有用户的能力。同时,用户可以根据自己想要的图书类型,方便地通过网上借阅图书,甚至可以在登录系统后更新自己的个人资料。
  
  小说网站源码系统结构:
  
  管理端
  
  1、仪表板
  
  2、借来的书
  
  3、还书
  
  4、图书种类
  
  5、管理书籍
  
  6、管理借款人
  
  7、管理用户
  
  8、登录和注销
  
  阅读段
  
  1、加书
  
  2、图书过滤
  
  3、关于我们
  
  4、联系人管理
  
  5、简况
  
  6、借书
  
  7、借阅图书一览表
  
  8、登录和注销
  
  小说站源码的安装方法:
  
  1、下载zip文件;
  
  2、下载并安装XAMPP;
  
  3、运行XAMPP控制面板并启动MySQL和Apache;
  
  4、去C:\xampp\htdocs并提取下载的zip文件(图书馆系统)在文件夹内;
  
  5、打开浏览器并转到localhost/phpmyadmin/创建数据库;
  
  6、单击新建以创建数据库;
  
  7、命名数据库数据库库;
  
  8、单击“导入”以导入sql语言文件;
  
  9、单击“选择文件”,然后选择可以在图书馆系统文件夹;
  
  10、单击go;
  
  11、打开浏览器并转到localhost/LibrarySystem/admin/
  
  访问管理员帐户
  
  用户名:admin
  
  密码:admin
  
  12、打开浏览器并转到localhost/LibrarySystem/
  
  访问管理员帐户
  
  你可以注册。
  
  关于源码
  
  这个小说网站源码使用PHP、JavaScript和CSS,并自动集成了多套采集规则。在介绍本系统的特点时,它包括管理部分和用户部分。所有的编辑更新,管理书籍作者都来自管理部门,这套源码的设计很简单,所以用户在工作时不会遇到任何困难。

收起阅读 »

字节抖音小程序使用$refs报错解决办法

经验分享

我做抖音小程序遇到这个问题,开发工具里一切正常,一旦真机使用时运行到$refs就报错
解决办法如下(困扰了我三天):
参考官网的“.sync修饰符

父组件:
<form-item ref="formItem" :isfromok.sync="isfromok"&gt;&lt;/form-item&gt;

components: {  
    formItem  
},  
data() {  
    return {  
        isfromok: false     //是否填写表单  
    };  
},  

子组件(直接修改父组件的值):
let data = 123456;
_this.$emit('update:isfromok',datas);

在父组件内可直接判断isfromok的值是否符合预期,不用再使用$refs了
如果需要执行子组件的方法,可以使用watch监听来实现,希望能够帮助更多的人

继续阅读 »

我做抖音小程序遇到这个问题,开发工具里一切正常,一旦真机使用时运行到$refs就报错
解决办法如下(困扰了我三天):
参考官网的“.sync修饰符

父组件:
<form-item ref="formItem" :isfromok.sync="isfromok"&gt;&lt;/form-item&gt;

components: {  
    formItem  
},  
data() {  
    return {  
        isfromok: false     //是否填写表单  
    };  
},  

子组件(直接修改父组件的值):
let data = 123456;
_this.$emit('update:isfromok',datas);

在父组件内可直接判断isfromok的值是否符合预期,不用再使用$refs了
如果需要执行子组件的方法,可以使用watch监听来实现,希望能够帮助更多的人

收起阅读 »

分享下安卓下文件和目录的读取,写入,移动,删除

Native.JS 文件 安卓

分享下安卓下目录和文件读取
注意需要安装排序库natsort.min.js,和 vm.$u.date 时间函数,可以用自己的函数代替

// #ifdef APP-PLUS  
//只能用于安卓 导入java类  
let File = plus.android.importClass("java.io.File");  
let BufferedReader = plus.android.importClass("java.io.BufferedReader");  
let FileReader = plus.android.importClass("java.io.FileReader");  
let FileWriter = plus.android.importClass("java.io.FileWriter");  
// 安卓11及一下可以在任意地方创建文件夹  /sdcard/自己的文件夹/1.txt  
// 安卓11(百度安卓目录限制) /storage/emulated/0/Download/自己的文件夹/1.txt  

//新建文件 newFiles("/sdcard/修止符/配置.json")  
    let newFiles = (name) => {  
        let directory = new File(name);  
        if (!directory.exists()) {  
            return directory.mkdirs(); //不存在创建目录  
        }  
        return false;  
    };  
//读取txt文件 readFile ("/sdcard/修止符/配置.json")  
    let readFile = (fileName) => {  
        let readFr = new File(fileName);  
        try {  
            let reader = new BufferedReader(new FileReader(readFr));  
            let txt;  
            let retxt = '';  
            while (true) {  
                txt = reader.readLine(); //读取文件  
                if (txt == null) {  
                    break;  
                }  
                retxt = retxt + '\r\n' + txt;  
            }  
            return retxt;  
        } catch (e) {  
            console.log(e)  
            return '';  
        }  
    };  
//写文件 whiteFile("/sdcard/修止符/配置.json",{"主键":"值"})  
    let whiteFile = (fileName, res) => {  
        res = res ? JSON.stringify(res) : ''; //对象转换为json文本  
        try {  
            //不加根目录创建文件(即用相对地址)的话directory.exists()这个判断一值都是false  
            let n = fileName.lastIndexOf("/");  
            if (n != -1) {  
                let fileDirs = fileName.substring(0, n);  
                let directory = new File(fileDirs);  
                if (!directory.exists()) {  
                    directory.mkdirs(); //不存在创建目录  
                }  
            }  
            let file = new File(fileName);  
            if (!file.exists()) {  
                file.createNewFile(); //创建文件  
            }  
            let fos = new FileWriter(fileName, false);  
            fos.write(res);  
            fos.close();  
            return true;  
        } catch (e) {  
            console.log(e);  
            return false;  
        }  
        return false;  
    };  
//删除文件或文件夹 deleteFile  ("/sdcard/修止符/待删除/配置.json")  
    let deleteFile = (fileName) => {  
        console.log(fileName);  
        let file = new File(fileName.replace('//', '/'));  
        if (file.isFile() && file.exists()) {  
            return file.delete();  
        } else if (file.isDirectory()) {  
            let flag = true;  
            let files = file.listFiles();  
            let lenI = files.length  
            for (let i = 0; i < lenI; i++) {  
                //删除子目录和文件  
                flag = deleteFile(files[i].getAbsolutePath());  
                if (!flag) break;  
            }  
            if (!flag) return false;  
            //删除当前空目录  
            return file.delete();  
        }  
    };  
//移动文件 moveFile ("/sdcard/修止符/待删除/配置.json","/sdcard/修止符/配置.json")  
    let moveFile = (oldfile, newfile) => {  
        let n = newfile.lastIndexOf("/");  
        if (n != -1) {  
            let fileDirs = newfile.substring(0, n);  
            let directory = new File(fileDirs);  
            if (!directory.exists()) {  
                directory.mkdirs(); //不存在创建目录  
            }  
        }  
        let file = new File(oldfile);  
        let nfile = new File(newfile);  
        return file.renameTo(nfile);  
    };  
//读取目录  readFileList ("/sdcard/修止符/")   注意需要安装排序库natsort.min.js, vm.$u.date 时间函数  
    let readFileList = (fileName) => {  
        let directory;  
        let path = vm.vuex_xzfdir;  
        let empty = vm.$u.test.isEmpty(fileName)  
        if (empty) {  
            directory = new File(vm.vuex_xzfdir);  
        } else {  
            path = fileName;  
            directory = new File(path);  
        }  
        if (!directory.exists()) {  
            directory.mkdirs();  
        }  
        let files = directory.listFiles();  
        //对文件和文件夹进行分类  
        let lenI = files.length  
        let folderArr = [];  
        let fileArr = [];  
        for (let i = 0; i < lenI; ++i) {  
            if (files[i].isFile()) {  
                fileArr.push({  
                    id: i,  
                    show: false,  
                    icon: 'file-text',  
                    path: path,  
                    fileName: files[i].getName(),  
                    CreationTime: vm.$u.date(new Date(files[i].lastModified()), 'yyyy年mm月dd日 hh时MM分ss秒')  
                });  
            } else {  
                folderArr.push({  
                    id: i,  
                    show: false,  
                    icon: 'list-dot',  
                    path: path,  
                    fileName: files[i].getName(),  
                    CreationTime: vm.$u.date(new Date(files[i].lastModified()), 'yyyy年mm月dd日 hh时MM分ss秒')  
                });  
            }  
        }  
        //对文件进行排序 需要安装排序库natsort.min.js  
        let sorter = natsort({  
            desc: vm.vuex_desc  
        });  
        fileArr.sort((a, b) => {  
            return sorter(a.fileName, b.fileName);  
        });  
        folderArr.sort((a, b) => {  
            return sorter(a.fileName, b.fileName);  
        })  
        let resultArr = folderArr.concat(fileArr);  
        return resultArr;  
    }  
    // #endif  
继续阅读 »

分享下安卓下目录和文件读取
注意需要安装排序库natsort.min.js,和 vm.$u.date 时间函数,可以用自己的函数代替

// #ifdef APP-PLUS  
//只能用于安卓 导入java类  
let File = plus.android.importClass("java.io.File");  
let BufferedReader = plus.android.importClass("java.io.BufferedReader");  
let FileReader = plus.android.importClass("java.io.FileReader");  
let FileWriter = plus.android.importClass("java.io.FileWriter");  
// 安卓11及一下可以在任意地方创建文件夹  /sdcard/自己的文件夹/1.txt  
// 安卓11(百度安卓目录限制) /storage/emulated/0/Download/自己的文件夹/1.txt  

//新建文件 newFiles("/sdcard/修止符/配置.json")  
    let newFiles = (name) => {  
        let directory = new File(name);  
        if (!directory.exists()) {  
            return directory.mkdirs(); //不存在创建目录  
        }  
        return false;  
    };  
//读取txt文件 readFile ("/sdcard/修止符/配置.json")  
    let readFile = (fileName) => {  
        let readFr = new File(fileName);  
        try {  
            let reader = new BufferedReader(new FileReader(readFr));  
            let txt;  
            let retxt = '';  
            while (true) {  
                txt = reader.readLine(); //读取文件  
                if (txt == null) {  
                    break;  
                }  
                retxt = retxt + '\r\n' + txt;  
            }  
            return retxt;  
        } catch (e) {  
            console.log(e)  
            return '';  
        }  
    };  
//写文件 whiteFile("/sdcard/修止符/配置.json",{"主键":"值"})  
    let whiteFile = (fileName, res) => {  
        res = res ? JSON.stringify(res) : ''; //对象转换为json文本  
        try {  
            //不加根目录创建文件(即用相对地址)的话directory.exists()这个判断一值都是false  
            let n = fileName.lastIndexOf("/");  
            if (n != -1) {  
                let fileDirs = fileName.substring(0, n);  
                let directory = new File(fileDirs);  
                if (!directory.exists()) {  
                    directory.mkdirs(); //不存在创建目录  
                }  
            }  
            let file = new File(fileName);  
            if (!file.exists()) {  
                file.createNewFile(); //创建文件  
            }  
            let fos = new FileWriter(fileName, false);  
            fos.write(res);  
            fos.close();  
            return true;  
        } catch (e) {  
            console.log(e);  
            return false;  
        }  
        return false;  
    };  
//删除文件或文件夹 deleteFile  ("/sdcard/修止符/待删除/配置.json")  
    let deleteFile = (fileName) => {  
        console.log(fileName);  
        let file = new File(fileName.replace('//', '/'));  
        if (file.isFile() && file.exists()) {  
            return file.delete();  
        } else if (file.isDirectory()) {  
            let flag = true;  
            let files = file.listFiles();  
            let lenI = files.length  
            for (let i = 0; i < lenI; i++) {  
                //删除子目录和文件  
                flag = deleteFile(files[i].getAbsolutePath());  
                if (!flag) break;  
            }  
            if (!flag) return false;  
            //删除当前空目录  
            return file.delete();  
        }  
    };  
//移动文件 moveFile ("/sdcard/修止符/待删除/配置.json","/sdcard/修止符/配置.json")  
    let moveFile = (oldfile, newfile) => {  
        let n = newfile.lastIndexOf("/");  
        if (n != -1) {  
            let fileDirs = newfile.substring(0, n);  
            let directory = new File(fileDirs);  
            if (!directory.exists()) {  
                directory.mkdirs(); //不存在创建目录  
            }  
        }  
        let file = new File(oldfile);  
        let nfile = new File(newfile);  
        return file.renameTo(nfile);  
    };  
//读取目录  readFileList ("/sdcard/修止符/")   注意需要安装排序库natsort.min.js, vm.$u.date 时间函数  
    let readFileList = (fileName) => {  
        let directory;  
        let path = vm.vuex_xzfdir;  
        let empty = vm.$u.test.isEmpty(fileName)  
        if (empty) {  
            directory = new File(vm.vuex_xzfdir);  
        } else {  
            path = fileName;  
            directory = new File(path);  
        }  
        if (!directory.exists()) {  
            directory.mkdirs();  
        }  
        let files = directory.listFiles();  
        //对文件和文件夹进行分类  
        let lenI = files.length  
        let folderArr = [];  
        let fileArr = [];  
        for (let i = 0; i < lenI; ++i) {  
            if (files[i].isFile()) {  
                fileArr.push({  
                    id: i,  
                    show: false,  
                    icon: 'file-text',  
                    path: path,  
                    fileName: files[i].getName(),  
                    CreationTime: vm.$u.date(new Date(files[i].lastModified()), 'yyyy年mm月dd日 hh时MM分ss秒')  
                });  
            } else {  
                folderArr.push({  
                    id: i,  
                    show: false,  
                    icon: 'list-dot',  
                    path: path,  
                    fileName: files[i].getName(),  
                    CreationTime: vm.$u.date(new Date(files[i].lastModified()), 'yyyy年mm月dd日 hh时MM分ss秒')  
                });  
            }  
        }  
        //对文件进行排序 需要安装排序库natsort.min.js  
        let sorter = natsort({  
            desc: vm.vuex_desc  
        });  
        fileArr.sort((a, b) => {  
            return sorter(a.fileName, b.fileName);  
        });  
        folderArr.sort((a, b) => {  
            return sorter(a.fileName, b.fileName);  
        })  
        let resultArr = folderArr.concat(fileArr);  
        return resultArr;  
    }  
    // #endif  
收起阅读 »

新版lib.5plus.base-release.aar插件导致android离线打包隐私弹窗中对应链接点击后为空白页(包含解决办法)

离线打包 隐私政策 uniapp

现象:
使用3.1.2配置使用正常
使用3.1.13+版本,安装应用后的隐私弹窗,点击其中的链接跳到空白页面,复制网址提示复制null
通过与3.1.2版本互换插件,将问题定位到lib.5plus.base-release.aar上
奇怪的是这个问题在as自带的模拟器上不存在,在真机上才存在

原因:
因为我们应用使用的是uniapp范例中的文案,所以一直以为是我们在strings.xml中的配置项目与新版插件不兼容导致
实际上本质是,我们的配置项目根本就没生效,看到的是lib.5plus.base-release.aar中携带的默认值,变更文案后可以发现模拟器中变更了,但是真机还是原样

造成原因是:我们的string配置按照demo写在了res/values/下,
3.1.2的lib.5plus.base-release.aar自带字符串资源只有values(中文) 和values-en(英文),编译时资源合并顺序最后写入自定义配置,可以生效。
而新版的lib.5plus.base-release.aar自带字符串资源有values(默认,英文?) 和values-en(英文),以及values-zh(中文)。
因为values的定义发生了变化,而离线打包sdk中demo使用的还是values,因此我们配置的项目,只会覆盖value的默认项目,并不会覆盖values-zh
而实际上真机因为是中文系统会默认使用values-zh,导致使用的字符串dcloud_privacy_prompt_message还是lib.5plus.base-release.aar中的默认值,其中对应的href是"",自然到了浏览器就是空值

解决办法:
res下的values目录复制一份更名为values-zh

这个问题应该是官方想要增强多语言的支持能力修订了相关的定义导致。
因为过于诡异,而且更诡异的是社区完全看不到类似的问题,特此提交一个说明,希望能够帮到有需要的人。
也希望官方能够在后续处理此类问题时兼顾考虑demo和相关配置文档的修订。

继续阅读 »

现象:
使用3.1.2配置使用正常
使用3.1.13+版本,安装应用后的隐私弹窗,点击其中的链接跳到空白页面,复制网址提示复制null
通过与3.1.2版本互换插件,将问题定位到lib.5plus.base-release.aar上
奇怪的是这个问题在as自带的模拟器上不存在,在真机上才存在

原因:
因为我们应用使用的是uniapp范例中的文案,所以一直以为是我们在strings.xml中的配置项目与新版插件不兼容导致
实际上本质是,我们的配置项目根本就没生效,看到的是lib.5plus.base-release.aar中携带的默认值,变更文案后可以发现模拟器中变更了,但是真机还是原样

造成原因是:我们的string配置按照demo写在了res/values/下,
3.1.2的lib.5plus.base-release.aar自带字符串资源只有values(中文) 和values-en(英文),编译时资源合并顺序最后写入自定义配置,可以生效。
而新版的lib.5plus.base-release.aar自带字符串资源有values(默认,英文?) 和values-en(英文),以及values-zh(中文)。
因为values的定义发生了变化,而离线打包sdk中demo使用的还是values,因此我们配置的项目,只会覆盖value的默认项目,并不会覆盖values-zh
而实际上真机因为是中文系统会默认使用values-zh,导致使用的字符串dcloud_privacy_prompt_message还是lib.5plus.base-release.aar中的默认值,其中对应的href是"",自然到了浏览器就是空值

解决办法:
res下的values目录复制一份更名为values-zh

这个问题应该是官方想要增强多语言的支持能力修订了相关的定义导致。
因为过于诡异,而且更诡异的是社区完全看不到类似的问题,特此提交一个说明,希望能够帮到有需要的人。
也希望官方能够在后续处理此类问题时兼顾考虑demo和相关配置文档的修订。

收起阅读 »

Uniapp 添加自定义参数,添加 webpack 插件,用 vue.config.js

uniapp

实际项目中,我们需要加入一些自定义的参数。比如针对 ENV=production / NODE_ENV=development ,两种编译方式,设置不同的参数。

1、当 ENV=production,api 使用域名 app.example.com
2、当 NODE_ENV=development,api 使用域名 dev.example.com

可以这样实现,在项目根目录下创建文件 vue.config.js,添加如下代码:

const webpack = require('webpack')  

module.exports = {  
    configureWebpack: {  
        plugins: [  
            new webpack.DefinePlugin({  
                "process.env": {  
                    'SERVER_URL': process.env.NODE_ENV == 'production' ?  
                        JSON.stringify('https://app.example.com/') : JSON.stringify('https://dev.example.com/')  
                }  
            })  
        ]  
    }  
}

需要调用的地方,直接使用 process.env.SERVER_URL,比如我在 config.js 中这样:

var config = {  
    apiUrl: process.env.SERVER_URL   'api/',  
}  

export default config

webpack 会在编译的时候替换掉 process.env.SERVER_URL,你可以在 dist 输出目录搜索 "example.com",就可以验证是否成功了。

使用Webpack PWA等其他插件

PWA 仅是针对Web发布的技术,chrome,firefox,微软Edge 都支持,而且可以直接加入系统的应用列表,入口和电脑应用一样,方便直接启动。

Webpack 有针对pwa的插件,在 uniapp 下,同样可以再 vue.config.js 中添加,代码参考如下:

注:参考代码里的 CopyWebpackPlugin,是无需编译,直接copy发布用的,也可以参考。

const webpack = require('webpack')  
const path = require('path')  
const CopyWebpackPlugin = require('copy-webpack-plugin')  

const SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');  
const WebpackPwaManifest = require('webpack-pwa-manifest');  

const {  
    getManifestJson,  
    parseManifestJson  
} = require('@dcloudio/uni-cli-shared/lib/manifest');  

const manifest = parseManifestJson(getManifestJson());  

module.exports = {  
    configureWebpack: {  
        plugins: [  
            new CopyWebpackPlugin([  
                {  
                    from: path.join(__dirname, 'src/packages/static'),  
                    to: path.join(__dirname, 'dist', process.env.NODE_ENV === 'production' ? 'build' : 'dev', process.env.UNI_PLATFORM, 'static')  
                }  
            ]),  
            new SWPrecacheWebpackPlugin(  
                {  
                    cacheId: 'bookcapt-cids',  
                    dontCacheBustUrlsMatching: /\.\w{8}\./,  
                    filename: 'service-worker.js',  
                    minify: false,  
                    navigateFallback: manifest.h5.router.base,  
                    staticFileGlobsIgnorePatterns: [/\.map$/, /manifest\.json$/, /automator\.json/]  
                }  
            ),  
            new WebpackPwaManifest({  
                name: '布克船长CIDAS',  
                short_name: '布克船长CIDAS',  
                description: '布克船长核心能力测评系统(CIDAS)',  
                background_color: '#f8f8f8',  
                theme_color: '#f8f8f8',  
                orientation: "landscape",  
                display: "standalone",  
                start_url: manifest.h5.router.base,  
                icons: [  
                    {  
                        src: path.resolve('src/static/pwa/logo.png'),  
                        sizes: [96, 128, 192],  
                        destination: path.join('assets', 'icons')  
                    }  
                ]  
            })  
        ]  
    }  
}

PWA页面见:https://app.readlevel.com/exam/#/

继续阅读 »

实际项目中,我们需要加入一些自定义的参数。比如针对 ENV=production / NODE_ENV=development ,两种编译方式,设置不同的参数。

1、当 ENV=production,api 使用域名 app.example.com
2、当 NODE_ENV=development,api 使用域名 dev.example.com

可以这样实现,在项目根目录下创建文件 vue.config.js,添加如下代码:

const webpack = require('webpack')  

module.exports = {  
    configureWebpack: {  
        plugins: [  
            new webpack.DefinePlugin({  
                "process.env": {  
                    'SERVER_URL': process.env.NODE_ENV == 'production' ?  
                        JSON.stringify('https://app.example.com/') : JSON.stringify('https://dev.example.com/')  
                }  
            })  
        ]  
    }  
}

需要调用的地方,直接使用 process.env.SERVER_URL,比如我在 config.js 中这样:

var config = {  
    apiUrl: process.env.SERVER_URL   'api/',  
}  

export default config

webpack 会在编译的时候替换掉 process.env.SERVER_URL,你可以在 dist 输出目录搜索 "example.com",就可以验证是否成功了。

使用Webpack PWA等其他插件

PWA 仅是针对Web发布的技术,chrome,firefox,微软Edge 都支持,而且可以直接加入系统的应用列表,入口和电脑应用一样,方便直接启动。

Webpack 有针对pwa的插件,在 uniapp 下,同样可以再 vue.config.js 中添加,代码参考如下:

注:参考代码里的 CopyWebpackPlugin,是无需编译,直接copy发布用的,也可以参考。

const webpack = require('webpack')  
const path = require('path')  
const CopyWebpackPlugin = require('copy-webpack-plugin')  

const SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');  
const WebpackPwaManifest = require('webpack-pwa-manifest');  

const {  
    getManifestJson,  
    parseManifestJson  
} = require('@dcloudio/uni-cli-shared/lib/manifest');  

const manifest = parseManifestJson(getManifestJson());  

module.exports = {  
    configureWebpack: {  
        plugins: [  
            new CopyWebpackPlugin([  
                {  
                    from: path.join(__dirname, 'src/packages/static'),  
                    to: path.join(__dirname, 'dist', process.env.NODE_ENV === 'production' ? 'build' : 'dev', process.env.UNI_PLATFORM, 'static')  
                }  
            ]),  
            new SWPrecacheWebpackPlugin(  
                {  
                    cacheId: 'bookcapt-cids',  
                    dontCacheBustUrlsMatching: /\.\w{8}\./,  
                    filename: 'service-worker.js',  
                    minify: false,  
                    navigateFallback: manifest.h5.router.base,  
                    staticFileGlobsIgnorePatterns: [/\.map$/, /manifest\.json$/, /automator\.json/]  
                }  
            ),  
            new WebpackPwaManifest({  
                name: '布克船长CIDAS',  
                short_name: '布克船长CIDAS',  
                description: '布克船长核心能力测评系统(CIDAS)',  
                background_color: '#f8f8f8',  
                theme_color: '#f8f8f8',  
                orientation: "landscape",  
                display: "standalone",  
                start_url: manifest.h5.router.base,  
                icons: [  
                    {  
                        src: path.resolve('src/static/pwa/logo.png'),  
                        sizes: [96, 128, 192],  
                        destination: path.join('assets', 'icons')  
                    }  
                ]  
            })  
        ]  
    }  
}

PWA页面见:https://app.readlevel.com/exam/#/

收起阅读 »

[uni-app]-安卓原生app特有的bug描述

[uni-app]-安卓原生app,在彼显现(v-if)此隐藏(v-else)的两个结构相似的doc对象中,在相同位置的同类型组件(特别是如 image、input 等这些组件)会进行复用,复用组件的v-if属性和样式会进行混用,动态切换的时候就会出现各种缺陷(明明是显示的组件其特有功能失效、呈现样式与预期的不一样,但微信小程序和苹果app的功能和呈现样式都正常)。


        <!-- 动态切换loginStatus的时候 图片圆角与预期的不一样 -->  
        <image v-if="loginStatus"  class="head-img-1" />  
        <image v-else  class="head-img-2" />  

<style>  
    .head-img-1 {  
        width: 80rpx;  
        height: 80rpx;  
        background-color: #999999;  
        border-radius: 40rpx;  
    }  

    .head-img-2 {  
        width: 80rpx;  
        height: 80rpx;  
        background-color: #999999;  
        border-radius: 8rpx;  
    }  
</style>
继续阅读 »

[uni-app]-安卓原生app,在彼显现(v-if)此隐藏(v-else)的两个结构相似的doc对象中,在相同位置的同类型组件(特别是如 image、input 等这些组件)会进行复用,复用组件的v-if属性和样式会进行混用,动态切换的时候就会出现各种缺陷(明明是显示的组件其特有功能失效、呈现样式与预期的不一样,但微信小程序和苹果app的功能和呈现样式都正常)。


        <!-- 动态切换loginStatus的时候 图片圆角与预期的不一样 -->  
        <image v-if="loginStatus"  class="head-img-1" />  
        <image v-else  class="head-img-2" />  

<style>  
    .head-img-1 {  
        width: 80rpx;  
        height: 80rpx;  
        background-color: #999999;  
        border-radius: 40rpx;  
    }  

    .head-img-2 {  
        width: 80rpx;  
        height: 80rpx;  
        background-color: #999999;  
        border-radius: 8rpx;  
    }  
</style>
收起阅读 »

H5开发业务外包,找个人或小团队支持。

Vue 外包

公司寻找可以长期提供前端技术开发支持的兼职个人或团队。现需要做一个类似http://www.ixiashan.cn/default 这种的h5(基于vue的最好),如果有整套可以直接用的最好;如果没有,可以作为成员之一加入我们的开发团队(远程即可)。有兴趣的联系我WX:Jonathanfu

继续阅读 »

公司寻找可以长期提供前端技术开发支持的兼职个人或团队。现需要做一个类似http://www.ixiashan.cn/default 这种的h5(基于vue的最好),如果有整套可以直接用的最好;如果没有,可以作为成员之一加入我们的开发团队(远程即可)。有兴趣的联系我WX:Jonathanfu

收起阅读 »

支付宝小程序使用动态加载插件

淘宝联盟

支付宝小程序插件支持动态加载,下面以淘宝联盟支付宝小程序营销套件为例说明一下在 uni-app 中的使用方式。

安装插件

在 npm 下载 miniapp-bc-user 模块后,将 miniapp-bc-user 模块及其依赖的 tslib 模块移动到 mycomponents 目录下

manifest 配置

在 manifest.json 中 mp-alipay 节点下配置 "useDynamicPlugins" : true

page 使用

<template>  
    <view>  
        <bc-module v-if="showComponent" code="suite://bc.suite.union618/bc.template.nav" name="block-nav" />  
    </view>  
</template>  

<script>  
    const {  
        loadBC  
    } = __non_webpack_require__('/mycomponents/miniapp-bc-user')  
    export default {  
        data() {  
            return {  
                showComponent: false,  
            }  
        },  
        async onReady() {  
            await loadBC().then(() => {  
                this.showComponent = true  
            })  
        }  
    }  
</script>  

<style>  

</style>

注意事项

  • 在 HBuilderX 3.1.19 版本之前,还需要在每次编译到小程序平台后,手动在生成的支付宝小程序 app.json 中增加 "useDynamicPlugins" : true
  • 需要使用 non_webpack_require 替代 require 来加载 miniapp-bc-user 模块,因为在此原生组件内也加载了相关模块,并依赖的模块内共享的状态,如果直接使用 require 会被 webpack 编译,和原生组件内引用的并非同一个模块,导致状态无法共享。
  • 需要开启压缩编译,因为在支付宝小程序内也使用了 webpack 编译,require 会被编译为 webpack_require 且由于编译时未进行安全重命名导致和 uni-app 框架的 webpack_require 冲突,启用 uni-app 的压缩编译后,uni-app 框架的 __webpack_require__ 会被压缩命名,避免和小程序框架冲突。
继续阅读 »

支付宝小程序插件支持动态加载,下面以淘宝联盟支付宝小程序营销套件为例说明一下在 uni-app 中的使用方式。

安装插件

在 npm 下载 miniapp-bc-user 模块后,将 miniapp-bc-user 模块及其依赖的 tslib 模块移动到 mycomponents 目录下

manifest 配置

在 manifest.json 中 mp-alipay 节点下配置 "useDynamicPlugins" : true

page 使用

<template>  
    <view>  
        <bc-module v-if="showComponent" code="suite://bc.suite.union618/bc.template.nav" name="block-nav" />  
    </view>  
</template>  

<script>  
    const {  
        loadBC  
    } = __non_webpack_require__('/mycomponents/miniapp-bc-user')  
    export default {  
        data() {  
            return {  
                showComponent: false,  
            }  
        },  
        async onReady() {  
            await loadBC().then(() => {  
                this.showComponent = true  
            })  
        }  
    }  
</script>  

<style>  

</style>

注意事项

  • 在 HBuilderX 3.1.19 版本之前,还需要在每次编译到小程序平台后,手动在生成的支付宝小程序 app.json 中增加 "useDynamicPlugins" : true
  • 需要使用 non_webpack_require 替代 require 来加载 miniapp-bc-user 模块,因为在此原生组件内也加载了相关模块,并依赖的模块内共享的状态,如果直接使用 require 会被 webpack 编译,和原生组件内引用的并非同一个模块,导致状态无法共享。
  • 需要开启压缩编译,因为在支付宝小程序内也使用了 webpack 编译,require 会被编译为 webpack_require 且由于编译时未进行安全重命名导致和 uni-app 框架的 webpack_require 冲突,启用 uni-app 的压缩编译后,uni-app 框架的 __webpack_require__ 会被压缩命名,避免和小程序框架冲突。
收起阅读 »

团队接单 uniapp、小程序、公众号、网站 有意联系Q:1940125999 V:18080373482

外包

团队接单 uniapp、小程序、公众号、网站 有意联系Q:1940125999 V:18080373482

团队接单 uniapp、小程序、公众号、网站 有意联系Q:1940125999 V:18080373482

代写 iOS 原生插件 需求

插件需求

代写 iOS 原生插件

有需要请联系 1585538620@qq.com

代写 iOS 原生插件

有需要请联系 1585538620@qq.com

语音识别插件配置问题

nodejs

在开发app过程中,问题一:我使用的是百度语音识别,安卓测试没有问题,苹果测试报11201错误(发生未知错误,核心技术由科大讯飞提供),我是使用的百度语音识别,为什么在苹果环境会出现科大讯飞的报错?问题二:我更换了语音识别模式为科大讯飞,在安卓机上测试报错(未经授权的语音应用,错误代码11201),我按照官方提供的文档操作,为什么还是会报错呢?

继续阅读 »

在开发app过程中,问题一:我使用的是百度语音识别,安卓测试没有问题,苹果测试报11201错误(发生未知错误,核心技术由科大讯飞提供),我是使用的百度语音识别,为什么在苹果环境会出现科大讯飞的报错?问题二:我更换了语音识别模式为科大讯飞,在安卓机上测试报错(未经授权的语音应用,错误代码11201),我按照官方提供的文档操作,为什么还是会报错呢?

收起阅读 »