详解uniapp的全局变量实现方式_javascript技巧

这篇具有很好参考价值的文章主要介绍了详解uniapp的全局变量实现方式_javascript技巧。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

本文整理了一些uniapp全局变量的实现方式,细节知识来自于uView官网中对uniapp中的全局变量实现,感兴趣的同学可以前往uView官网搜索vuex进行查看

全局变量的实现方式

一般来说在uniapp中有以下几种方式

本地存储
配置文件
挂载到 Vue.prototype
globalData
vuex
下面对这5种方式的实现进行介绍

本地存储

永久存储,以app为例即使该应用被关闭,该数据依然会被存储

这是一种永久的存储方式,类似于web的Local Storage(有关于Cookie、Token、SessionStorage、LocalStorage,会整理在另一篇文章中),当我们需要永久存储用户的某一信息时会使用这种方法,但是需要注意使用这种方式需要避免对存储数据的频繁获取和修改操作,因为会对性能产生一定的影响,应用声明周期内的变量,不应该使用此种方式

这种存储方式有 同步和异步两种

同步存储

//同步存储
  uni.setStorageSync("key","value")
  //同步获取
  let value = uni.getStorageSync("key")  
  console.log("我会等到上边执行完毕后才会执行)

异步存储

uni.setStorage({
   key:"key",
    data:"value",
    success:function(){
      //存储成功的回调
      console.log("我是异步存储的回调,我会在val声明后被执行")
    }
  })
  let val = 1//这行会先执行
  
  uni.getStorage({
   key:"key",
    success:function(res){
      //存储成功的回调
      console.log("我是异步获取的回调,我会在val2声明后被执行")
    }
  })
  let val2 = 2//这行会先执行

配置文件

这是一种利用模块化文件导出实现的方式,先将变量写在js文件中,然后通过export default的形式导出使用

一般来说使用这种方式实现的全局变量,是需要在应用被用户安装之前到用户卸载时都必须使用的变量,如向后端请求的域名,其他的情况不太适用这种方式,同时这种方式也有弊端,就是每次使用都需要引入文件

config.js

//如在config.js中 我们导出了一个基础域名
  export default{
   baseUrl:"http://www.test.com"
  }

index.js

 //通过import引入这个文件
  import config from "../common/config.js"
  export default {
    onLoad(){
     console.log(config.baseUrl)//baseUrl:"http://www.test.com"
    }
  }

挂载到Vue.prototype

这是一种利用原型的实现方式(有关于js的原型链和继承,会在整理在另一篇文章中),但是这种方式在微信小程序上会有特殊表现

注意:在微信小程序中 模板无法直接读取展示引入的全局变量
main.js

//这里的config.js参照上文已经写好的文件
  import config from "./common/config.js"
  //将baseUrl挂载到Vue上,此后在页面和组件中就可以通过this.baseUrl的方式去访问
  Vue.prototype.baseUrl = config.baseUrl

页面中

<template>
 <!-- 微信小程序中值为undefined,其他端有效 -->
 <view>
 值为:{{this.baseUrl}}
 </view>
</template>

<script>
 export default {
 onLoad() {
    console.log(this.baseUrl)//"http://www.test.com"
 }
 }
</script>

globalData

这种方式是微信小程序特有的,小程序无法使用vuex因此出现了globalData,uniapp是小程序另一种实现因此也出现了globalData

使用globalData有以下几点需要注意的地方:

globalData不是响应式的,一个文件中对globalData的修改,不会动态的在另一个文件中响应
如果想实现globalData的"响应",你需要在onShow的生命周期中手动获取值
对第二点进行解释,为什么需要在onShow里去获取值onLoad不行么?

因为如果A、B页面都引入了globalData,B在页面内部修改了globalData的值返回A页面,此时A页面没有被销毁不会调用onLoad生命钩子,只会执行onShow此时在onLoad里去获取globalData,那么是不会执行的,也就无法做到响应式

App.vue

 export default{
   //需要在App.vue中去定义globalData
   globalData:{
     userName:"白居易"
    },
    //这里需要注意,如果想要在App.vue中使用globalData,不能直接使用getApp().globalData.Name,因为此时getApp()未有生成
    // 1. 非V3模式,可以通过this.$scope.globalData获取
   // 2. V3模式,可以通过getApp({allowDefault: true}).globalData获取
    onLaunch(){
     console.log(this.$scope.globalData.userName)
    }
  }

当在App.vue中定义好globalData后我们就可以在页面中使用了
A.vue

<template>
 <view>
 <view>
  <!-- 注意,不能在模板中直接使用 getApp().globalData.userName -->
  <<卖炭翁>>的作者是:{{author}}
 </view>
 <view>
  <u-button @click="modifyUserName">修改userName值</u-button>
 </view>
 </view>
</template>

<script>
 export default {
 data() {
  return {
  author: ''
  }
 },
 onShow() {
  // 每次A.vue出现在屏幕上时,都会触发onShow,从而更新author值
  this.author = getApp().globalData.userName;
 },
 methods: {
  modifyUserName() {
                //此时修改了globalData的值
  getApp().globalData.userName = "诗圣"// 修改userName后,本页的author依然不会自动刷新,因为globalData不是响应式的
  // 我们仍然需要手动刷新本页的author值,由此可见globalData的弊端
  this.author = getApp().globalData.userName;
  }
 }
 }
</script>

Vuex的实现方式

强烈建议使用vuex的方式,在uniapp使用vuex有两种方式,一种是基于传统vue的方式,一种是uView封装后的方式,下面介绍uView官网对vuexd的封装

传统实现方式

传统vuex的使用方式,这里只做简单介绍,如果对vuex不了解的同学,可以去vue官网查看官方文档

在uni.app的根目录下创建一个store文件,并在其中创建一个index.js文件 内容如下

//index.js
  import Vue from "vue"
  import Vuex from "vuex"
  Vue.use(Vuex)
  const store = new Vuex.Store({
   state:{
     vuex_token:"123456"
    },
    //同步修改 state 中值的方法
    mutations:{
     //payload使用户在使用mutations是传入的参数,可以使单一值也可以是对象
     modifyToken(state,payload){
       state.vuex_token = payload.token
      }
    }
  })
  export default store

在main.js中引入

import store from '@/store';

// 将store放入Vue对象创建中
const app = new Vue({
 store,
 ...App
})

在页面中使用

<template>
 <view>
 <view>
  Token值为{{vuex_token}}
 </view>
 <u-button @click="btnClick">修改vuex_token</u-button>
 </view>
</template>

<script>
//这是Vue官方为了更方便使用store提供的api,详情可以去Vue官方查看文档
import {mapState, mapMutations} from 'vuex'; 
export default {
 computed: { 
 ...mapState(['vuex_token']) 
 }, 
 methods: { 
 ...mapMutations(['modifyToken']),
 btnClick() {
  // 这里第二个参数可以普通变量或者对象,自定义的,根据mutations需求处理(不使用mapMutations的方式)
  this.$store.commit('modifyToken', {token: 'xxxyyyzzz'}
            //使用mapMutations的方式
            this.modifyToken({token: 'xxxyyyzzz'})
 }
 } 
}
</script>

uView的vuex实现方式(重点)

首说为什么uView对vuex进行了封装,原因有以下两点

uView觉得需要在vuex中定义state和mutations,在每个需要用到vuex的地方都需要引入mapState进行解构,然后再次使用(操作繁琐)
因为vuex是将变量保存在内存中的,刷新浏览器就会导致vuex变量消失,一般还需要配合其他的存储方式进行使用如LocalStorage
针对这些问题uView官方提供了自己封装使用vuex的一套方法,这个方法结合LocalStorage、vuex,使得用户不必再去繁琐的调用vuex和考虑刷新丢失的问题,下面我将代码展示,并将其思路和过过程解释

先在根目录下创建一个index.js文件,写入以下内容,开头我会先提供大致思路具体含义之后会在注释中解释
思路:index.js的大致思路如下

a. 为了解决vuex刷新丢失无法永久存储数据的问题,创建了一个lifeData对象,这个对象会通过函数,将其存储在LocalStorage中,以达到永久保存的效果,此时我只需要将vuex中需要永久保存的数据,以key、value的形式存储在这个对象中就可以了

b. 为了解决每次使用vuex都需要使用mutations中的函数去操作对应的stroe中的变量,封装了$uStore这一个方法去操作所有的store中的变量,当然只进行了简单的复制操作,对于更拓展的功能,用户可以自己在mutations中去封装函数进行拓展

c. 封装一个saveStateKeys数组,这个数组的数据会在app启动时就会被取出,因此我们可以把一些需要app启动时就获取的数据放在其中,如应用中上次用户已经登陆的信息,实际上saveStateKeys和lifeData是配合使用的,只有存在saveStateKeys中的变量,才会在存储时被存储在lifeData中以达到永久的存储,其他的就和普通vuex存储方式一样,对于这点我们可以在下述代码中看到

//引入Vuex、vue 使用Vuex,这一步和一般使用vuex没有区别
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

//创建一个变量,这个变量用于存储需要永久存储的数据
let lifeData = {};

try{
  // 尝试获取本地是否存在lifeData变量,第一次启动APP时是不存在的
  lifeData = uni.getStorageSync('lifeData');
}catch(e){
 
}

// 需要永久存储,且下次APP启动需要取出的,在state中的变量名
let saveStateKeys = ['vuex_user', 'vuex_token'];

// 保存变量到本地存储中(达到刷新/重启(app不存在刷新,app只会重启)不丢失)
const saveLifeData = function(key, value){
 // 判断变量名是否在需要存储的数组中
  //这一条就是在判断如果变量名存储在saveStateKeys中,那么就将其存储在lifeData中达到永久存储,否则就和一般vuex的存储方式一样
 if(saveStateKeys.indexOf(key) != -1) {
 // 获取本地存储的lifeData对象,将变量添加到对象中
 let tmp = uni.getStorageSync('lifeData');
 // 第一次打开APP,不存在lifeData变量,故放一个{}空对象
 tmp = tmp ? tmp : {};
 tmp[key] = value;
 // 执行这一步后,所有需要存储的变量,都挂载在本地的lifeData对象中
 uni.setStorageSync('lifeData', tmp);
 }
}
const store = new Vuex.Store({
 // 下面这些值仅为示例,使用过程中请删除
 state: {
 // 如果上面从本地获取的lifeData对象下有对应的属性,就赋值给state中对应的变量
 // 加上vuex_前缀,是防止变量名冲突,也让人一目了然 
 // 被永久存储的数据会从lifeData中去获取,因为lifeData已经存储在了本地中
 vuex_user: lifeData.vuex_user ? lifeData.vuex_user : {name: '明月'},
 vuex_token: lifeData.vuex_token ? lifeData.vuex_token : '',
 // 如果vuex_version无需保存到本地永久存储,无需lifeData.vuex_version方式
 vuex_version: '1.0.1',
 },
 mutations: {
 $uStore(state, payload) {
            //payload就是后来调用的this.$u.vuex时传入的对象
            //如this.$u.vuex("user.info.score","jack") payload = {name:"user.info.score",value:"jack"}
  // 判断是否多层级调用,state中为对象存在的情况,诸如user.info.score = 1
  let nameArr = payload.name.split('.');//[user,info,score]
  let saveKey = '';
  let len = nameArr.length;
  if(nameArr.length >= 2) {
  let obj = state[nameArr[0]];
  for(let i = 1; i < len - 1; i ++) {
   obj = obj[nameArr[i]];// 此时obj就是user.info,当然此时他还是一个空数据
  }
                //nameArr[len-1]就是score,obj[nameArr[len - 1]]相当于 user.info.score
  obj[nameArr[len - 1]] = payload.value;
  saveKey = nameArr[0];
  } else {
  // 单层级变量,在state就是一个普通变量的情况
  state[payload.name] = payload.value;
  saveKey = payload.name;
  }
  // 保存变量到本地,见顶部函数定义
  saveLifeData(saveKey, state[saveKey])
 }
 }
})
export default store

在同目录下创建 mixin.js文件

思路:
a. 为了能够在每个页面都能通过this.的方式使用变量,我们需要将mapState通过Vue mixin的方式进行全局混入
b. 为了能够在每个页面都能轻松的调用vuex中的mutations里的方法,我们需要一个方法能够帮我们去调用uStore,而不是每次都通过commit的方式,因此uView还混入了另一个方法$u.vuex

ps: minxi(混入)是Vue提供的一种实现全局功能的一个api,混入有多种方式这里使用了全局混入,如果对于混入不是很了解可以去Vue官网查看相关文档

//mixin.js
import { mapState } from 'vuex'
import store from "@/store"

// 尝试将用户在根目录中的store/index.js的vuex的state变量,全部加载到全局变量中
let $uStoreKey = [];
try{
 $uStoreKey = store.state ? Object.keys(store.state) : [];
}catch(e){
 
}

module.exports = {
 created() {
 // 将vuex方法挂到this.$u上
 // 使用方法为:如果要修改vuex的state中的user.name变量为"史诗" => this.$u.vuex('user.name', '史诗')
 // 如果要修改vuex的state的version变量为1.0.1 => this.$u.vuex('version', '1.0.1')
 this.$u.vuex = (name, value) => {
  this.$store.commit('$uStore', {
  name,value //这里有没有回忆起来$uStore传入的payload haha 
  })
 }
 },
 computed: {
 // 将vuex的state中的所有变量,解构到全局混入的mixin中
 ...mapState($uStoreKey)
 }
}

开始全局混入,在main.js中引入 mixin.js文件进行混入

//main.js
let vuexStore = require("@/store/$u.mixin.js");
Vue.mixin(vuexStore);

将store放到Vue实例中

//main.js
import store from '@/store';

// 将store放入Vue对象创建中
const app = new Vue({
 store,
 ...App
})

结语

以上就是uView官方对vuex的封装,在app开发中使用这种封装后的vuex很便捷,同时自身也可以根据需要在@/stote/index.js中去拓展自己的方法
此博文出自网络,非本人所写,如有侵权联系删除。
原文:https://juejin.cn/post/6916074986276913166文章来源地址https://www.toymoban.com/news/detail-730492.html

到了这里,关于详解uniapp的全局变量实现方式_javascript技巧的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • uniapp主题切换功能的第一种实现方式(scss变量+vuex)

    随着用户端体验的不断提升,很多应用在上线的时候都要求做不同的主题,最基本的就是白天与夜间主题。 就像b站app主题切换,像这样的 uniapp因为能轻松实现多端发布而得到很多开发者的青睐,但每个端的实现也有可能不同,现我把已实现的功能一点点的大家分享给大家,

    2024年02月08日
    浏览(36)
  • JavaScript保留字和预定义的全局变量及函数汇总

    保留字也称,每种语言中都有该语言本身规定的一些,这些都是该语言的语法实现基础,JavaScript中规定了一些标识符作为现行版本的或者将来版本中可能会用到的,所以当我们定义标识符时就不能使用这些了,下面介绍下JavaScript保留

    2024年01月16日
    浏览(49)
  • C语言编程技巧 全局变量在多个c文件中公用的方法

    在使用C语言编写程序时,经常会遇到这样的情况:我们希望在头文件中定义一个全局变量,并将其包含在两个不同的C文件中,以便这个全局变量可以在这两个文件中共享。举个例子,假设项目文件夹\\\"project\\\"下有三个文件:main.c、common.c和common.h。在这种情况下,我们希望声明

    2024年02月14日
    浏览(26)
  • 【Postman】Postman接口测试进阶用法详解:断言、全局与环境变量、关联、批量执行用例、读取外部文件实现参数化

    Postman断言使用JavaScript语言编写,写在Postman的【Tests】 标签中。 【Tests】中的脚本在发送请求之后执行,它会把断言的结果(PASS/FAIL)最终在【Test Results】 标签页中。 断言响应状态码是否为200(Status code is 200) 断言响应体JSON数据校验(Response body:JSON value check) 断言响应体

    2024年02月15日
    浏览(45)
  • 欧姆龙SysmacStudio 关于模块化编程的使用技巧---全局变量和数据类型

    在平常使用欧姆龙SysmacStudio 编程时,有新建大量的结构体和全局变量,若不分类进行模块化,会造成查找不方便,下面分享的就是对全局变量和数据类型进行模块分类,方便查找,提高编程效率。 下图中是新建的一个系统周期时钟频率的FB块 为了方便在程序中使用,将FB的输

    2024年02月06日
    浏览(53)
  • Vue3使用全局函数或变量的两种常用方式

    例如:想要在index.ts中创建getAction函数,并可以全局使用: 方式一:使用依赖注入(provide/inject) 在main.ts中进行挂载: 在要使用的页面注入: 方式二:使用 app.config.globalProperties 和 getCurrentInstance() app.config.globalProperties:一个用于注册能够被应用内所有组件实例访问到的全局

    2024年02月12日
    浏览(31)
  • 解决分类变量问题的完整指南:处理方式及技巧

    本指南探讨了处理分类变量的不同方法,包括标签编码、二值化和独热编码,并比较了它们在内存占用上的差异。了解如何优化分类变量处理,提高模型性能。

    2024年02月22日
    浏览(27)
  • 关于uniapp全局挂载变量/方法的问题,没遇到过点进来吧,记录一下我踩过的坑。

    事情是这样的,我在用uniapp做一个微信小程序,遇到了个问题,是在封装uni.request()到全局方法的时候,其实就很简单的,是关于 this的指向问题 (若想了解此问题的话,点这里去看大佬的文章!!!) ,找几个小时的博客都未能解决。 建uniapp项目时用了vue3,那么就要遵

    2024年02月16日
    浏览(39)
  • 史上最详细的vite引入scss全局变量详解

    我们经常因为某些变量不能全局引入而头疼如麻,尤其是在做一些统一样式的时候,简直是噩梦,而且网上乱七八糟的文章很多很多,但是真正教你配置的没几个,因为很多都是复制过来的,有些人为了赶时间随便复制一下,这里将为你提供史上最详细的引入流程 第三步:创

    2024年02月16日
    浏览(27)
  • uniapp引入全局js,vue2/vue3不同方式引入

    Hi I’m Shendi uniapp引入全局js,vue2/vue3不同方式引入 最近写小程序,个人开发,选用了 uni-app 进行开发 选用的 vue3 版本 因为我用的 vue3 版本,在这里踩了没学过vue3的坑,用vue2引入全局js的方式使用,导致undefined… Vue2 版引入全局js的方法如下 将js放到项目内,一般放到自建的

    2024年02月03日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包