HarmonyOS官网案例解析——保存应用数据

介绍

本篇Codelab将介绍如何使用基础组件Slider,通过拖动滑块调节应用内字体大小。要求完成以下功能:

  1. 实现两个页面的UX:主页面和字体大小调节页面。
  2. 拖动滑块改变字体大小系数,列表页和调节页面字体大小同步变化。往右拖动滑块字体变大,反之变小。
  3. 字体大小支持持久化存储,再次启动时,应用内字体仍是调节后的字体大小。

最终效果图如图所示:

https://gitee.com/runitwolf/sloop-pic-go/raw/master/image/202312212240377.gif

一、相关概念

  • 字体大小调节原理:通过组件Slider滑动,获取滑动数值,将这个值通过首选项进行持久化,页面的字体通过这个值去改变大小。
  • 首选项:首选项为应用提供Key-Value键值型的数据处理能力,支持应用持久化轻量级数据,并对其修改和查询。

二、完整实例

gitee源码地址

ps:官网的案例很简单,但是有很多地方值得我们借鉴。

官方对案例解析

<HarmonyOS第一课>保存应用数据

三、零基础实战开发

一、用数组的方法值得借鉴

  1. 现新建一个bean类
export default class SettingData{
  settingName:string
  settingImage:Resource
}
  1. 新建HomeViewModel.etx
import SettingData from './SettingData'

export class HomeViewModel {
  settingArr: SettingData[] = []

  initSettingData(): SettingData[] {
    if (this.settingArr.length === 0) {
      let settingData = new SettingData()
      settingData.settingName = '显示和亮度'
      settingData.settingImage = $r('app.media.ic_display_and_brightness')
      this.settingArr.push(settingData)

      settingData = new SettingData();
      settingData.settingName = '声音';
      settingData.settingImage = $r('app.media.ic_voice');
      this.settingArr.push(settingData);

      settingData = new SettingData();
      settingData.settingName = '应用管理';
      settingData.settingImage = $r('app.media.ic_app_management');
      this.settingArr.push(settingData);

      settingData = new SettingData();
      settingData.settingName = '存储';
      settingData.settingImage = $r('app.media.ic_storage');
      this.settingArr.push(settingData);

      settingData = new SettingData();
      settingData.settingName = '隐私';
      settingData.settingImage = $r('app.media.ic_privacy');
      this.settingArr.push(settingData);

      settingData = new SettingData();
      settingData.settingName = '设置字体大小';
      settingData.settingImage = $r('app.media.ic_setting_the_font_size');
      this.settingArr.push(settingData);

    }
    return this.settingArr
  }
}
export default new HomeViewModel()

在index.ets中直接使用即可使用方法如下

 settingArr = HomeViewModel.initSettingData();
 //settingArr[x],x为数组的索引,直接使用就可以获取设定的数据

1."标题"页面实现

import { TitleBarComponent } from '../view/TitleBarComponent'

@Entry
@Component
struct Index {
  build() {
    Column() {
      TitleBarComponent({ isBack: false, title: '设置' })
    }
    .width('100%')
    .height('100%')
  }
}
import router from '@ohos.router'
@Component
export struct TitleBarComponent {
  isBack:boolean = true
  title:string = ''

  build() {
    Row() {
      if (this.isBack){
        Image($r('app.media.ic_public_back'))
          .width(24)
          .height(24)
          .margin({ right: 4 })
          .onClick(() => {
            router.back()
          })
      }
      Text(this.title)
        .fontColor(Color.Black)
        .fontSize($r('sys.float.ohos_id_text_size_headline8'))
        .fontWeight(FontWeight.Medium)
        .margin({ left: 8 })
    }
    .width('100%')
    .height('7.2%')
    .padding({ left: 16 })
  }
}

在这里插入图片描述

2."显示和亮度"页面实现

import SettingItemComponent from '../view/SettingItemComponent'
import { TitleBarComponent } from '../view/TitleBarComponent'
import HomeViewModel from '../viewModel/HomeViewModel'
import SettingData from '../viewModel/SettingData'

@Entry
@Component
struct Index {
  settingArr: SettingData[] = HomeViewModel.initSettingData()
  @State changeFontSize: number = 16

  build() {
    Column() {
      ...
      //显示和亮度
      Row() {
        SettingItemComponent({
          setting: this.settingArr[0],
          changeFontSize: this.changeFontSize,
          itemClick: () => {
            //TODO
          }
        })
      }
      .blockBackground('1.5%')
    }
    .backgroundColor('#f1f3f5')
    .width('100%')
    .height('100%')
  }
}

@Extend(Row) function blockBackground (marginTop: string) {
  .backgroundColor(Color.White)
  .borderRadius(24)
  .margin({ top: marginTop })
  .width('93.3%')
  .padding({ top: 4, bottom: 4 })
}

思考题:这里的changeFontSize变量为什么需要用@State进行修饰,而settingArr又为什么不需要?

3."声音"页面实现

import SettingItemComponent from '../view/SettingItemComponent'
import { TitleBarComponent } from '../view/TitleBarComponent'
import HomeViewModel from '../viewModel/HomeViewModel'
import SettingData from '../viewModel/SettingData'

@Entry
@Component
struct Index {

  build() {
    Column() {
      TitleBarComponent({ isBack: false, title: '设置' })
      ...
      //声音
      Row() {
        SettingItemComponent({
          setting: this.settingArr[1],
          changeFontSize: this.changeFontSize,
          itemClick: () => {
            //TODO
          }
        })
      }
      .blockBackground('1.5%')
    }
    .backgroundColor('#f1f3f5')
    .width('100%')
    .height('100%')
  }
}

4.“应用管理”、"存储"等列表页面实现

import SettingItemComponent from '../view/SettingItemComponent'
import { TitleBarComponent } from '../view/TitleBarComponent'
import HomeViewModel from '../viewModel/HomeViewModel'
import SettingData from '../viewModel/SettingData'

@Entry
@Component
struct Index {
  settingArr: SettingData[] = HomeViewModel.initSettingData()
  @State changeFontSize: number = 16

  build() {
    Column() {
     ...
      Row(){
        this.SettingItems()
      }
      .blockBackground('1.5%')
    }
    ...
  }

  @Builder SettingItems(){
    List(){
      ForEach(this.settingArr.splice(2,6),(item:SettingData,index:number)=>{
        ListItem(){
          SettingItemComponent({setting:item,changeFontSize:this.changeFontSize,itemClick:()=>{
            //TODO
          }})
        }
      }, (item:SettingData,index:number)=>JSON.stringify(item)+index)
    }
  }
}

5."设置字体大小"点击事件跳转

import router from '@ohos.router'
import PreferencesUtil from '../common/database/PreferencesUtil'
import SettingItemComponent from '../view/SettingItemComponent'
import { TitleBarComponent } from '../view/TitleBarComponent'
import HomeViewModel from '../viewModel/HomeViewModel'
import SettingData from '../viewModel/SettingData'

@Entry
@Component
struct Index {
  settingArr: SettingData[] = HomeViewModel.initSettingData()
  @State changeFontSize: number = 16

  onPageShow(){
    PreferencesUtil.getChangeFontSize().then((value)=>{
      this.changeFontSize = value
    })
  }

  build() {
	....
  @Builder SettingItems(){
    List(){
      ForEach(this.settingArr.splice(2,6),(item:SettingData,index:number)=>{
        ListItem(){
          SettingItemComponent({setting:item,changeFontSize:this.changeFontSize,itemClick:()=>{
            if (index === 3) {
              router.pushUrl({
                url:"pages/SetFontSizePage"
              })
            }
          }})
        }
      }, (item:SettingData,index:number)=>JSON.stringify(item)+index)
    }
  }
}

在pages目录下新建SetFontSizePage子组件

import  PreferencesUtil  from '../common/database/PreferencesUtil'
import { ItemComponent } from '../view/ItemComponent'
import { SliderLayout } from '../view/SliderLayout'
import { TitleBarComponent } from '../view/TitleBarComponent'
import HomeViewModel from '../viewModel/HomeViewModel'
import SettingData from '../viewModel/SettingData'

@Entry
@Component
struct SetFontSizePage {

  build() {
    Column() {
      TitleBarComponent({ title: '字体大小设置' })
    }
    .width('100%')
    .height('100%')
  }
}

ps:官网的案例不太友好,我们在官网的页面基础上进行功能及界面简化

6.SetFontSizePage页面创建数据

我们之前在首页HomeViewModel模型下创建过数据,我们沿用HomeViewModel模型,继续创建想要的数据

import SettingData from './SettingData'

export class HomeViewModel {
  ...
  fontSizeArr: SettingData[] = []
  ...

  initFontSizeData():SettingData[]{
    this.fontSizeArr = new Array();
    let fontSizeArr = new SettingData()
    fontSizeArr.settingName = '11111111111111111111'
    this.fontSizeArr.push(fontSizeArr)
    fontSizeArr = new SettingData()
    fontSizeArr.settingName = '22222222222222222222'
    this.fontSizeArr.push(fontSizeArr)
    fontSizeArr = new SettingData()
    fontSizeArr.settingName = '33333333333333333333'
    this.fontSizeArr.push(fontSizeArr)
    fontSizeArr = new SettingData()
    fontSizeArr.settingName = '44444444444444444444'
    this.fontSizeArr.push(fontSizeArr)

    return this.fontSizeArr
  }
}
export default new HomeViewModel()

7.写SetFontSizePage中list页面

import  PreferencesUtil  from '../common/database/PreferencesUtil'
import { ItemComponent } from '../view/ItemComponent'
import { SliderLayout } from '../view/SliderLayout'
import { TitleBarComponent } from '../view/TitleBarComponent'
import HomeViewModel from '../viewModel/HomeViewModel'
import SettingData from '../viewModel/SettingData'

@Entry
@Component
struct SetFontSizePage {
  contentArr: SettingData[] = HomeViewModel.initFontSizeData()
  @State changeFontSize: number = 0

  onPageShow(){
    PreferencesUtil.getChangeFontSize().then((value)=>{
      this.changeFontSize = value
    })
  }

  build() {
    Column() {
      TitleBarComponent({ title: '字体大小设置' })
      List() {
        ForEach(this.contentArr, (item: SettingData, index: number) => {
          ListItem() {
            ItemComponent({ contentArr: item, changeFontSize: this.changeFontSize })
          }

        }, (item: SettingData, index: number) => JSON.stringify(item) + index)
      }
    }
    .width('100%')
    .height('100%')
  }
}
import SettingData from '../viewmodel/SettingData'
@Component
export struct ItemComponent {

  contentArr: SettingData
  @Prop changeFontSize:number

  build() {
    Column() {
      Text(this.contentArr.settingName)
        .fontSize(this.changeFontSize)
        .fontColor('#182431')
        .fontWeight(FontWeight.Medium)
        .height(48)
        .width('100%')
        .textAlign(TextAlign.Center)
    }
  }
}

看看list的效果图:

8.写SetFontSizePage进度条

import  PreferencesUtil  from '../common/database/PreferencesUtil'
import { ItemComponent } from '../view/ItemComponent'
import { SliderLayout } from '../view/SliderLayout'
import { TitleBarComponent } from '../view/TitleBarComponent'
import HomeViewModel from '../viewModel/HomeViewModel'
import SettingData from '../viewModel/SettingData'

@Entry
@Component
struct SetFontSizePage {
	...
  build() {
    Column() {
     ...
      List() {
        ...
      }
      SliderLayout({changeFontSize:$changeFontSize})
    }
    ...
  }
}
import PreferencesUtil from '../common/database/PreferencesUtil'
@Component
export struct SliderLayout {

  @Link changeFontSize:number

  build() {
    Column() {
      Text('文字大小')
        .fontSize(14)
        .fontColor('#182431')
        .fontWeight(FontWeight.Medium)

      Row(){
        Text('A')
          .fontColor('#182431')
          .fontSize(20)
          .fontWeight(FontWeight.Medium)
          .textAlign(TextAlign.End)
          .width('12.5%')
          .padding({right:9})

        Slider({
          value:this.changeFontSize,
          min:14,
          max:22,
          step:2,
          style:SliderStyle.InSet
        })
          .showSteps(true)
          .width('75%')
          .onChange((value:number)=>{
            this.changeFontSize = value
          })

        Text('A')
          .fontColor('#182431')
          .fontSize(20)
          .fontWeight(FontWeight.Medium)
          .width('12.5%')
          .padding({left:9})
      }

    }
  }
}

运行后效果图如下:
在这里插入图片描述

至此,我们发现滑动进度条,页面的大小变了,但是返回页面后再次进入,数据没有保存。

四、保存应用数据

<HarmonyOS第一课>保存应用数据(官网文档)

根据官网的文档,我们新建PreferencesUtil工具类

import dataPreferences from '@ohos.data.preferences';
import { GlobalContext } from '../utils/GlobalContext';
import Logger from '../utils/Logger';

const TAG = '[PreferencesUtil]';
const PREFERENCES_NAME = 'myPreferences';
const KEY_APP_FONT_SIZE = 'appFontSize';

/**
 * The PreferencesUtil provides preferences of create, save and query.
 */
export class PreferencesUtil {
  createFontPreferences(context: Context) {
    let fontPreferences: Function = (() => {
      let preferences: Promise<dataPreferences.Preferences> = dataPreferences.getPreferences(context, PREFERENCES_NAME);
      return preferences;
    });
    GlobalContext.getContext().setObject('getFontPreferences', fontPreferences);
  }

  saveDefaultFontSize(fontSize: number) {
    let getFontPreferences: Function = GlobalContext.getContext().getObject('getFontPreferences') as Function;
    getFontPreferences().then((preferences: dataPreferences.Preferences) => {
      preferences.has(KEY_APP_FONT_SIZE).then(async (isExist: boolean) => {
        Logger.info(TAG, 'preferences has changeFontSize is ' + isExist);
        if (!isExist) {
          await preferences.put(KEY_APP_FONT_SIZE, fontSize);
          preferences.flush();
        }
      }).catch((err: Error) => {
        Logger.error(TAG, 'Has the value failed with err: ' + err);
      });
    }).catch((err: Error) => {
      Logger.error(TAG, 'Get the preferences failed, err: ' + err);
    });
  }

  saveChangeFontSize(fontSize: number) {
    let getFontPreferences: Function = GlobalContext.getContext().getObject('getFontPreferences') as Function;
    getFontPreferences().then(async (preferences: dataPreferences.Preferences) => {
      await preferences.put(KEY_APP_FONT_SIZE, fontSize);
      preferences.flush();
    }).catch((err: Error) => {
      Logger.error(TAG, 'put the preferences failed, err: ' + err);
    });
  }

  async getChangeFontSize() {
    let fontSize: number = 0;
    let getFontPreferences: Function = GlobalContext.getContext().getObject('getFontPreferences') as Function;
    fontSize = await (await getFontPreferences()).get(KEY_APP_FONT_SIZE, fontSize);
    return fontSize;
  }

  async deleteChangeFontSize() {
    let getFontPreferences: Function = GlobalContext.getContext().getObject('getFontPreferences') as Function;
    const preferences: dataPreferences.Preferences = await getFontPreferences();
    let deleteValue = preferences.delete(KEY_APP_FONT_SIZE);
    deleteValue.then(() => {
      Logger.info(TAG, 'Succeeded in deleting the key appFontSize.');
    }).catch((err: Error) => {
      Logger.error(TAG, 'Failed to delete the key appFontSize. Cause: ' + err);
    });
  }
}

export default new PreferencesUtil();
export class GlobalContext {
  private constructor() { }
  private static instance: GlobalContext;
  private _objects = new Map<string, Object>();

  public static getContext(): GlobalContext {
    if (!GlobalContext.instance) {
      GlobalContext.instance = new GlobalContext();
    }
    return GlobalContext.instance;
  }

  getObject(value: string): Object | undefined {
    return this._objects.get(value);
  }

  setObject(key: string, objectClass: Object): void {
    this._objects.set(key, objectClass);
  }
}

1.使用前提

需要在entryAbility的onCreate方法获取首选项实例

import UIAbility from '@ohos.app.ability.UIAbility';
import hilog from '@ohos.hilog';
import window from '@ohos.window';
import Logger from '../common/utils/Logger';
import { GlobalContext } from '../common/utils/GlobalContext';
import PreferencesUtil from '../common/database/PreferencesUtil'

export default class EntryAbility extends UIAbility {
  onCreate(want, launchParam) {
 
    PreferencesUtil.createFontPreferences(this.context);
  }
	...
}

2.保存数据

在应用刚启动时,设置字体默认大小

import UIAbility from '@ohos.app.ability.UIAbility';
import hilog from '@ohos.hilog';
import window from '@ohos.window';
import Logger from '../common/utils/Logger';
import { GlobalContext } from '../common/utils/GlobalContext';
import PreferencesUtil from '../common/database/PreferencesUtil'

export default class EntryAbility extends UIAbility {
  onCreate(want, launchParam) {
    ...
    // 设置字体默认大小
    PreferencesUtil.saveDefaultFontSize(16);
  }
	...
}

在滑动进度条后,保存进度条设置的字体大小

import PreferencesUtil from '../common/database/PreferencesUtil'
@Component
export struct SliderLayout {

  @Link changeFontSize:number

  build() {
    ...
        Slider({
         ...
          .onChange((value:number)=>{
            this.changeFontSize = value
            PreferencesUtil.saveChangeFontSize(this.changeFontSize)
          })
        ...
      }
    }
  }
}

3.获取保存的数据

数据都保存了,我们怎么去使用保存的数据呢?

import  PreferencesUtil  from '../common/database/PreferencesUtil'
import { ItemComponent } from '../view/ItemComponent'
import { SliderLayout } from '../view/SliderLayout'
import { TitleBarComponent } from '../view/TitleBarComponent'
import HomeViewModel from '../viewModel/HomeViewModel'
import SettingData from '../viewModel/SettingData'

@Entry
@Component
struct SetFontSizePage {
 ...
  @State changeFontSize: number = 0

  onPageShow(){
    PreferencesUtil.getChangeFontSize().then((value)=>{
      this.changeFontSize = value
    })
  }

}
import router from '@ohos.router'
import PreferencesUtil from '../common/database/PreferencesUtil'
import SettingItemComponent from '../view/SettingItemComponent'
import { TitleBarComponent } from '../view/TitleBarComponent'
import HomeViewModel from '../viewModel/HomeViewModel'
import SettingData from '../viewModel/SettingData'

@Entry
@Component
struct Index {
  ...
  @State changeFontSize: number = 16

  onPageShow(){
    PreferencesUtil.getChangeFontSize().then((value)=>{
      this.changeFontSize = value
    })
  }
  ...
}
...

效果图:
在这里插入图片描述

至此,大功告成~~~撒花

至此,所有功能已全部完成。

代码链接:https://gitee.com/runitwolf/set-app-font-size

typora笔记链接:https://gitee.com/runitwolf/set-app-font-size/blob/master/%E5%BA%94%E7%94%A8%E5%86%85%E5%AD%97%E4%BD%93%E5%A4%A7%E5%B0%8F%E8%B0%83%E8%8A%82.md

CSDN typora笔记链接 :https://download.csdn.net/download/qq_36067302/88671288

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/285376.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

江西速欣商务咨询有限公司:债务规划重组的专业法务咨询服务

在财务管理中&#xff0c;债务问题往往成为个人和企业面临的一项重要挑战。江西速欣商务咨询有限公司作为债务问题的专业解决者&#xff0c;致力于为客户提供高效而专业的债务规划重组法务咨询服务&#xff0c;帮助他们摆脱负担&#xff0c;重整财务秩序。 深谙债务规划的专业智…

通信基站绿色低碳服务认证

据标准编制组代表汇报该标准是在2022年工信部等7部门印发《信息通信行业绿色低碳发展行动计划&#xff08;2022-2025&#xff09;》提出通信基站要向集约化布局、高效化设计、绿色化建设、低碳化技术、智能化运维方向发展。加快形成以管理制度为引领、以绿色采购为关键、以评估…

Rancher 单节点 docker 部署备份与恢复

Rancher 单节点 docker 部署备份与恢复 1. 备份集群 获取 rancher server 容器名&#xff0c;本例为 angry_aryabhata docker ps | grep rancher/rancher6a27b8634c80 rancher/rancher:v2.5.14 xxx angry_aryabhata停止容器 docker stop angry_aryabhata创建备…

桉木芯建筑模板与其他材质比较有何不同?

在建筑行业中&#xff0c;模板的选择对于确保工程质量和效率至关重要。桉木芯建筑模板作为市场上的一种选择&#xff0c;与其他材质的模板相比&#xff0c;具有独特的优势。能强优品木业作为专业的桉木芯建筑模板生产厂家&#xff0c;其产品充分展示了这一材质的优越性能。 材质…

Vue-响应式数据

一、ref创建基本类型的响应式数据 vue3可以使用ref、reactive去定义响应式数数据。 知识点汇总 使用ref需要先引入ref&#xff0c;import {ref} from vue在模板 template 中使用了添加ref 的响应式数据&#xff0c;变量的后面不用添加.value所有js代码里面&#xff0c;去操作r…

27、web攻防——通用漏洞SQL注入Tamper脚本Base64Jsonmd5

文章目录 数字型&#xff1a;0-9。http;//localhost:8081/blog/news.php?id1 字符型&#xff1a;a-z、中文&#xff0c;需要闭合符号。http;//localhost:8081/blog/news.php?idsimple 搜索型&#xff1a;在字符型的基础上加入了通配符%。http;//localhost:8081/blog/news.…

大数据机器学习GAN:生成对抗网络GAN全维度介绍与实战

文章目录 大数据机器学习GAN&#xff1a;生成对抗网络GAN全维度介绍与实战一、引言1.1 生成对抗网络简介1.2 应用领域概览1.3 GAN的重要性 二、理论基础2.1 生成对抗网络的工作原理2.1.1 生成器生成过程 2.1.2 判别器判别过程 2.1.3 训练过程训练代码示例 2.1.4 平衡与收敛 2.2…

Gin 集成 prometheus 客户端实现注册和暴露指标

前言 当我们构建一个 Web 应用程序时&#xff0c;了解应用程序的性能和行为是非常重要的。Prometheus 是一个流行的开源监控系统&#xff0c;它提供了强大的指标收集和查询功能&#xff0c;可以帮助我们监控应用程序的各个方面。 在 Gin 中集成 Prometheus 可以让我们更方便地监…

vue中的内置指令v-model的作用和常见使用方法以及自定义组件上的用法

一、v-model是什么 v-model是Vue框架的一种内置的API指令&#xff0c;本质是一种语法糖写法&#xff0c;它负责监听用户的输入事件以更新数据&#xff0c;并对一些极端场景进行一些特殊处理。在Vue中&#xff0c;v-model是用于在表单元素和组件之间创建双向数据绑定的指令。它…

0基础学习VR全景平台篇第134篇:720VR全景,云台调整节点

相机、云台和脚架全套设备组装完成后需要进行调校才能开始拍摄。这一节&#xff0c;我们将主要介绍云台调整的两个内容&#xff1a;对中心靶、调三点一线。&#xff08;后附调校原理&#xff09; 云台部件名称 一、调节准备 &#xff08;一&#xff09;对于安装好的云台 1.检…

NAO.99b海潮模型的详解教程

NAO.99b模型是由日本国家天文台开发的全球潮汐模式&#xff0c;基于二维非线性浅水方程。该模型具有较高的分辨率&#xff0c;网格间距为0.50.5&#xff0c;网格数为720360&#xff0c;覆盖的经度范围为0.25&#xff5e;359.75E&#xff0c;纬度范围为89.75S&#xff5e;89.75N…

web前端导航条练习(包含弹性盒)

<!DOCTYPE html> <html lang"en"><head><meta charset"utf-8"><!--设置最佳适配窗口--><meta name"viewpoint" content"widthdevice-width,initial-scale1.0"><meta http-equiv"X-UA-&qu…

Maya-UE xgen-UE 毛发导入UE流程整理

首先声明&#xff1a;maya建议用2022版本及一下&#xff0c;因为要用到Python 2 ,Maya2023以后默认是Python3不再支持Python2; 第一步&#xff1a;Xgen做好的毛发转成交互式Groom 第二步&#xff1a;导出刚生成的交互式Groom缓存&#xff0c;需要设置一下当前帧&#xff0c;和…

Vue3复习笔记

目录 挂载全局属性和方法 v-bind一次绑定多个值 v-bind用在样式中 Vue指令绑定值 Vue指令绑定属性 动态属性的约束 Dom更新时机 ”可写的“计算属性 v-if与v-for不建议同时使用 v-for遍历对象 数组变化检测 事件修饰符 v-model用在表单类标签上 v-model还可以绑定…

钱数加s还是不加s?

语法 看有没有数字 有数字&#xff1a;无s 没数字&#xff1a;有s 案例

迅为龙芯2K1000开发板虚拟机 ubuntu 更换下载源

Ubuntu 系统软件的下载安装我们通常使用命令“apt-get” &#xff0c; 该命令可以实现软件自动下载&#xff0c; 安装&#xff0c; 配置。 该命令采用客户端/服务器的模式&#xff0c; 我们的 Ubuntu 系统作为客户端&#xff0c; 当需要下载软件的时候就向服务器发起请求&#…

(十)上市企业实施IPD成功案例分享之——IBM

集成产品开发&#xff08;Integrated Product Development&#xff0c;简称IPD&#xff09;是一套产品开发的模式、理念与方法。IPD的思想来源于美国PRTM公司出版的《产品及生命周期优化法》。IPD强调以市场和客户需求作为产品开发的驱动力&#xff0c;IPD将产品开发作为一项投…

SCT2601,可替代LMR16006X/MP2459/MP2456;4.5V-60V Vin,0.6A,高效降压DCDC转换器

•宽输入范围&#xff1a;4.5V-60V •高达0.6A的连续输出电流 •0.765V2.5%反馈参考电压 •集成500mΩ高压侧MOSFET •低静态电流为80uA •轻负载下的脉冲跳过模式&#xff08;PSM&#xff09; •最小接通时间80ns •内置6ms软启动时间 •开关频率为700KHz •可编程输入电压欠压…

pendulum,一个超酷的 Python 库!

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;今天为大家分享一个超酷的 Python 库 - pendulum。 Github地址&#xff1a;https://github.com/sdispater/pendulum 日期和时间处理在许多应用程序中都是常见的任务&#xff0c;然而&#xff0c;Python标准库中的…

2024年Mac专用投屏工具AirServer 7 .27 for Mac中文版

AirServer 7 .27 for Mac中文免费激活版是一款Mac专用投屏工具&#xff0c;能够通过本地网络将音频、照片、视频以及支持AirPlay功能的第三方App&#xff0c;从 iOS 设备无线传送到 Mac 电脑的屏幕上&#xff0c;把Mac变成一个AirPlay终端的实用工具。 目前最新的AirServer 7.2…