vue项目打包app,uniapp

2,341 阅读10分钟

vue项目打包成APP

1,把vue项目打包成dist目录

我们先将项目目录下config文件内index.js中

assetsPublicPath修改为 assetsPublicPath: ‘./’

然后打包成dist文件夹,在cmd输入以下命令

npm run build

你就可以得到dist文件夹

打开Hbuilder,在里边打开dist文件夹

image.png

3,打包成app

接着我们右击这个dist目录,选择转化为移动app

这时候就会出现一个manifest.json,点击

image.png

image.png 这里你可以选择启动图配置,选择你喜欢的启动图,也可以跳过。

大部分的设置都可以默认,跳过

image.png 对了,因为vue项目没办法检测这个手机物理返回键,所以我们可以在index.html文件中修改一下,很简单

<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"><title>123</title><link href=./static/css/app.8203cae5dd59c366dbd3e59555e22b0b.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript>document.addEventListener('plusready', function(a) { //等待plus ready后再调用5+ API:
                   在这里调用5+ API
                  var first = null;
                  plus.key.addEventListener('backbutton', function() { //监听返回键
                          //首次按键,提示‘再按一次退出应用’
                          if (!first) {
                              first = new Date().getTime(); //获取第一次点击的时间戳
                              // console.log('再按一次退出应用');//用自定义toast提示最好
                              // toast('双击返回键退出应用'); //调用自己写的吐丝提示 函数
                              plus.nativeUI.toast("双击退出", {duration:'short'}); //通过H5+ API 调用Android 上的toast 提示框
                              setTimeout(function() {
                                  first = null;
                              }, 1000);
                          } else {
                              if (new Date().getTime() - first < 1000) { //获取第二次点击的时间戳, 两次之差 小于 1000ms 说明1s点击了两次,
                                  plus.runtime.quit(); //退出应用
                              }
                          }
                      }, false);
              });</script><script type=text/javascript src=./static/js/manifest.3ad1d5771e9b13dbdad2.js></script><script type=text/javascript src=./static/js/vendor.48ebd8a571039a26aa74.js></script><script type=text/javascript src=./static/js/app.202646c89ad3a0f4e2e1.js></script></body></html>

直接复制贴上去就行了。

点击导航栏的发行,选择云打包

image.png 广告可以去掉,点击打包。

image.png 打包完成,下载到手机,就可以安装使用了。

Vue移动端App实现自动更新(升级版本)

App.vue页面的methods添加以下方法

// 获取当前版本号
getNativeVersion(){
    let that = this;
    plus.runtime.getProperty(plus.runtime.appid, function(inf){
        that.nativeVersion = inf.version;
        that.checkUpdate(inf.version);
        localStorage.setItem("nativeVersion", inf.version);
    });
},
// 检查更新
checkUpdate(nativeVersion){
    let that = this;
    const checkUrl = "你的更新地址?date="+new Date();
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function(){
        if (xhr.readyState === 4) {
            if(xhr.status === 200){
                let responseObj = JSON.parse(xhr.responseText);
                let serverVersion = responseObj.version;
                if(responseObj.update === "yes" && nativeVersion < serverVersion){
                    that.downloadApk(responseObj.url);
                }
            }
        }
    };
    xhr.open('GET',checkUrl);
    xhr.send();
},
// 下载apk文件
downloadApk(url){
    let that = this;
    plus.downloader.createDownload( url , {filename: "_doc/update/"}, function(d, status){
        if ( status === 200 ) {
            // 安装apk资源包
            that.installFlag = true;
            that.path = d.filename;
        }
    }).start();
},
// 安装apk
installApk(){
    this.installFlag = false;
    plus.nativeUI.showWaiting("安装更新");
    plus.runtime.install(this.path,{},function(){
        plus.nativeUI.closeWaiting();
        plus.nativeUI.alert("更新完成!",function(){
            //  更新完成后重启应用
            plus.runtime.restart();
        });
    },function(e){
        plus.nativeUI.closeWaiting();
        plus.nativeUI.toast("安装更新失败!");
    });
},

vue引入框架

完整引入

在 main.js 中写入以下内容:

import Vue from 'vue'; 
import ElementUI from 'element-ui'; 
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue'; 
Vue.use(ElementUI); 
new Vue({ el: '#app', render: h => h(App) });

按需引入

借助 babel-plugin-component,我们可以只引入需要的组件,以达到减小项目体积的目的。

首先,安装 babel-plugin-component:

npm install babel-plugin-component -D

然后,将 .babelrc 修改为:(babel.config.js文件中,在plugins中添加如下:)

{
  "presets": [["es2015", { "modules": false }]],
  "plugins": [
    [
      "component",
      {
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ]
  ]
}

接下来,如果你只希望引入部分组件,比如 Button 和 Select,那么需要在 main.js 中写入以下内容:

import Vue from 'vue';
import { Button, Select } from 'element-ui';
import App from './App.vue';

Vue.component(Button.name, Button);
Vue.component(Select.name, Select);
/* 或写为
 * Vue.use(Button)
 * Vue.use(Select)
 */

new Vue({
  el: '#app',
  render: h => h(App)
});

uni-app

uni-app 如何在app端查看输入结果

Hbuilder编辑器->设置->运行配置->打开真机运行时打开调试视图

image.png

如何把uniapp项目运行在安卓手机上(保姆式教程)

  • 第一步:用数据线将安卓手机和电脑进行连接。
  • 再然后,我们需要有一个项目。(项目都没有,你运行在手机上,你在想屁?)
  • 找到菜单栏【运行】=》【运行到手机或模拟器】=》【未检测到手机或模拟器,请稍后重试】

image.png

  • 如果你是如图效果,请不要着急。听我细细讲来。
  • 这时候就需要操作你的安卓手机,找到【设置】=》【我的设备】=》【全部参数】=》多次点击【MIUI版本】,直到提示打开开发者模式。

image.png

  • 完成上一步,你就可以退出此页面。【设置】=》【更多参数】=》【开发者选项】=》打开【USB调试】 注意:有的手机和我的不一样,你们也是需要找到自己手机的版本,然后多次点击。找到开启开发者选项就行。换汤不换药。

  • 把电脑和手机用数据线进行连接起来。

  • 连接以后会出现如下图,记得选择【传输文件】

image.png

  • 以上操作你都做完以后,你就可以返回HBX去再次运行操作,如下图。

image.png

  • 点击运行到某某设备以后,你就等待编译,然后安装。即可成功。

image.png

image.png

Uni-App内引入Vant框架

1.Uni-App优点

一套代码编到11个平台,这不是梦想。眼见为实,扫描11个二维码,亲自体验最全面的跨平台效果!(这是官网原话)

2.项目搭建

1.首先在连接中下载vant。链接:vant组件下载链接

上述的链接由于是GitHub可能反应比较慢,但是一定是可以使用的。

2.建立Uni-App项目,打开Hbuilder,新建项目,选择uni-app里的默认模板直接创建就行。

image.png 3.在项目中引入vant。

首先在根目录下创建一个新的文件wxcomponents(与pages同级),接着把刚才在连接中下载的压缩包解压后的dist文件夹复制到wxcomponents文件中,并将dist文件名改为vant(如图)。

image.png

4.接着在pages.json中加入下列代码(Uni-App官网上有的)。

"autoscan": true,
	  "custom": {
	         "^van-(.*)": "@/wxcomponents/vant/$1/index.vue"// 匹配wxcomponents目录内的vue文件
	   
	  }

意思把vant - $1目录下生成index.vue文件(编译器可以搞定它)。

5.在App.vue中的style标签里加上下列代码。

@import "/wxcomponents/vant/common/index.wxss"

6.点击运行到浏览器。

image.png

3.问题及解决

完成以上步骤后,大家遇到的问题应该就是这个了。

image.png 解决:

找到icon文件夹下的index.vue,直接Ctrl+K进行格式化。

image.png 接着我们使用vant组件,在index.vue使用button组件。

<template>
    <view class="content">
        <image class="logo" src="/static/logo.png"></image>
        <view class="text-area">
            <text class="title">{{title}}</text>
            <van-button type="primary">LL</van-button>
        </view>
    </view>
</template>

image.png 直接在运行中找到浏览器:

image.png

image.png

项目中初始化引入npm或uniapp项目中使用npm

在非脚手架创建的项目中,有时需要使用npm包管理工具,例如在uniapp项目中。如果需要使用到npm,使用步骤如下:

1、初始化npm

//打开项目的终端,在终端中输入如下命令进行npm的初始化:

npm init -y

//这样项目根目录下就会出现 node_modules 文件夹 //如果此时没有出现,那么在后面的下载依赖后,根目录下就会出现 node_modules 文件夹

2、下载所需要的依赖包(这里以下载axios为例)

npm install axios 此时项目根目录下的 node_modules 内就会有你下载的依赖 如下图:

image.png 之后就可以在项目中需要的地方使用import引入所需的依赖包了。

开发规范(uniapp为什么会生成多套终端代码?)

为了实现多端兼容,综合考虑编译速度、运行性能等因素,uni-app 约定了如下开发规范:

前端常用的加密算法

1. base加密(可逆)

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>base64加密</title>
<script type="text/javascript" src="base64.js"></script>
<script type="text/javascript">  
        var b = new Base64();  
        var str = b.encode("admin:admin");  
        alert("base64 encode:" + str);  
     //解密
        str = b.decode(str);  
        alert("base64 decode:" + str);  
</script>  
</head>

<body>
</body>
</html>

2. md5加密(不可逆)

MD5共有6种加密方法:

  1. hex_md5(value)
  2. b64_m d5(value)
  3. str_md5(value)
  4. hex_hmac_md5(key, data)
  5. b64_hmac_md5(key, data)
  6. str_hmac_md5(key, data)
<script src="md5/md5.js"></script>"></script>
    <script>
        var code = "123456";
        var username = "123456";
        var password = "123456";
        var str1 = hex_md5("123456");
        var str2 = b64_md5("123456");
        var str3 = str_md5("123456");
        var str4 = hex_hmac_md5(code,code);
        var str5 = b64_hmac_md5(username,username);
        var str6 = str_hmac_md5(password,password);
        console.log(str1);            // e10adc3949ba59abbe56e057f20f883e
        console.log(str2);            // 4QrcOUm6Wau+VuBX8g+IPg
        console.log(str3);            // áÜ9IºY«¾VàWò��>
        console.log(str4);            // 30ce71a73bdd908c3955a90e8f7429ef
        console.log(str5);            // MM5xpzvdkIw5VakOj3Qp7w
        console.log(str6);            // 0Îq§;Ý��9U©��t)ï
</script>

3. sha1加密(不可逆)

<script src="https://cdn.bootcss.com/js-sha1/0.6.0/sha1.js"></script>
<script type="text/javascript">
        var sha1_1 = sha1("mosquito~");
        console.log(sha1_1);
        var sha1_2 = sha1("admin:1001");
        console.log(sha1_2);
</script>

image.png

什么是静态网页?什么是动态网页?

静态网页:

(1)静态网页不能简单地理解成静止不动的网页,他主要指的是网页中没有程序代码,只有HTML(即:超文本标记语言),一般后缀为.html,.htm,或者.xml等。虽然静态网页的页面一旦做成,内容就不会再改变了。但是,静态网页也包括一些能动的部分,这些主要是一些GIF动画等

(2)静态网页的打开,用户可以直接双击,并且不管任何人任何时间打开的页面的内容都是不变的。

动态网页:

(1)动态网页是指跟静态网页相对的一种网页编程技术。动态网页的网页文件中除了HTML标记以外,还包括一些特定功能的程序代码,这些代码可以使得浏览器和服务器可以交互,所以服务器端根据客户的不同请求动态的生成网页内容。

即:动态网页相对于静态网页来说,页面代码虽然没有变,但是显示的内容却是可以随着时间、环境或者数据库操作的结果而发生改变的。

(2)动态网页,与网页上的各种动画、滚动字幕等视觉上的动态效果没有直接关系,动态网页也可以是纯文字内容的,也可以是包含各种动画的内容,这些只是网页具体内容的表现形式,无论网页是否具有动态效果,只要是采用了动态网站技术(如PHP、ASP、JSP等)生成的网页都可以称为动态网页。

动态网页和静态网页的区别:

(1)更新和维护:

静态网页内容一经发布到网站服务器上,无论是否有用户访问,这些网页内容都是保存在网站服务器上的。如果要修改网页的内容,就必须修改其源代码,然后重新上传到服务器上。静态网页没有数据库的支持,当网站信息量很大的时候网页的制作和维护都很困难

动态网页可以根据不同的用户请求,时间或者环境的需求动态的生成不同的网页内容,并且动态网页一般以数据库技术为基础,可以大大降低网站维护的工作量

(2)交互性:

静态网页由于很多内容都是固定的,在功能方面有很大的限制,所以交互性较差

动态网页则可以实现更多的功能,如用户的登录、注册、查询等

(3)响应速度:

静态网页内容相对固定,容易被搜索引擎检索,且不需要连接数据库,因此响应速度较快

动态网页实际上并不是独立存在于服务器上的网页文件,只有当用户请求时服务器才返回一个完整的网页,其中涉及到数据的连接访问和查询等一系列过程,所以响应速度相对较慢

(4)访问特点:

静态网页的每个网页都有一个固定的URL,且网页URL以.htm、.html、.shtml等常见形式为后缀,而不含有“?”,可以直接双击打开

动态网页中的“?”对搜索引擎检索存在一定的问题,搜索引擎一般不可能从一个网站的数据库中访问全部网页,或者出于技术方面的考虑,搜索之中不去抓取网址中“?”后面的内容,不能直接双击打开

如果网页内容相对的简单,不需要频繁的进行改动,或者只是为了展示信息等,就用静态网页,简单易操作,不需要管理数据库等

如果网页内容相对复杂,功能多,改动频繁,实时性的内容多,就用动态网页

JS代码实现

JS - 浮点数不精确的解决方案

js浮点数的计算存在精度不准的问题,解决方案:用整数与整数的加减乘除运算来规避该问题

let [num1,num2] = [0.1, 0.2];

console.log(num1 + num2); // 0.30000000000000004
console.log(num1 - num2); // -0.1
console.log(num1 * num2); // 0.020000000000000004
console.log(num1 / num2); // 0.5

解决方案

  • number.js
/**
 * 加 +
 * @param num1
 * @param num2
 * @returns {number}
 */
function accAddition(num1, num2) {
    const num1Digits = (num1.toString().split('.')[1] || '').length;
    const num2Digits = (num2.toString().split('.')[1] || '').length;
    const baseNum = Math.pow(10, Math.max(num1Digits, num2Digits));
    return (Math.round(num1 * baseNum) + Math.round(num2 * baseNum)) / baseNum;
}

/**
 * 减 -
 * @param num1
 * @param num2
 * @returns {number}
 */
function accSubtract(num1, num2) {
    const num1Digits = (num1.toString().split('.')[1] || '').length;
    const num2Digits = (num2.toString().split('.')[1] || '').length;
    const baseNum = Math.pow(10, Math.max(num1Digits, num2Digits));
    return (Math.round(num1 * baseNum) - Math.round(num2 * baseNum)) / baseNum;
}

/**
 * 乘 *
 * @param num1
 * @param num2
 * @returns {number}
 */
function accMultiply(num1, num2) {
    const num1Digits = (num1.toString().split('.')[1] || '').length;
    const num2Digits = (num2.toString().split('.')[1] || '').length;
    const baseNum = Math.pow(10, Math.max(num1Digits, num2Digits));
    return (Math.round(num1 * baseNum) * Math.round(num2 * baseNum)) / baseNum / baseNum;
}

/**
 * 除 /
 * @param num1
 * @param num2
 * @returns {number}
 */
function accDivision(num1, num2) {
    const num1Digits = (num1.toString().split('.')[1] || '').length;
    const num2Digits = (num2.toString().split('.')[1] || '').length;
    const baseNum = Math.pow(10, Math.max(num1Digits, num2Digits));
    return (Math.round(num1 * baseNum) / Math.round(num2 * baseNum));
}

export {
    accAddition,
    accMultiply,
    accSubtract,
    accDivision
}

结果验证

import {accAddition, accSubtract, accMultiply, accDivision} from "@/utils/number";

let [num1,num2] = [0.1, 0.2];

console.log(accAddition(num1, num2)); // 0.3
console.log(accSubtract(num1, num2)); // -0.1
console.log(accMultiply(num1, num2)); // 0.02
console.log(accDivision(num1, num2)); // 0.5

js获取30天前日期

var date1 = new Date();
var date2 = new Date(date1);

//-30为30天前,+30可以获得30天后的日期
date2.setDate(date1.getDate() - 30);

//30天前(月份判断是否小于10,小于10的前面+0)
var agoDay = `${date2.getFullYear()}-${date2.getMonth() + 1<10?`0${date2.getMonth() + 1}`:date2.getMonth() + 1}-${date2.getDate()}`;
  
//当前日期
var nowDay = `${date1.getFullYear()}-${date1.getMonth() + 1<10?`0${date1.getMonth() + 1}`:date1.getMonth() + 1}-${date1.getDate()}`;

console.log(`30天前:${agoDay}`)
console.log(`当前日期:${nowDay}`)

image.png

比较两个日期的大小

第一种:转换为date对象进行比较操作

利用JS中的new Date方式将日期字符串转化为日期对象

<script>
var st="2009-10-20 14:38:40"
var et="2009-10-20 15:38:40"
var stdt=new Date(st.replace("-","/"));
var etdt=new Date(et.replace("-","/"));
if(stdt>etdt) alert("开始时间必须小于结束时间")
</script>

第二种:直接比较大小即可

<script>
var st="2009-10-20 14:38:40"
var et="2009-10-20 15:38:40"
if(st>et) alert("开始时间必须小于结束时间")
</script>

js通过身份证号获取出生日期,性别,年龄

 
 /*
    * 当type=1时获取出生日期,type=2时获取性别,type=3时获取年龄
    * */
    var idCard = '' //身份证号
    function IdCard(IdCard, type) {
        if (type === 1) {
            //获取出生日期
            let birthday = IdCard.substring(6, 10) + "-" + 
            IdCard.substring(10, 12) + "-" + IdCard.substring(12, 14)
            
            return birthday
        }
        if (type === 2) {
            //获取性别
            if (parseInt(IdCard.substr(16, 1)) % 2 === 1) {
                return "男"
            } else {
                return "女"
            }
        }
        if (type === 3) {
            //获取年龄
            var ageDate = new Date()
            var month = ageDate.getMonth() + 1
            var day = ageDate.getDate()
            var age = ageDate.getFullYear() - IdCard.substring(6, 10) - 1
            
            if (IdCard.substring(10, 12) < month || 
            IdCard.substring(10, 12) === month && IdCard.substring(12, 14) <= day) {
                age++
            }
            if (age <= 0) {
                age = 1
            }
            return age
        }
    }
 
    IdCard(idCard, 3)
 

根据用户输入身份证号前端自动计算其年龄

function get_baseinfo() {

 var usercode = $('#usercode').val();
 if (usercode == '' || usercode.length != 18) {
 alert('请输入18位正确身份证号');
 return false;
 }
 
 var date = new Date();
 var year = date.getFullYear();
 var birthday_year = parseInt(usercode.substr(6, 4));
 var userage = year - birthday_year;
  $('#age').val(userage);
 return false;
 }

<input type="text" id="usercode" οnchange="get_baseinfo()" name="identity" required="required" data-validate-length-range="8,20" class="form-control col-md-7 col-xs-12">

<input type="text" id="age" name="age" readonly="readonly" required="required" data-validate-length-range="8,20" class="form-control col-md-7 col-xs-12">

JS首字母大写方法

例如: BOB, aleN, tony, 变成 Bob, Alen, Tony

const titleCase = (str) => {
  let tmp = str.toLowerCase()
  
  //第一种方法
  tmp = tmp.charAt(0).toUpperCase() + tmp.slice(1)

  //第二种方法
  tmp = tmp.slice(0,1).toUpperCase() + tmp.slice(1)

  //第三种方法
  tmp = tmp.substring(0,1).toUpperCase() + tmp.substring(1)

  return tmp;
}
```
```