华为HarmonyOS NEXT 原生应用开发:鸿蒙中组件的组件状态管理、组件通信 组件状态管理小案例(好友录)!
文章目录
- 组件状态管理
- 一、@State装饰器
- 1. @State装饰器的特点
- 2. @State装饰器的使用
- 二、@Prop装饰器(父子单向通信)
- 1. @Prop装饰器的特点
- 2. @Prop装饰器的使用示例
- 三、@Link装饰器(父子双向通信)
- 1. @Link装饰器的特点
- 3. @Link使用示例
- 四、@Provide/@Consume装饰器(祖孙后代双向通信)
- 1. 特点
- 2. 使用条件
- 五、@Observed装饰器和@ObjectLink装饰器
- 1. 特点:
- 2. 使用说明
- 代码示例:
- 六、拓展装饰器
- 组件状态管理案例练习 - 好友录
组件状态管理
一、@State装饰器
1. @State装饰器的特点
● @State装饰的变量与子组件中的@Prop装饰变量之间建立单向数据同步,与@Link、@ObjectLink装饰变量之间建立双向数据同步。
● @State装饰的变量生命周期与其所属自定义组件的生命周期相同
2. @State装饰器的使用
- 简单示例:
以下示例为@State装饰的简单类型,count被@State装饰成为状态变量,count的改变引起Button组件的刷新:
● 当状态变量count改变时,查询到只有Button组件关联了它;
● 执行Button组件的更新方法,实现按需刷新。
@Entry
@Component
struct MyComponent {@State count: number = 0;build() {Button(`click times: ${this.count}`).onClick(() => {this.count += 1;})}
}
- 该装饰器修饰的变量将别 UI 框架监视。
- 需要注意,该变量访问权只在该组件中,且必须初始化。
二、@Prop装饰器(父子单向通信)
1. @Prop装饰器的特点
● 传递的是数据的深拷贝,每次都会拷贝数据源然后流转到子组件, 并且支持嵌套传递。
在父子组件中,使用该装饰器实现单向数据流。
● 父组件:数据源修改数据,@Prop修饰的变量都会进行覆盖变化。
● 子组件:对@Prop修饰的变量进行数据修改,并不会影响到父组件(数据源)。
2. @Prop装饰器的使用示例
- 父组件发生变化,数据流向子组件,实现单向同步,而子组件修改数据,不影响父组件数据源。子组件你数据使劲修改,父组件最终修改数据,都会同步到子组件!
@Entry
@Component
struct CStatusPage {@State age: number = 0build() {Column({ space: 20 }) {Column({ space: 20 }) {Text("父组件: " + this.age).fontSize(20)// 给子组件传参ChildComponent({age: this.age})}.width("50%").height(200).justifyContent(FlexAlign.Center).padding(20).backgroundColor(Color.Pink)Row({space: 100 }) {Button("父组件 + 1").onClick(() => {this.age++})}.width("100%").justifyContent(FlexAlign.Center)}.height('100%').width('100%').justifyContent(FlexAlign.Center)}
}@Component
struct ChildComponent {// 接收父组件参数@Prop age: number = 0build() {Column() {Row() {Text("子组件:" + this.age).fontSize(18)}.width("80%").height(100).backgroundColor(Color.Green)Button("子组件 + 1").onClick(() => {this.age++})}}
}
三、@Link装饰器(父子双向通信)
1. @Link装饰器的特点
双向数据流:@Link装饰的变量与其父组件中的数据源共享相同的值。
● 浅拷贝,直接将引用地址进行共享,同样支持嵌套。
- 限制条件
● @Link装饰器不能在@Entry装饰的组件中使用。
● 禁止子组件在本地初始化数据(父类数据直接流到子类,允许访问和修改,若是赋值就没有意义)。
● 私有,只能在所属组件内访问。
3. @Link使用示例
和上方 @Prop 大差不差,@Link 是双向数据流,父组件可以修改子,子也可以修改父组件。
@Entry
@Component
struct CStatusPage {@State age: number = 0build() {Column({ space: 20 }) {Column({ space: 20 }) {Text("父组件: " + this.age).fontSize(20)// 给子组件传参ChildComponent({age: this.age})}.width("50%").height(200).justifyContent(FlexAlign.Center).padding(20).backgroundColor(Color.Pink)Row({space: 100 }) {Button("父组件 + 1").onClick(() => {this.age++})}.width("100%").justifyContent(FlexAlign.Center)}.height('100%').width('100%').justifyContent(FlexAlign.Center)}
}@Component
struct ChildComponent {// 接收父组件参数 (需要注意不能有初始值,因为和父组件共享一份,有初始值就没有意义了)@Link age: numberbuild() {Column() {Row() {Text("子组件:" + this.age).fontSize(18)}.width("80%").height(100).backgroundColor(Color.Green)Button("子组件 + 1").onClick(() => {this.age++})}}
}
四、@Provide/@Consume装饰器(祖孙后代双向通信)
1. 特点
双向数据流、UI框架可以跨多层检测。
使用场景: 一般在一个组件中嵌套两层一及以上的组件使用,否则直接用@Link就可以解决一层父子通信的问题。
@Provide:@Provide装饰的状态变量自动对其所有后代组件可用.
@Consume:后代通过使用@Consume去获取@Provide提供的变量,建立在@Provide和@Consume之间的双向数据同步
,与@State/@Link不同的是,他是多层级的父子组件之间传递。
2. 使用条件
使用说明:熟
- @Consume修饰的状态变量不能主动初始化,只能接受祖先Provide的初始化
- @Provide修饰的状态变量必须初始化,可以用于初始化子组件,但不能被父组件初始化。
- 两个组件之间状态变量名和类型需要保持一致。
- 组件内变量名同名了(当然,进行取别名 @Consume(“别名”)),子组件直接使用别名即可! @Provide(“别名”),子组件同样直接使用别名。
● 需要注意:随着新版本的更新优化,组组件有别名的子组件就用别名,有的子组件用了父组件原名的就用其原名,不相互影响。
- 祖先组件代码
import { SonComponents } from '../components/SonComponents'
@Entry
@Component
struct Index {@State message: string = 'component1';@Provide user: string = 'admin'build() {Column({ space: 50}) {Text(this.message).fontSize(50)Row() {SonComponents()}}.height('100%').width('100%')}
}
- 第一层组件代码
import { Sun } from '../components/Sun'
@Component
export struct SonComponents {build() {Column() {Text('SonComponents2').fontSize(40)Sun()}.width('100%').height('100%')}
}
- 第三层组件代码
@Component
export struct Sun {@Consume user: stringbuild() {Column() {Text(this.user).fontSize(40)}.width('100%').height('100%')}
}
五、@Observed装饰器和@ObjectLink装饰器
1. 特点:
2. 使用说明
● @ObjectLink装饰器不能在@Entry装饰的自定义组件中使用。
● @ObjectLink中的属性可以被修改,但是不能直接覆盖自身
代码示例:
// 允许@ObjectLink装饰的数据属性赋值
this.objLink.a= ...
// 不允许@ObjectLink装饰的数据自身赋值
this.objLink= ...
class ClassA {public c: number;constructor(c: number) {this.c = c;}
}@Observed
class ClassB {public a: ClassA;public b: number;constructor(a: ClassA, b: number) {this.a = a;this.b = b;}
}
- ClassB被@Observed装饰,其成员变量的赋值的变化是可以被观察到的,但对于ClassA,没有被@Observed装饰,其属性的修改不能被观察到。
@ObjectLink b: ClassB// 赋值变化可以被观察到
this.b.a = new ClassA(5)
this.b.b = 5// ClassA类没有被@Observed装饰,嵌套在ClassB类中其属性的变化观察不到
this.b.a.c = 5
六、拓展装饰器
@Require修饰符
● 主要用于数据参数校验,添加该修饰符后,必须传递参数,故此也可以不给初始值。
@Track修饰符 (主要用于做新能优化的)
组件状态管理案例练习 - 好友录
- 可以跟着源码写一遍熟悉一下,主要练习组件通信。
- 数据模型文件源码
let nextId = 1// 随机姓名数组
const NameArr: string[] = ["子涵", "天宇", "雨欣", "晨曦", "思琪", "佳怡", "子轩", "浩然", "梦洁","文博", "子涵", "明轩", "诗涵", "子轩", "明轩", "子涵", "天宇", "雨欣","晨曦", "思琪", "佳怡", "子轩", "浩然", "梦洁", "文博", "诗涵", "子轩","明轩", "子涵", "天宇", "雨欣", "晨曦", "思琪", "佳怡", "子轩", "浩然","梦洁", "文博", "诗涵", "子轩", "明轩", "子涵", "天宇", "雨欣", "晨曦","思琪", "佳怡", "子轩", "浩然", "梦洁", "文博", "诗涵", "子轩", "明轩","子涵", "天宇", "雨欣", "晨曦", "思琪", "佳怡", "子轩", "浩然", "梦洁","文博", "诗涵", "子轩", "明轩", "子涵", "天宇", "雨欣", "晨曦", "思琪","佳怡", "子轩", "浩然", "梦洁", "文博", "诗涵", "子轩", "明轩", "小欣","梦洁", "文博", "诗涵", "子轩", "明轩", "子涵", "天宇", "雨欣", "晨曦","思琪", "佳怡", "子轩", "浩然", "梦洁", "文博", "诗涵", "子轩", "明轩","欣姚"
]
// 随机生成的 手机号码@Observed
export class Person {id: numbername: stringphone: stringisStar: boolean = falseconstructor(name: string, phone: string) {this.id = nextId++this.name = namethis.phone = phone}
}export function getPhonePerson (): Person {let personArr = new Person(randomNameHandle(), randomPhoneNumberHandle())return personArr
}// 随机生成姓名
export function randomNameHandle(): string {let name: string = ""let randomNameNumber: number = Math.floor(Math.random() * 100 )name = NameArr[randomNameNumber]return name
}// 生成随机的手机号
export function randomPhoneNumberHandle(): string {// 生成 11 位随机数字let phoneNumber = '';for (let i = 0; i < 11; i++) {phoneNumber += Math.floor(Math.random() * 10).toString();}return phoneNumber;
}
- index文件源码
import { Person, getPhonePerson } from "./model/DataModel"
import { promptAction } from '@kit.ArkUI'@Entry
@Component
struct Index {// 当前的id值@State PhonePerson: Person[] = [getPhonePerson(), getPhonePerson(), getPhonePerson()]// id容器,我需要得到子组件给我的当前id值@State currentContactID: number = -1// false 选择, true 取消@State titleTextBoolean: boolean = false@State deleteArrList: number[] = []build () {Column() {// 标题Row({ space: 10 }) {Text('联系人').fontSize(24).fontWeight(FontWeight.Bold)Blank()Button(this.titleTextBoolean ? "取消" : "选择").fontColor(Color.White).fontSize(14).backgroundColor(this.titleTextBoolean ? Color.Red : "#007dfe").onClick(() => {this.titleTextBoolean = ! this.titleTextBooleanthis.deleteArrList = []})Button(" + ").fontColor(Color.White).fontSize(14).onClick(() => {// 新增联系人(往数组追加对象)this.PhonePerson.push(getPhonePerson())})}.width('100%')// 主体列表List({ space: 10 }) {ForEach(this.PhonePerson, (item: Person, index: number) => {ListItem() {// 联系人项目ContactPersonComponent({// 将当前对象传递下去item: item,currentContactID: this.currentContactID,titleTextBoolean: this.titleTextBoolean,deleteArrList: this.deleteArrList})}})}.margin({ top: 10 }).layoutWeight(1)// 底部按钮if (this.titleTextBoolean) {Button(this.deleteArrList.length === 0 ? "取消" : "删除").fontColor(Color.White).backgroundColor(this.deleteArrList.length === 0 ? Color.Gray : Color.Red).onClick(() => {if (this.deleteArrList.length === 0) {promptAction.showToast({message: "操作取消!",textColor: "#FFCCAA"})this.titleTextBoolean = false} else {for(let item = 0; item < this.PhonePerson.length; item++) {for(let i = 0; i < this.deleteArrList.length; i++) {if (this.PhonePerson[item].id === this.deleteArrList[i]) {this.PhonePerson.splice(item, 1)}}}// 复原操作this.titleTextBoolean = false// 每次删除完成后,重置数组this.deleteArrList = []promptAction.showToast({message: "删除成功!",textColor: "#8ADAB2"})}})}}.width('100%').height('100%').padding(15).backgroundColor("#ffd6d4d4")}
}@Component
struct ContactPersonComponent {@ObjectLink item: Person@State showFlag: boolean = false@Link @Watch("onClickContactChange") currentContactID: number@Prop titleTextBoolean: boolean@Link deleteArrList: number[]onClickContactChange() {// 只要id发生变化,则将id 不等于当前的联系人详细信息项关闭if(this.currentContactID != this.item.id) {this.showFlag = false}}build() {Column({ space: 15 }) {Row({ space: 10 }) {if (this.titleTextBoolean) {Toggle({ type: ToggleType.Checkbox}) // {type: 按钮类型, isOn: 按钮是否选中状态}.selectedColor("#FFB0B0") // Toggle按钮组件 选中时候的颜色.onChange((value: boolean) => {// value值为true和false,二者之间随时切换!如果用户点击就为true,在次点击就为falseif (value) {this.deleteArrList.push(this.item.id)} else {// 获取该元素在deleteArrList的位置,以便后续删除操作let index: number = this.deleteArrList.indexOf(this.item.id)this.deleteArrList.splice(index, 1)}})}Image($r("app.media.startIcon")).width(35).height(35)Text(this.item.name)Blank()Image(this.item.isStar ? $r("app.media.select_collection") : $r("app.media.collection")).width(24).onClick(() => {this.item.isStar = ! this.item.isStar// 弹框提示if (this.item.isStar) {promptAction.showToast({message: `收藏成功!`,alignment: Alignment.Bottom,offset: { dx: 0, dy: -200},textColor: "#9ADE7B"})} else {promptAction.showToast({message: `取消收藏!`,alignment: Alignment.Bottom,offset: { dx: 0, dy: -200},textColor: Color.Red})}})}.width('100%').height(60)if (this.showFlag) {Divider().strokeWidth(2).color(Color.Black)Row({ space: 20 }) {Text("手机号码:")Text(this.item.phone)}.width('100%').justifyContent(FlexAlign.Start).padding(15)}}.backgroundColor(Color.White).padding({ top: 5, bottom: 5, left: 10, right: 10 }).borderRadius(15).onClick(() => {this.showFlag = ! this.showFlagthis.currentContactID = this.item.id // 将当前点击的联系人 id 给父组件})}
}
相关文章:

华为HarmonyOS NEXT 原生应用开发:鸿蒙中组件的组件状态管理、组件通信 组件状态管理小案例(好友录)!
文章目录 组件状态管理一、State装饰器1. State装饰器的特点2. State装饰器的使用 二、Prop装饰器(父子单向通信)1. Prop装饰器的特点2. Prop装饰器的使用示例 三、Link装饰器(父子双向通信)1. Link装饰器的特点3. Link使用示例 四…...
node.js 环境配置
node_global下创建node_modules 系统变量 新建NODE_Path -> node_modules的路径 用户变量 编辑Path 编辑…\npm为 node_modules的路径 系统变量 Path 新建 %NODE_PATH% CMD测试 npm install express -g 报错 npm error code ETIMEDOUT源的连接超时,没用了要换源 …...
高并发数据采集场景下Nginx代理Netty服务的优化配置
高并发数据采集场景下,要优化Nginx反向代理来支持多个Netty数采服务并保证稳定的性能,可以从以下几个方面对Nginx进行优化配置。 直连模式(直接通过 Nginx 处理与后端 Netty 服务的连接,而不作为反向代理),…...

【C++算法】40.模拟_N 字形变换
文章目录 题目链接:题目描述:解法C 算法代码: 题目链接: 6. N 字形变换 题目描述: 解法 解法一:模拟 a,b,c,d,e,f,g...... n4 弄个矩阵放进去,最后从左往右读取。 解法二:模拟优化-…...
【云计算】虚拟化技术
目录 1. 虚拟化技术在云计算中的那些地方发挥了关键作用? 2. 比较VMare,Xen等虚拟化产品的关键技术,以及对云计算技术提供的支持? 3. 服务器虚拟化,存储虚拟化和网络虚拟化都有哪些实现方式? 4. 讨论桌面…...

手机租赁系统开发指南一站式服务流程解析
内容概要 手机租赁系统的开发是一个复杂但有趣的过程,像搭建乐高一样,只要找到合适的模块,就能打造出一个宾至如归的租赁平台。在这部分,我们将对开发流程的整体结构进行简要概述,并指出每个环节的重要性。 首先&…...
【机器学习】—时序数据分析:机器学习与深度学习在预测、金融、气象等领域的应用
云边有个稻草人-CSDN博客 目录 引言 1. 时序数据分析基础 1.1 时序数据的特点 1.2 时序数据分析的常见方法 2. 深度学习与时序数据分析 2.1 深度学习在时序数据分析中的应用 2.1.1 LSTM(长短期记忆网络) 2.2 深度学习在金融市场预测中的应用 2…...

OBS + SRS:打造专业级直播环境的入门指南
OBS SRS:打造专业级直播环境的入门指南 1. OBS简介2. OBS核心功能详解2.1 场景(Scenes)管理2.2 源(Sources)控制2.3 混音器功能2.4 滤镜与特效2.5 直播控制面板 3. OBS推流到SRS服务器配置指南3.1 环境准备3.2 OBS推流…...

收银系统源码-会员管理
会员制早已成为门店经营首选的营销工具,尤其是针对连锁多门店会员管理尤为重要。 必然要求门店的收银系统需要支持会员管理,能提供多种会员权益; 1.会员类型 收银系统支持常规会员、plus付费会员、可绑定实体卡; plus会员&…...
MongoDB深化与微软的合作,新增人工智能和数据分析集成和微软 Azure Arc支持
日前,在微软Ignite技术大会上,MongoDB公司宣布面向MongoDB与微软共同客户推出三项新功能,双方协作更进一步。首先,需要构建由检索增强生成 (RAG) 技术驱动的应用程序的客户,现在可以选择MongoDB Atlas作为微软Azure AI…...

对流层路径延迟对SAR方位压缩的影响(CSDN_20240301)
目录 仿真参数 方位向脉冲压缩与高阶多普勒参数的关系 仿真结果 2m分辨率 1m分辨率 0.5m分辨率 0.3m分辨率 0.2m分辨率 0.1m分辨率 0.05m分辨率 小结 对流层路径延迟对方位脉冲压缩的影响 仿真参数 地球参数 赤道半径(m) 6378140 极半径&a…...

RK3588 Linux实例应用(2)——SDK与编译
SDK包编译与使用 一、安装SDK包1.1 安装软件依赖1.2 Git 配置1.3 安装 SDK1.4 安装第三方开源库 二、编译SDK包 一、安装SDK包 安装的步骤和原子哥一样的,我讲一下注意的细节。 看正点原子路径为:开发板光盘A盘→10、用户手册→02、开发文档→02【正点原…...
深入探究 Scikit-learn 机器学习库
一、数据处理与准备 (一)数据加载 内置数据集:Sklearn 自带一些经典数据集,如鸢尾花数据集(load_iris)、波士顿房价数据集(load_boston)等。这些数据集方便初学者快速上手实践&…...

PAT甲级-1114 Family Property
题目 题目大意 共有n个户主,每个户主的房产按照“ 户主id 父亲id 母亲id 孩子个数 孩子的id 房产数 房产面积 ”的格式给出。如果父亲或母亲不存在,值为-1。每个户主及其父亲母亲孩子可以构成一个家庭,不同户主如果有相同的家人,…...

5.2 JavaScript 案例 - 轮播图
JavaScript - 轮播图 文章目录 JavaScript - 轮播图基础模版一、刷新页面随机轮播图案例二、轮播图 定时器版三、轮播图完整版 基础模版 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"…...

使用IP自签名SSL证书
最近需要创建WebSocket服务器并使用SSL证书,由于是内网测试,所以需要使用指定IP的自签SSL证书。 其实笔者前面博文 使用nexus3作为Docker镜像仓库 解决nexus3登录x509: certificate has expired or is not yet valid 中有创建过相应的证书,这…...

数据库中的运算符
1.算术运算符 算术运算符主要用于数学运算,其可以连接运算符前后的两个数值或表达式,对数值或表达式进行加()、减(-)、乘(*)、除(/)和取模(%&…...

定制erp真的很贵吗?
定制ERP真的很贵吗?这个问题,相信很多企业在考虑是否实施ERP系统时,都会纠结。特别是对于一些中小型企业,预算有限,心里总会有个疑问:花大价钱定制一个系统,真的值得吗?其实…...
Java Integer的数值比较
文章目录 环境问题答案说明解决办法其它总结 环境 Windows 11 专业版Java 21 问题 下面这段代码的运行结果是什么? Integer i1 0;int i2 0;for (int n 0; n < 200; n) {if (i1 ! i2) {System.out.println("i1 " i1 ", i2 " i2);b…...

QGroundControl之5-AppSettings.cc
介绍 应用程序设置 Application Settings ,这里看下语言选择功能,它是怎么和json文件关联起来的,刚刚看的时候,很是奇怪这么多的json文件作用。 1.AppSettings.cc 文件怎么和App.SettingsGroup.json关联 在AppSettings.cc文件没…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...

基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...
ubuntu22.04 安装docker 和docker-compose
首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...
数据库正常,但后端收不到数据原因及解决
从代码和日志来看,后端SQL查询确实返回了数据,但最终user对象却为null。这表明查询结果没有正确映射到User对象上。 在前后端分离,并且ai辅助开发的时候,很容易出现前后端变量名不一致情况,还不报错,只是单…...
CppCon 2015 学习:Reactive Stream Processing in Industrial IoT using DDS and Rx
“Reactive Stream Processing in Industrial IoT using DDS and Rx” 是指在工业物联网(IIoT)场景中,结合 DDS(Data Distribution Service) 和 Rx(Reactive Extensions) 技术,实现 …...

基于小程序老人监护管理系统源码数据库文档
摘 要 近年来,随着我国人口老龄化问题日益严重,独居和居住养老机构的的老年人数量越来越多。而随着老年人数量的逐步增长,随之而来的是日益突出的老年人问题,尤其是老年人的健康问题,尤其是老年人产生健康问题后&…...