在uni_app中开发小程序之常用功能示例代码汇总

2023-06-01 00:00:00 uni

uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台。

官网:

https://uniapp.dcloud.net.cn/

常用功能示例demo:

类名

<view :class="['screen',screenNum!==0?'i_search_g':'' ]"></view>

设置标题

uni.setNavigationBarTitle({
  title: "剩余次卡"
});

上拉刷新下拉加载

// 需要在pages.json加入
// "enablePullDownRefresh": true
export default {
  data() {
    return {};
  },
  methods: {},
  onLoad: function(options) {
    uni.startPullDownRefresh();
  },
  onPullDownRefresh() {
    console.log("结束加载");
    setTimeout(function() {
      uni.stopPullDownRefresh();
    }, 1000);
  },
  onReachBottom() {
    console.log("下拉触底");
  }
};

弹框

数据加载

uni.showLoading({
  title: "加载中"
});
uni.hideLoading();

提示框

uni.showToast({});
title:显示的提示信息,在没有图标的情况下,文本内容可显示两行
icon: 显示的图标
success:成功图标
loading:加载图标
none:没有图标
image:自定义显示的图标,优先级高于 icon
duration:延迟的时间,弹出框弹出后的显示时间
mask:true/false 是否显示遮罩层
success:接口调用成功的回调函数
fail:接口调用失败的回调函数
complete:不管成功还是失败都会执行的函数

对话框

uni.showModal({
  title: "暂无数据",
  icon: "none"
});

wx.showModal() title:提示信息的标题 content:提示信息的内容 showCancel:true/false 是否显示取消按钮 cancelText:取消按钮的文本内容,不得超过四个字符 cancelColor:取消按钮的文本颜色,默认#000000 confirmText:确认按钮的文本内容,不得超过四个字符 confirmColor:却惹按钮的文本颜色,默认#000000 success:接口成功的回调 fail:接口失败的回调


小程序“↵”换行符号处理

var myString = myString.replace(/(\r\n|\n|\r)/gm, "\n");

小程序的换行符为'/n'

只有在 text 里面才能生效,在 view 里面不生效

拨打电话

openPhone(phone) {
  uni.makePhoneCall({
    phoneNumber: 'phone'
  })
}

页面传参

A页面获取data-id并跳转:

gotoB: function (e) {
      var id = e.target.dataset.id         //id 为绑定在button组件上的 data-id='123'
      wx.navigateTo({
        url: './index/index?id='+id,
    })
},

B页面获取:

onLoad: function (options) {
  var id = options.id
  console.log(id)
}

$set 更新数据

调用方法: Vue.set( target , key , value) target: 要更改的数据源(可以是一个对象或者数组) key 要更改的具体数据 (索引) value 重新赋的值

openUnfold(item,key,index) {
item[key]=!item[key];
this.$set(this.shopData.coupon,index,item);
},


引入全局 sass

在根目录下有一个文件 uni.scss 可以定义全局变量

调用地图

<template>
 <view @cilck="getLocation">华侨城商业中心</view>
</template>
<script>
//使用微信内置地图查看位置。
    export default {
methods: {
     getLocation:function(){
    uni.getLocation({
      type: 'wgs84',
      success: function (res) {
        uni.openLocation({
          latitude: 31.0938140000,//纬度
          longitude: 121.5039390000,//经度
          name: "MALL华侨城商业中心",
          address: '华侨城商业中心'
        })
      }
    })
},
}
<script>

获取用户的当前地址

https://lbs.qq.com/miniProgram/jsSdk/jsSdkGuide/jsSdkOverview
getLocationAuth() {
locationCity()
uni.getLocation({
type: 'wgs84',
success: function(res) {
console.log(res, "经纬度");
}
});
},

navigator 点击背景色

设置 navigator 属性 hover-class="none"时,没有点击态效果


设置分享

好友分享

左上角的分享
按钮分享,使用 button 添加 open-type="share"
朋友圈分享

左上角的分享

按钮分享无法调用 onShareTimeline

<button open-type="share">分享</button>
wx.showShareMenu({
    menus: ['shareAppMessagewx', 'shareTimeline'],
    withShareTicket:true
});
onShareAppMessage: function () {//分享好友
    return {
        title: '',
        imageUrl:'',
        path: '',
    }
},
onShareTimeline: function () {//分享朋友圈
    return {
        title: '',
        imageUrl:'',
        query: '',
    }
},

保存图片

uni.chooseImage({
  count: 1,
  sourceType: ["camera"],
  success: function(res) {
    uni.saveImageToPhotosAlbum({
      filePath: res.tempFilePaths[0],
      success: function() {
        console.log("save success");
      }
    });
  }
});

回到顶部

  goTop: function (e) {  // 一键回到顶部
    if (wx.pageScrollTo) {
      uni.pageScrollTo({
        scrollTop: 0
      })
    } else {
      uni.showModal({
        title: '提示',
        content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。'
      })
    }
  },

变量全局

globalData 小程序中有个 globalData 概念,可以在 App 上声明全局变量。 Vue 之前是没有这类概念的,但 uni-app 引入了 globalData 概念,并且在包括 H5、App 等平台都实现了。 在 App.vue 可以定义 globalData ,也可以使用 API 读写这个值。 globalData 支持 vue 和 nvue 共享数据。 globalData 是一种比较简单的全局变量使用方式。 定义:App.vue

<script>
    export default {
        globalData: {
            text: 'text'
        },
        onLaunch: function() {
            console.log('App Launch')
        },
        onShow: function() {
            console.log('App Show')
        },
        onHide: function() {
            console.log('App Hide')
        }
    }
</script>
<style>
    /*每个页面公共css */
</style>

js 中操作 globalData 的方式如下: 

赋值:getApp().globalData.text = 'test' 
取值:console.log(getApp().globalData.text) // 'test'


hover-class

用于代替 css 的 active

目前支持 hover-class 属性的组件有三个:view、button、navigator。

<view
  hover-class="hover_act"
  class="lg text-gray cuIcon-close"
  @click.stop="searchClose"
></view>
.hover_act { transform: rotate(360deg); transition: transform 0.5s; }

检查地址是否授权

uni.getSetting({
  success: res => {
    let authSetting = res.authSetting;
    if (authSetting["scope.userLocation"]) {
      // 已授权
    } else {
      uni.showModal({
        title: "您未开启地理位置授权",
        content: "小程序将无法正常使用",
        success: res => {
          if (res.confirm) {
            nui.openSetting();
          }
        }
      });
    }
  }
});

编译条件

APP-PLUS App APP-PLUS-NVUE App nvue H5 H5 MP-WEIXIN 微信小程序 MP-ALIPAY 支付宝小程序 MP-BAIDU 百度小程序 MP-TOUTIAO 字节跳动小程序 MP-QQ QQ 小程序 MP-360 360 小程序 MP 微信小程序/支付宝小程序/百度小程序/字节跳动小程序/QQ 小程序/360 小程序 QUICKAPP-WEBVIEW 快应用通用(包含联盟、华为) QUICKAPP-WEBVIEW-UNION 快应用联盟 QUICKAPP-WEBVIEW-HUAWEI 快应用华为

#ifdef APP-PLUS
https://uniapp.dcloud.io/platform

下载图片

wx.downloadFile({
  url: "https://www.cardbaobao.com/asset/uploads/image/cbbxcx.png", //需要下载的图片url
  success: function(res) {
    //成功后的回调函数
    wx.saveImageToPhotosAlbum({
      //保存到本地
      filePath: res.tempFilePath,
      success(res) {
        wx.showToast({
          title: "保存成功",
          icon: "success",
          duration: 2000
        });
      },
      fail: function(err) {
        console.log(err, "授权失败");
        if (err.errMsg === "saveImageToPhotosAlbum:fail auth deny") {
          wx.showToast({
            title: "授权失败,请重新授权",
            icon: "none",
            duration: 2000
          });
        }
      }
    });
  }
});

百度 web 版会存在一个问题

由于浏览器于涉及到隐私以及安全方面的考虑, 在使用 geolocation 进行定位的时候, 浏览器会询问用户是否允许共享位置信息; 不管用户同意还是拒绝,操作都会缓存起来

直白来说,就是当用户进入我们的 web 化的 h5 页面时,如果用户点击拒绝授权定位时, 那么以后打开的都会默认拒绝获取定位且无法再次调取定位,也就是说在 h5 页面用户拒绝了定位会一直白屏没数据,


我能想到的解决方式

通过 IP 获取定位 (代码存到百度服务器里面,难以实现)

引导用户清理缓存授权重新定位

当用户拒绝定位时,前端或者后端给一个经纬度的默认值

class Request {
  constructor(config = {}) {
    this.config = {};
    this.config.baseUrl = config.baseUrl ? config.baseUrl : "";
    this.config.dataType = config.dataType ? config.dataType : "json";
    this.config.responseType = config.responseType
      ? config.responseType
      : "text";
    this.config.header = config.header ? config.header : {};
    this.reqInterceptors = null;
    this.resInterceptors = null;
    this.interceptors = {
      request: fn => {
        this.reqInterceptors = fn;
      },
      response: fn => {
        this.resInterceptors = fn;
      }
    };
  }
  async get(url, config = {}) {
    return this._request("get", url, config);
  }
  async post(url, config = {}) {
    return this._request("post", url, config);
  }
  async put(url, config = {}) {
    return this._request("put", url, config);
  }
  async delete(url, config = {}) {
    return this._request("delete", url, config);
  }
  setConfig(config = {}) {
    this.config = this._deepCopy(this._merge(this.config, config));
  }
  getConfig() {
    return this.config;
  }
  _request(method, url, config) {
    const _this = this;
    let newConfig = this._deepCopy(this._merge(this.config, config));
    let lastConfig = {};
    if (this.reqInterceptors && typeof this.reqInterceptors === "function") {
      let reqInterceptors = this.reqInterceptors(newConfig);
      if (!reqInterceptors && process.env.NODE_ENV === "development") {
        console.warn("请求被拦截,此消息仅在开发环境显示。");
        return false;
      } else if (
        Object.prototype.toString.call(reqInterceptors) === "[object Promise]"
      ) {
        return reqInterceptors;
      }
      lastConfig = this._deepCopy(reqInterceptors);
    } else {
      lastConfig = this._deepCopy(newConfig);
    }
    let fullUrl = this._formatUrl(lastConfig.baseUrl, url);
    return new Promise((resolve, reject) => {
      uni.request({
        url: fullUrl,
        method,
        data: lastConfig.data ? lastConfig.data : {},
        header: lastConfig.header,
        dataType: lastConfig.dataType,
        responseType: lastConfig.responseType,
        async complete(response) {
          let res = response;
          if (
            _this.resInterceptors &&
            typeof _this.resInterceptors === "function"
          ) {
            let resInterceptors = _this.resInterceptors(res);
            if (!resInterceptors) {
              reject("返回值已被您拦截!");
              return;
            } else if (
              Object.prototype.toString.call(resInterceptors) ===
              "[object Promise]"
            ) {
              try {
                let promiseRes = await resInterceptors;
                resolve(promiseRes);
              } catch (error) {
                reject(error);
              }
            } else {
              res = resInterceptors;
            }
          }
          resolve(res);
        }
      });
    });
  }
  _formatUrl(baseUrl, url) {
    if (!baseUrl) return url;
    let formatUrl = "";
    const baseUrlEndsWithSlash = baseUrl.endsWith("/");
    const urlStartsWithSlash = url.startsWith("/");
    if (baseUrlEndsWithSlash && urlStartsWithSlash) {
      formatUrl = baseUrl + url.substring(1);
    } else if (baseUrlEndsWithSlash || urlStartsWithSlash) {
      formatUrl = baseUrl + url;
    } else {
      formatUrl = baseUrl + "/" + url;
    }
    return formatUrl;
  }
  _merge(oldConfig, newConfig) {
    let mergeConfig = this._deepCopy(oldConfig);
    if (!newConfig || !Object.keys(newConfig).length) return mergeConfig;
    for (let key in newConfig) {
      if (key !== "header") {
        mergeConfig[key] = newConfig[key];
      } else {
        if (
          Object.prototype.toString.call(newConfig[key]) === "[object Object]"
        ) {
          for (let headerKey in newConfig[key]) {
            mergeConfig[key][headerKey] = newConfig[key][headerKey];
          }
        }
      }
    }
    return mergeConfig;
  }
  _deepCopy(obj) {
    let result = Array.isArray(obj) ? [] : {};
    for (let key in obj) {
      if (obj.hasOwnProperty(key)) {
        if (typeof obj[key] === "object") {
          result[key] = this._deepCopy(obj[key]);
        } else {
          result[key] = obj[key];
        }
      }
    }
    return result;
  }
}
if (!global.$request) {
  global.$request = new Request();
}
export default global.$request;
在 main.js 引入
import request from "@/api/request/request.js";
Vue.prototype.$request = request;
request.setConfig({
  baseUrl: "https://store.91changqi.com",
  dataType: "json",
  responseType: "text",
  header: {
    token: "token from global",
    "content-type": "application/x-www-form-urlencoded"
  }
});

使用

this.$request.get("/api/ptype ").then(res => {
  console.log(res);
});

相关文章