Mr.Raindrop

Mr.Raindrop

一切都在无可挽回的走向庸俗。
twitter
github

Vue2与uni-app笔记

Vue2 与 uni-app 笔记#

Vue2#

Vue 通过组件允许创建可重用块标记。大多数时候,Vue 组件是使用一个特殊的 HTML 模板的语法写的。当需要比 HTML 语法允许的更多的控制时,可以编写 JSX 或纯 JavaScript 函数来定义组件。一个 Vue 应用由一个通过 new Vue 创建的根 Vue 实例,以及可选的嵌套的、可复用的组件树组成。

template 是一级节点,用于写 tag 组件,script 和 style 是并列的一级节点,也就是有 3 个一级节点。

  • HTML 是一种标记语言,用来结构化我们的网页内容并赋予内容含义,例如定义段落、标题和数据表,或在页面中嵌入图片和视频。

  • CSS 是一种样式规则语言,可将样式应用于 HTML 内容,例如设置背景颜色和字体,在多个列中布局内容。

  • JavaScript 是一种脚本语言,可以用来创建动态更新的内容,控制多媒体,制作图像动画,还有很多。

DOM#

文档对象模型(Document Object model,简称 DOM)是针对 HTML 和 XML 文档的一个 API(应用程序编程接口)。文档对象模型(DOM)通过将文档的结构(例如表示网页的 HTML)以对象的形式存储在内存中,将网页与脚本或编程语言连接起来。DOM 使用逻辑树的形式来表示文档。树的每个分支末端都是一个节点,每个节点都包含对象。DOM 方法允许以编程方式来访问树。借助这些方法,你可以改变文档的结构、样式或内容。

rendering.svg

指令#

指令 (Directives) 是带有 v- 前缀的特殊 attribute。指令 attribute 的值预期是单个 JavaScript 表达式 (v-for 是例外情况)。

<!-- 完整语法 -->
<a v-on:click="doSomething">...</a>

<!-- 缩写 -->
<a @click="doSomething">...</a>

<!-- 完整语法 -->
<a v-bind:href="url">...</a>

<!-- 缩写 -->
<a :href="url">...</a>

计算属性与方法属性#

计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。因此,计算属性对于性能要求更低。

getter 和 setter 的含义#

Getter#

  1. 含义:
    • Getter 是计算属性的主要组成部分,它是一个函数,用于获取计算属性的值。
    • 当你访问计算属性时,实际上是在调用 getter 方法。
  2. 用途:
    • Getter 方法通常用于基于其他数据属性计算出一个新值。
    • Getter 方法可以访问组件的所有数据和其他计算属性。
    • 当依赖的数据发生变化时,Vue.js 会自动调用 getter 方法来更新计算属性的值。

Setter#

  1. 含义:
    • Setter 是一个可选的部分,它也是一个函数,用于设置计算属性的值。
    • 当你试图改变一个只读的计算属性时,Vue.js 会自动调用 setter 方法。
  2. 用途:
    • Setter 方法通常用于更新其他数据属性的值,而不是直接改变计算属性本身。
    • 当计算属性被赋值时,Vue.js 会调用 setter 方法。

箭头函数表达式 =>#

() => {
  statements
}

param => {
  statements
}
(param1, paramN) => {
  statements
}

箭头函数可以是 async 的,方法是在表达式前加上 async 关键字。

async param => expression
async (param1, param2, ...paramN) => {
  statements
}

异步操作和 Async/Await#

promise#

Promise 是现代 JavaScript 中异步编程的基础。它是一个由异步函数返回的对象,可以指示操作当前所处的状态。在 Promise 返回给调用者的时候,操作往往还没有完成,但 Promise 对象提供了方法来处理操作最终的成功或失败。

Promise 的优雅之处在于 then() 本身也会返回一个 Promise,这个 Promise 将指示 then() 中调用的异步函数的完成状态。由此可以链式使用 promise。

promise 有 ** 待定(pending)、已兑现(fulfilled)和已拒绝(rejected)** 三种状态。

Async 和 Await#

在一个函数的开头添加 async,就可以使其成为一个异步函数。

在 uni-app 中,asyncawait 的底层逻辑与原理与其他 JavaScript 环境相同。

在 Vue 组件的生命周期中,有一些钩子函数是异步的,比如 created 和 mounted。这些钩子函数允许你在组件被创建或挂载到 DOM 之后执行异步操作。

this.$api.common.login(this.loginForm).then(async res => {   // async 异步  箭头函数去除掉function关键字,在形参列表和函数体之间使用=>连接
    if (res.code == 200) {
    // 存储token和账号
    this.saveToken(res.token);
    this.saveAccount();
    // 获取用户信息
    let profile = await this.getProfile();   // 等待异步完成
    uni.$u.vuex('profile', profile);
    // 跳转主页
    uni.switchTab({
    url: '/pages/tabBar/home/index'
    });

async 函数是一个特殊的函数,它总是返回一个 Promise。即使你不显式地返回一个 Promise,async 函数也会返回一个已解决的 Promise,其值为 undefined

await 关键字只能在 async 函数内部使用。它用于等待一个 Promise 的结果。当 await 一个 Promise 时,JavaScript 引擎会暂停执行 async 函数,直到 Promise 解决或被拒绝。

asyncawait 的底层原理基于 Promise。Promise 是 JavaScript 中处理异步操作的标准方式之一,它有三种状态:pending(挂起)、fulfilled(已解决)和 rejected(已拒绝)。Promise 对象代表了一个最终可能会完成或失败的异步操作,并附带了完成或失败时的值。

await 关键字用于等待一个 Promise 的结果。当你在 async 函数中使用 await 关键字时,JavaScript 引擎会暂停执行 async 函数,直到 Promise 被解决或被拒绝。如果 Promise 被解决,await 表达式的值将是解决值;如果 Promise 被拒绝,await 表达式会抛出一个错误,这可以通过 try...catch 语句来处理。

插槽(slot)#

    <!-- 根据不同条件渲染图片 -->
    <u--image v-if="device.imgUrl" :src="device.imageUrl" radius="10" mode="aspectFill"
    width="70" height="70">
    <!-- 插槽(slot)显示不同状态时显示的图像 -->
    <view slot="error" style="font-size: 12px;">加载失败</view>
    <template v-slot:loading>
    <u-loading-icon></u-loading-icon>
    </template>

HTML 元素是 ——Web 组件技术套件的一部分 —— 它是一个在 web 组件内部的占位符,你可以使用自己的标记来填充该占位符,从而创建单独的 DOM 树并将其一起呈现。

$ 符号#

在 Vue.js 中,$ 符号的使用主要是基于 Vue 实例或 Vue 组件实例的一些特定属性和方法。这些属性和方法通常以 $ 开头,以区分它们与普通的数据属性、计算属性、方法等的不同。这些以 $ 开头的属性和方法往往是由 Vue 框架自身提供的,用于执行 Vue 相关的操作或访问 Vue 实例的内部状态。

template 中:的使用#

Vue.js 中属性绑定的详细解析:冒号 `:` 和非冒号的区别_vue 属性 冒号 - CSDN 博客

v-bind attribute 被称为指令。指令带有前缀 v-,以表示它们是 Vue 提供的特殊 attribute。

在设置参数时是否添加主要取决于是在设置 HTML 属性(attributes)还是 Vue 特有的指令。它们会在渲染的 DOM 上应用特殊的响应式行为。

不需要:的情况#

静态 HTML 属性:当你直接在元素上写属性时,如<div id="app">,这里的id="app"是一个静态的 HTML 属性,其值在编译时就已经确定,不会随着 Vue 实例中的数据变化而变化。

Vue 指令但非属性绑定:对于某些 Vue 指令,如v-modelv-ifv-for等,它们不是用于绑定 HTML 属性的,而是 Vue 特有的模板指令,用于实现数据绑定、条件渲染、列表渲染等功能。这些指令不需要:前缀,因为它们不是 HTML 属性的绑定。

需要:的情况#

动态 HTML 属性绑定:当你想要根据 Vue 实例中的数据动态地设置 HTML 元素的属性时,就需要使用v-bind指令。为了简化,Vue 允许使用:作为v-bind的简写。例如,<div :id="dynamicId">中的:id="dynamicId"表示id属性的值将绑定到 Vue 实例的dynamicId数据属性上。如果dynamicId的值发生变化,那么<div>id属性也会相应地更新。

<!-- 完整语法 -->
<a v-on:click="doSomething">...</a>

<!-- 缩写 -->
<a @click="doSomething">...</a>

动态绑定和静态绑定在性能上有所差异。动态绑定会增加一定的渲染开销,因为 Vue.js 需要监视表达式的变化并进行响应式更新。静态绑定则不会有这样的性能开销,因为它们是静态的值。

免密码登录相关#

从本地缓存中读取 token 值,并将其存储到 Vuex 状态管理器中,以便在需要的地方可以方便地访问此 token 值。

getToken () {
    // 本地缓存获取token
    this.token = uni.getStorageSync('token');
    // vuex存储token
    uni.$u.vuex('vuex_token', this.token);
}
  • 安全性:Token 通常比 Cookie 更安全,因为它包含了加密签名,并且可以设计为不持久化存储。而 Cookie 存储在客户端,更容易受到攻击。

  • 可扩展性:Token 机制更适合于无状态架构和分布式系统,因为它不需要服务器维护会话状态。

  • 跨域问题:Token 可以轻松解决跨域问题,而传统的 Session Cookie 受到同源策略的限制。

this.$refs.form#

this.$refs.form 是一个引用,指向了模板中带有 ref="form" 的表单元素或组件。

在 Vue 组件的模板中使用 ref 属性时,Vue 会在该组件实例的 $refs 对象中创建一个对应的属性,该属性的值就是对应的子组件实例或 DOM 元素。

注意:$refs 的值在组件渲染完成之前是 undefined。因此,你不能在 created 钩子中直接访问 $refs,而应该在 mounted 钩子或之后的生命周期中访问。

页面结构#

页面 | uni-app 官网 (dcloud.net.cn)

一个页面内,有 3 个根节点标签:

  • 模板组件区 <template>
  • 脚本区 <script>
  • 样式区 <style>

在 vue 文件中,templatescriptstyle 这 3 个是平级关系。在 vue2 中,template 的二级节点只能有一个节点,一般是在一个根 view 下继续写页面组件。但在 vue3 中,template 可以有多个二级节点,省去一个层级

在脚本区中,开发者应谨慎编写 export default {} 外面的代码,这里的代码有 2 个注意事项:

  1. 影响应用性能。这部分代码在应用启动时执行,而不是页面加载。如果这里的代码写的太复杂,会影响应用启动速度,占用更多内存。
  2. 不跟随组件、页面关闭而回收。在外层的静态变量不会跟随页面关闭而回收。如果必要你需要手动处理。比如 beforeDestroydestroyed 生命周期进行处理。

export#

在 ES6(ECMAScript 6)中,export 与 export default 均可用于导出变量 (含常量)、函数、类、文件、模块等,然后在其它文件或模块中通过 import 变量 (含常量)| 函数 | 类 | 文件 | 模块名的方式,将其导入,以便能够对其进行使用。export 可以有多个,然而 export default 只能有一个。

install#

在 Vue.js 中,使用 const install = (Vue, vm) => { ... }export default { install } 是一种常见的模式来定义和导出 Vue 插件。这种方法允许创建一个可以在 Vue 应用程序中使用的插件。

install 函数通常接收两个参数:

  • Vue 构造函数,可以用来扩展 Vue 的原型、注册全局组件、指令等。
  • vm: 可选参数,通常用于访问 Vue 实例的上下文,但在 Vue 3 中已被废弃。

在函数体中,可以执行各种操作来配置 Vue 或者注册自定义行为。当你在其他地方导入 (比如main.js) 这个模块时,可以通过 Vue.use() 方法来安装这个插件。

prototype#

在 JavaScript 中,原型是一种特殊的机制,用于实现对象之间的继承和共享属性及方法。每个 JavaScript 对象都有一个内部属性 [[[Prototype]]],它指向另一个对象,这个对象被称为原型对象。当试图访问一个对象的属性或方法时,如果该对象本身没有这个属性或方法,JavaScript 引擎会沿着原型链向上查找,直到找到这个属性或方法为止。Java 作为一种面向对象的编程语言,也有一种类似于 JavaScript 中原型机制的概念,但它采用的是类继承和接口实现的方式。Java 中并没有直接与 JavaScript 的 prototype 相对应的概念,但我们可以探讨 Java 中的一些机制,它们在某种程度上实现了类似的功能。

prototype 是一个特殊的属性,它存在于所有函数对象上。当创建一个函数时,这个函数会自动获得一个 prototype 属性。这个 prototype 属性是一个对象,它的用途是作为新创建对象的原型。当你使用构造函数创建对象时,新创建的对象会继承 prototype 对象上的属性和方法。

在 Vue.js 中,可以利用 JavaScript 的原型机制来扩展 Vue 的原型,使得所有的 Vue 实例可以共享某些属性和方法。这通常通过将属性或方法添加到 Vue.prototype 来实现。

Vue.prototype.$api = {
    // 导入模块
    common,
    scene,
    group,
    deviceUser,
    deviceLog,
    device,
    deviceJob,
    account,
    energyConsumptionAnalysis
};

上述代码,向 Vue 的原型上添加了一个名为 $api 的属性,并将自定义的模块加入之中。之后,可以在 Vue 的任何实例中都可以通过 $api 访问这些方法。

 this.$api.common.xxx()   // 访问自定的方法

Props#

uni-app 官网 (dcloud.net.cn)

组件基础 | Vue.js (vuejs.org)

props 可以是数组或对象,用于接收来自父组件的数据。Props 可以在子组件上声明注册,在父组件定义其中声明参数的值,父级 prop 的更新会向下流动到子组件中,但不能反向。props 可以是简单的数组,或者使用对象作为替代,对象允许配置高级选项,如类型检测、自定义验证和设置默认值。

ref#

uni-app 官网 (dcloud.net.cn)

用来给元素或子组件注册引用信息,引用信息将会注册在父组件的 $refs 对象上。

<!-- index 父组件页面 -->
<template>
	<view>
		<base-input ref="usernameInput"></base-input>
		<button type="default" @click="getFocus">获取焦点</button> 
	</view>
</template>
<script>
	export default {
		methods:{
			getFocus(){
				//通过组件定义的ref调用focus方法
				this.$refs.usernameInput.focus()
			}
		}
	}
</script>

vuex#

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

Vuex 与全局变量区别

vuex全局变量
不能直接改变 store 里面的变量,由统一的方法修改数据可以任意修改
每个组件可以根据自己 vuex 的变量名引用不受影响全局变量可能操作命名污染
解决了多组件之间通信的问题跨页面数据共享
适用于多模块、业务关系复杂的中大型项目适用于 demo 或者小型项目

每一个 Vuex 应用的核心就是 store(仓库),它包含着你的应用中大部分的状态 (state)。

状态管理有 5 个核心:stategettermutationactionmodule

Uni-app#

页面生命周期#

每个 Vue 实例在被创建时都要经过一系列的初始化过程 —— 例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数。

mounted#

在组件的 DOM 元素被挂载到文档 DOM 中之后被调用。下面代码中如果发现 token 则直接跳转页面。

	mounted () {    // mounted 钩子在组件的DOM元素被挂载(即插入到文档DOM中)之后被调用。
		this.getToken();  // 获取本地缓存token
		if (this.token != '' && this.token != null) {     
			// 跳转主页
			uni.switchTab({
				url: '/pages/tabBar/home/index'
			});
		} else {
			this.getCode();
			this.getAccount();
		}
	},

onShow、onHide、onUnload#

注意页面显示,是一个会重复触发的事件。

a 页面刚进入时,会触发 a 页面的 onShow

当 a 跳转到 b 页面时,a 会触发 onHide,而 b 会触发 onShow。

但当 b 被关闭时,b 会触发 onUnload,此时 a 再次显示出现,会再次触发 onShow。

在 tabbar 页面(指 pages.json 里配置的 tabbar),不同 tab 页面互相切换时,会触发各自的 onShow 和 onHide。

create#

在实例创建完成后被立即调用。

onReady#

监听页面初次渲染完成并执行所编写的代码,此时组件已挂载完成,DOM 树已可用。

Uni-app Vue2 中的页面生命周期

uni-app 框架,首先根据 pages.json 的配置,创建页面。根据页面中的 template 组件创建 dom。之后,触发 onload。

Tabbar 的设置#

uni-app 底部导航栏 tabBar 的显示和使用步骤_uni-app 判断是否为 tabbar 界面 - CSDN 博客

tabBar 中的 list 是一个数组,只能配置最少 2 个、最多 5 个 tab,tab 按数组的顺序排序。Tabbar 的设置位于page.js文件中。Tabbar 页面要加入文档中的 pages 数组中。

删除顶部导航栏#

uni-app 开发 - 顶部导航栏 - 掘金 (juejin.cn)

属性类型默认值描述
navigationStyleStringdefault导航栏样式,仅支持 default/custom。custom 即取消默认的原生导航栏,需看使用注意

pages.json 页面路由 | uni-app 官网 (dcloud.net.cn)

通过在manifest.json 中设置如下参数可以避免 app 与手机顶部状态栏或是水滴屏等遮挡的问题。也可以在顶部添加视觉块填充顶部状态栏区域解决该问题。

"app-plus" : {
    "statusbar": {  
        "immersed": false  
    }
}

uni.setStorageSync 和 Vuex store 存储异同#

uni.setStorageSync 是 uni-app 提供的一个本地存储 API,用于在客户端存储数据。它类似于 Web Storage API 中的 localStoragesessionStorage。Vuex 是 Vue.js 的官方状态管理模式,用于集中管理应用的所有组件的状态。本地存储是在客户端存储数据的一种方式,而状态管理是一种模式,用于集中管理应用程序的状态。

  • 存储位置: uni.setStorageSync 存储数据在客户端本地存储中;Vuex store 存储数据在内存中。
  • 持久化: uni.setStorageSync 中的数据是持久化的;Vuex store 中的数据在页面刷新后会丢失。
  • 响应式: Vuex store 中的数据是响应式的;uni.setStorageSync 中的数据不是响应式的。
  • 状态管理: Vuex store 提供了复杂的状态管理功能;uni.setStorageSync 主要用于简单的数据存储。
  • 安全性: uni.setStorageSync 中的数据更容易受到攻击;Vuex store 中的数据更受保护,因为数据在内存中而不是客户端本地存储。

uni.setStorage (OBJECT) @setstorage | uni-app 官网 (dcloud.net.cn)

使用 uni-app 的全局数据管理#

客户端存储 - 学习 Web 开发 | MDN (mozilla.org)

main.jsApp.vue 中初始化:

使用全局变量或 store#

在 store 文件夹下的 JS 文件夹中可以看到所存储的全局变量。

缓存#

一文读懂 Uniapp 的 setStorage、setStorageSync、getStorage 以及 getStorageSync(附 Demo)_uni.getstorage-CSDN 博客

通过缓存数据以在其他页面使用。

  • uni.setStorage({key, data, success, fail, complete}):将数据异步存储到本地缓存中,可提供成功、失败和完成时的回调函数
  • uni.getStorage({key, success, fail, complete}):从本地缓存中异步获取数据,可提供成功、失败和完成时的回调函数
  • uni.setStorageSync(key, data):将数据同步存储到本地缓存中,即时执行,没有回调函数
  • uni.getStorageSync(key):从本地缓存中同步获取数据,即时执行,没有回调函数
// 异步方法
uni.setStorage({
  key: 'key',
  data: 'value',
  success: function () {
    console.log('数据存储成功');
  },
  fail: function (error) {
    console.log('数据存储失败:', error);
  }
});

// 获取数据
uni.getStorage({
  key: 'key',
  success: function (res) {
    console.log('获取数据成功:', res.data);
  },
  fail: function (error) {
    console.log('获取数据失败:', error);
  }
});

// 同步方法
uni.setStorageSync('projectId', this.projectId);  // 缓存数据
let x = uni.getStorageSync('projectId');  // 提取数据

下拉单选框组件的使用#

选择使用 uniapp 社区的select-lay - DCloud 插件市场 插件。该插件可以实现自定义数据索引对象,对于一些传入复杂的数据结构单选展示具有很好的效果。

<select-lay :value="tval" name="name" :options="datalist" @selectitem="selectitem"></select-lay>

自定义数据结构的写法为:

<select-lay :zindex="998" :value="choicedID" name='Name' placeholder="请选择拓扑名称"
    slabel="t_name" svalue="t_id"
    :options="project" @selectitem="choicet_Name"></select-lay>

value 要与选择框最终传给的变量值相同,否则选择之后在 UI 上面无法显示选择后的结果。

组件层级设置#

在 UI 中不同组件显示过程中,通过参数设置不同的层可以使一部分组件显示在另一部分组建的上方。

uniapp 中部分组件可以通过z-index参数来设置组件的层级。z-index 属性设置元素在渲染时的 z 轴顺序。在同一个层叠上下文下 z-index 较大的元素会覆盖在 z-index 较小的元素上面。简单来说,就是当该参数设置的值越大,则会显示在更上层。

app 端 z-index 默认值为 0,web 端默认值为 auto。

z-index | uni-app-x (dcloud.net.cn)

props 参数的使用#

props 可以是数组或对象,用于接收来自父组件的数据。props 可以是简单的数组,或者使用对象作为替代,对象允许配置高级选项,如类型检测、自定义验证和设置默认值。

表单检查与校验#

.some 方法

.some() 方法是 JavaScript 数组的一个方法,用于测试数组中的元素是否至少有一个满足提供的测试函数。如果至少有一个元素让测试函数返回 true,那么 .some() 方法就会返回 true;否则返回 false

// 是否有任何数字大于 10
const numbers = [1, 5, 10, 15, 20];
const hasNumberGreaterThanTen = numbers.some(number => number > 10);
console.log(hasNumberGreaterThanTen); // 输出: tr

检查对应两组变量之间是否相同

// 检查哪些属性发生了改变
const changedProperties = ['email', 'nickname', 'phone'].some(prop => {
    return this.accountForm[prop] !== this.profile[prop];
});

弹窗的实现#

Popup 弹出层 | uView 2.0 - 全面兼容 nvue 的 uni-app 生态框架 - uni-app UI 框架 (uviewui.com)

通过 uview 中 u-popup 组件实现

<u-popup :show="popShow" mode="center">
        <view >
            <text>确认取消?</text>
            <u-button  type="primary" style="margin-top: 5rpx;" text="返回" @click="popShow = false"></u-button>
            <u-button type="error" style="margin-top: 5rpx;" text="确认" @click="cancelAppoint(cancelId)"></u-button>
        </view>
</u-popup>

弹出消息后延时跳转#

uni.showToast({
    title: ' 预约成功!',
    duration: 1000
});
setTimeout(function() {
    uni.reLaunch({
        url: '/pages/tabBar/home/index'
    });
}, 1000);

post 传递 query 形式数据#

问题#

使用 post 携带 query 数据发送请求。

背景#

使用 uview 发送请求,默认是可以提前对请求进行设置。下面是 uview 官网提供的配置。通过定义并导出配置即可实现在对所有请求的全局配置。在不配置 headers 中 datatype 的情况下,uview 默认 post 发送的是 body 的请求。如果要使用 post 请求发送数据则需要修改 headers 中 Content-Type 的值。

const install = (Vue, vm) => {
    baseURL: '',
    header: {},
    method: 'GET',
    dataType: 'json',
    // #ifndef MP-ALIPAY
    responseType: 'text',
    // #endif
    // 注:如果局部custom与全局custom有同名属性,则后面的属性会覆盖前面的属性,相当于Object.assign(全局,局部)
    custom: {}, // 全局自定义参数默认值
    // #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
    timeout: 60000,
    // #endif
    // #ifdef APP-PLUS
    sslVerify: true,
    // #endif
    // #ifdef H5
    // 跨域请求时是否携带凭证(cookies)仅H5支持(HBuilderX 2.6.15+)
    withCredentials: false,
    // #endif
    // #ifdef APP-PLUS
    firstIpv4: false, // DNS解析时优先使用ipv4 仅 App-Android 支持 (HBuilderX 2.8.0+)
    // #endif
    // 局部优先级高于全局,返回当前请求的task,options。请勿在此处修改options。非必填
    // getTask: (task, options) => {
    // 相当于设置了请求超时时间500ms
    //   setTimeout(() => {
    //     task.abort()
    //   }, 500)
    // },
    // 全局自定义验证器。参数为statusCode 且必存在,不用判断空情况。
    validateStatus: (statusCode) => { // statusCode 必存在。此处示例为全局默认配置
        return statusCode >= 200 && statusCode < 300
    }
}

解决方法#

post 发送 query 请求时 headers 中 Content-Type 的值为application/x-www-form-urlencoded, 而发送 body 请求时值为application/json。由于上述为全局设置,而项目中使用 post 发送 query 形式的数据较少,因此,可以在发送 query 请求时单独设置 headers 中 Content-Type 的值。

// query形式的http传参
export function http_a_post_query(path,params){	
	let formBody = Object.keys(params).map(key => key + '=' + params[key]).join('&');
	console.log('http_a_post=', projectConfig.baseUrl_a + path);
	return http.post(projectConfig.baseUrl + path, params,{header:{'content-type': 'application/x-www-form-urlencoded'}});
}

图片上传#

  • 使用 uni.chooseImage 从文件中选择图片,并使用 uni.uploadFile 上传图片。选择图片结束后。

    获取文件路径后,以content-type=multipart/form-data的形式,使用 post 协议上传至服务器。同时,接收服务器返回的图片地址。

		uploadPic() {
			uni.chooseImage({
				count: 1,
				sizeType: ['original', 'compressed'],
				success: res => {
					console.log(projectConfig.baseUrl + '/v1/dms/upload/picture/local');
					uni.uploadFile({
						url: projectConfig.baseUrl + '/v1/dms/upload/picture/local',
						filePath: res.tempFilePaths[0],
						name: 'files',
						header: {
							'Authorization': 'Bearer ' + uni.getStorageSync('token'),
						},
						complete: (res) => {
							console.log('res:', JSON.parse(res.data)[0]);
							this.form.device_image = JSON.parse(res.data)[0];
							this.$u.toast('图片上传完毕!');
							this.upPicMsg = '重新上传'
						}
					})
				}
			})
		},

统计图实现#

指南 - uCharts 跨平台图表库

** 思路:** 对后端返回的数据格式化成组件所接受的数据格式,通过图表组件实现。

HTML 部分#

<qiun-data-charts :ontouch="true" type="line" :opts="line_opts2" :localdata="trendData" />
  • :ontouch="true" 表示组件是否应该响应触摸事件。
  • type="line" 指定了图表的类型为折线图。
  • :opts="line_opts2" 是一个包含图表配置的对象,在本地的 js 中设定,例如轴的标签、网格线等。
  • :localdata="trendData" 是一个包含要显示的数据集的对象

数据格式#

第一种格式

    let res = {
        categories: ["2016","2017","2018","2019","2020","2021"],   // 横坐标的标签
        series: [
          {
            name: "目标值",
            data: [35,36,31,33,13,34]    // 第一条数据
          },
          {
            name: "完成量",
            data: [18,27,21,24,6,28]     // 第二条数据
          }
        ]
      };

第二种格式

localdata:[
  {value:35, text:"2016", group:"目标值"},
  {value:18, text:"2016", group:"完成量"},
  {value:36, text:"2017", group:"目标值"},
  {value:27, text:"2017", group:"完成量"},
  {value:31, text:"2018", group:"目标值"},
  {value:21, text:"2018", group:"完成量"},
  {value:33, text:"2019", group:"目标值"},
  {value:24, text:"2019", group:"完成量"},
  {value:13, text:"2020", group:"目标值"},   // 根据group类确定两类或是多类数据
  {value:6, text:"2020", group:"完成量"},
  {value:34, text:"2021", group:"目标值"},
  {value:28, text:"2021", group:"完成量"}
]

表格的实现#

问题#

uniapp 自带的表格无法完成合并单元格等操作,直接使用 rowspancolspan 会在不同端中产生兼容性问题。

uniapp uni-table 表格组件 合并单元格_uni-table 合并单元格 - CSDN 博客

方法#

直接使用 HTML 中的table、tr、td标签来实现。需要注意的是:v-for 不能在以下标签里使用:

thead
tbody
tfoot
th
td

在实际使用中如果希望使用循环来显示后端返回的不同长度的数据,可以在外侧再嵌套一层。

<template v-for="(type, typeIndex) in deviceParam">
    <tr :key="typeIndex">
        <!-- 类型标题行,使用rowspan属性来合并单元格 -->
        <th :rowspan="type.deviceParamInfoVos.length + 1">
            {{ type.device_param_type_name }}
        </th>
        <!-- 使用v-for遍历每个参数 -->
    <tr v-for="param in type.deviceParamInfoVos" :key="param.device_param">
        <td>{{ param.device_param_name }}</td>
        <td>{{ param.device_param_value + param.device_param_unit }}</td>
    </tr>
    </tr>
</template>

[HTML 表格基础 - 学习 Web 开发 | MDN (mozilla.org)](

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。