精华内容
下载资源
问答
  • js中怎么获取某个属性的值_小程序中 setData 详解
    2020-11-13 17:09:44

    前言

    在小程序中各个页面之间是相互独立的,一个页面分为渲染层(视图层 webview),逻辑层(JavaScript),系统层(底层),在架构上,WebView和 JavascriptCore 都是独立的模块,并不具备数据直接共享的通道,换而言之,若要将逻辑层中的data的数据渲染到页面中,他们之间是无法直接通信的,往往需要系统层作为中间角色

    我们都知道视图层的数据来源于逻辑层 data,而视图图层若想要改变逻辑层 data 的数据,需要借助setData这个方法去触发,以达到更新视图层的数据,具体的工作过程是怎么样的?

    setData 是什么

    定义: 设置数据,更改数据

    作用: setData函数用于将数据从逻辑层发送到视图层(异步),同时改变对应的this.data的值(同步)

    仔细细品这句话,会包含了很多信息

    • setData它是微信小程序提供的一个内置的接口,是用于改变逻辑层中data下的数据的
    • 视图层 view的数据挂载在逻辑层的data下,发送到视图层中是异步的
    • 改变this.data是同步,换句话说,若直接修改 this.data 而不调用 this.setData方法,是无法改变页面的状态的,还会造成数据不一致
    dc1db462b4d2fadf8947cdd7227894a8.png

    从上面的这张图中就可以看到,当逻辑层data数据渲染到界面的时候,逻辑层的数据需要经过系统层,当系统层接收到这个逻辑层的数据后

    系统层在把数据转发给渲染层,然后在渲染层展示出来,在这个过程当中是异步的

    视图层和逻辑层的数据传输,实际上通过两边提供的JavScript Core所实现,即用户传输的数据,需要将其转换为字符串形式传递,同时把转换后的数据内容拼接成一份 JS 脚本,再通过执行 JS 脚本的形式传递到两边独立的环境

    setData 接收两重要参数

    从官方文档中看到这句Page.prototype.setData(Object data, Function callback),得知,setData方法是挂载当前页面实例Page原型下一个公用实例方法

    也就是说,Page 下面的任何一个方法内,都可以使用 setData 方法,它接收两个参数

    • 一个是Object data,第一个参数Object data是必传的,数据类型是Object,所代表的含义是,这次要改变的数据
    • 而第二个参数Function callback回调函数是非必填的,它所代表的含义是,setData引起的界面更新渲染完毕后的回调函数

    为了便于理解,在小程序中创建一个 page 页面,名为setdata,如下是逻辑层 js 文件

    // miniprogram/pages/setdata/setdata.jsPage({  /**   * 页面的初始数据   */  data: {    name: "itclanCoder"  },  /**   * 生命周期函数--监听页面加载   */  onLoad: function (options) {  }})

    而 wxml 文件如下

    // miniprogram/pages/setdata/setdata.wxml{{name}}

    在Web 开发中,开发者使用 JavaScript 通过Dom接口来完成界面的实时更新。而在小程序中,使用 WXML语言所提供的数据绑定功能,来完成此项功能,在小程序中是没有DOM,BOM的那一套东西的,没有document.getElementById等的

    小程序是数据驱动视图的,逻辑层中的 data 数据改变了,视图层 view 也会跟着改变,它是单向数据流的,如果想要触发视图中数据的更新,那么就需要借助setData这个方法

    上面的WXML通过插值表达式来绑定 WXML文件和对应的JavaScript文件中的data对象属性

    在上面的示例中,页面会显示itclanCoder,那如何更改逻辑层的数据呢

    在下面的示例中,演示了如何更改逻辑层的数据,在 wxml 中新增了一个按钮,用bindtap绑定了一个handleChangeName方法,触发按钮,改变 data 下的数据

    {{name}}更改data中数据

    而在逻辑层 JS

    // miniprogram/pages/setdata/setdata.jsPage({  /**   * 页面的初始数据   */  data: {    name: "itclanCoder"  },  // 改变data的方法  handleChangeName() {    console.log("name开始的数据", this.data.name); // itclanCoder    this.setData({      name: "川川"    })    console.log("name经过setData后的数据", this.data.name); // 川川  }})

    在上面的示例代码中,更改data下面的name字段值,使用的是setData方法,这个方法接收了一个参数,第一个参数是对象,这个Object 以 key: value 的形式表示,将 this.data 中的 key 对应的值改变成 value

    注意

    这个key 可以以数据路径的形式给出,支持改变数组中的某一项或对象的某个属性,如 array[2].message,a.b.c.d,并且不需要在 this.data 中预先定义,但凡是页面要显示的变量数据,最好先挂载在data下初始化定义,然后在使用

    也就是说在更改setData下的变量时,直接写key名就可以了的,不用写this.data.属性,如下所示

    this.setData({   // this.data.name: "川川"  // 这样写是会报错的   name: "川川"               // 正确的写法})

    而setData接收第二个参数,是一个Function callback

    handleChangeName() {    console.log("name开始的数据", this.data.name); // itclanCoder    this.setData({      name: "川川"    }, () => { // 接收第二个回调函数       console.log("执行setData引起的界面更新渲染完毕后的回调函数");    })    console.log("name经过setData后的数据", this.data.name); // 川川  }

    上面代码的执行顺序是

    itclancoder川川执行setData引起的界面更新渲染完毕后的回调函数

    此结果说明这个setData方法是异步的,等待主线程任务做完了,然后在去执行第二个参数,回调异步函数

    如何更改当前对象某个属性的值

    有时候,我们的接口数据类型是对象,并非是基本数据类型(number,boolean,string,null),但由于业务需求,我们往往需要改变对象下的某个属性

    如下所示,我想改变person下的 age 属性值

    // miniprogram/pages/setdata/setdata.jsPage({  /**   * 页面的初始数据   */  data: {    person: {      name: "随笔川迹",      sex: "男神",      age: 20    }  },  handleChangeName() {    this.setData({      person: {        age: 24      }    })  }})

    在上面的代码中,的确可以更改person对象下的age属性,但是随之带来的问题是,person对象下除了age属性,其他属性都消失了 这非常令人郁闷

    de9364a913b8a8d54aec031d6bb4b180.gif

    那如何解决这个问题?

    原因:

    对象是一个引用数据类型,上面那种方式,是把我们当前的值指向了一个新的对象

    这样,就相当于现在的对象把之前的对象的值给覆盖掉了的,所以只看到age属性值,其他属性值给覆盖掉了的,这是一个非常蛋疼的问题,

    解决方式如下

    • 方法 1: 指明具体的修改对象属性
    this.setData({   "person.age": 24  // 注意要用双引号或单引号将属性给引起来})
    • 方法 2:使用中扩号['对象.属性']:属性值
    this.setData({   ['person.age']: "川川"   // 访问对象下的属性可以用.也可以用中括号,中间代表是一个变量,需要用引号引起来})

    如下所示

    0ecf984a4c5bac1a72a01f4553735c85.gif

    这个在以后的开发中,很有用,有时候,在需要更改对象下的某个属性值的时候,就可以使用这种方式

    setData 注意事项

    • 直接修改 this.data而不调用 this.setData是无法改变页面的状态的,还会造成数据不一致
    • 仅支持设置可 JSON化的数据,如果不是 JSON 对象数据格式,需要将数据进行转化成json对象,key:value形式
    • 单次设置的数据不能超过1024kB(1M),不要一次设置过多的数据(由于小程序运行逻辑线程与渲染线程之上,setData的调用会把数据从逻辑层传到渲染层,数据太大会增加通信时间,会增加脚本的编译执行时间,占用 WebView JS 线程,)
    • 不要把 data中任何一项的value设为undefined,否则这一项将不被设置并可能遗留一些潜在问题
    • 页面中需要显示的数据,可以挂载在data下面初始化,虽然这个值不一定要先设置,但是建议先声明然后在使用
    • 避免setData的调用过于频繁(setData接口的调用涉及逻辑层与渲染层间的线程通信,通信过于频繁可能导致处理队列阻塞,界面渲染不及时而导致卡顿,应避免无用的频繁调用)在Android 下
    • 用户在滑动时会感觉到卡顿,操作反馈延迟严重,因为JS 线程一直在编译执行渲染,未能及时将用户操作事件传递到逻辑层,逻辑层亦无法及时将操作处理结果及时传递到视图层渲染有出现延时
    • 由于 WebView的 JS 线程一直处于忙碌状态,所以,逻辑层到页面层的通信耗时上升,视图层收到的数据消息时距离发出时间已经过去了几百毫秒,渲染的结果并不是实时的
    • 避免 setData 数据冗余(setData操作会引起框架处理一些渲染界面相关的工作,避免将未绑定在 WXML 的变量传入setData,减少不必要的性能消耗)
    • 后台态页面进行 setData(比如退出小程序),当页面进入后台态(用户不可见),不应该继续去进行 setData,后台态页面的渲染用户是无法感受到的,另外后台态页面去 setData 也会抢占前台页面的执行
    • 总结
    • 在本文中主要介绍了下setData的使用,它是用于修改挂载在 data 下面的数据的,当想要修改视图 view,那么需要借助 setData 函数,它接收两个参数,第一个参数时必传的,也就是要修改视图 view 层的对象,而第二个参数时非必传的

    setData 将数据从逻辑层发送到视图层是异步,同时改变对应的this.data的值是同步,它并不是实时的,这也导致了必须要考虑性能的因素

    从而介绍了 setData 的使用注意事项,值得注意的是,如何修改对象下的某个属性,这个在往后的开发中,是使用比较频繁的.

    更多相关内容
  • 微信小程序 setData使用方法及常用错误解决办法 最近在弄微信小程序,类似于共享单车用来练练手,基本原理就是小程序发送经纬度给服务器,服务器从数据库中检索经纬度附近的单车传给小程序。 就在这里。。没错就是...
  • 偶然之下,发现了setdata 的一些机制,也有可能不对,请多指教。 先放结论:data的变量通过setdata绑在一起,是同步变化的 准备做一个一键还原界面的按钮事件,如果有后端接口,只需调一下接口,就可以了。问题是...
  • 这些值在微信小程序中都需要使用一个名为setData的方法,而这个方法是通过键值对的形式对数据进行修改,setData({ 参数名: 值 });  既然知道是以键值对的方式进行传参,那么我们在修改数组和对象的时候就直接将要...
  • 小程序中我们会经常使用到this.data与this.setData。其中this.data是用来获取页面data对象的,而this.setData是用来更新界面的。那么他们之间的区别与联系你真的搞懂了吗? Page.prototype.setData() setData 函数...
  • 代码如下: [AppleScript] 纯文本查看 复制代码 ? 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 wx.request({  url: 'http://route.showapi.com/', // 调用接口 ... hea
  • 其实这个功能实现起来也不难,核心就是用到了window子对象clipboardData的一个方法:setData()语法: clipboardData.setData(sDataFormat, sData) 参数:sDataFormat:要复制的内容的格式;sData:要复制的内容。 ...
  • 主要介绍了微信小程序错误this.setData报错及解决过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • 微信小程序 setData的使用方法详解 最近在使用微信小程序的setData时,遇到了以下问题。如下: 官网文档在使用setData()设置数组对象的某个元素的属性时,是这么使用的: Page({ data: { array: [{text: 'init ...
  • this.setData估计是小程序中最经常用到的一个方法,但是要注意其实他是有限制的,忽略这些限制的话,会导致数据无法更新 setData的反模式: -- 短时间频繁进行setData操作 --页面进入后台后依然进行setData操作 -- ...
  • 微信小程序 报错:this.setData is not a function 在page中定义的代码如下,代码会报错:this.setData is not a function <strong> pasteEncryptedText:function()</strong>{ let decryptedPass = this.data....
  • 小程序SetData()方法使用
  • 主要介绍了浅谈小程序 setData学问多,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 前言:微信小程序中经常需要用到this.setData({})把变量值渲染到视图层,那到底什么是this.setData,如何使用?需要注意哪些?作为一个初学者,分享一点我的经验,希望大家批评指正。  介绍:setData函数主要用于将...
  • 主要介绍了详解关于微信setData回调函数中的坑,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 新版的wepy已经废弃了setData - 副本. https://blog.csdn.net/qq_36413371/article/details/101070653
  • Page.prototype.setData setData 函数用于将数据从逻辑层发送到视图层(异步),同时改变对应的 this.data 的值(同步)。 setData() 参数格式 setData(data, callback); // data需为可 JSON 化的数据,callback在 ...
  • 演示微信小程序开发对 Page.prototype.setData() 函数的封装的例子,作者:云淡风轻。  比如显示/隐藏、添加样式、移除样式、添加class、绑定事件、移除事件、重新注册事件源、列表绑定事件等。
  • 最近在使用微信小程序的setData时,遇到了以下问题。如下: 官网文档在使用setData()设置数组对象的某个元素的属性时,是这么使用的:   Page({ data: { array: [{text: 'init data'}], }, changeItemInArray: ...
  • 微信小程序中 setData 详解

    万次阅读 多人点赞 2020-06-21 11:44:26
    从官方文档中看到这句Page.prototype.setData(Object data, Function callback),得知,setData方法是挂载当前页面实例Page原型下一个公用实例方法 也就是说,Page 下面的任何一个方法内,都可以使用 setData 方法,它...

    虽互不曾谋面,但希望能和您成为笔尖下的朋友

    以读书,技术,生活为主,偶尔撒点鸡汤

    不作,不敷衍,意在真诚吐露,用心分享

    点击左上方,可关注本刊

    标星公众号(ID:itclanCoder

    如果不知道如何操作

    点击这里,标星不迷路

    ━━━━━━

    ━━━━━━

    我希望您保持空杯

    一边阅读一边思考

    更重要是要动手敲

    如果有收获三连击

    作者 | 随笔川迹

    ID | suibichuanji

    前言

    撰文:川川

    在小程序中各个页面之间是相互独立的,一个页面分为渲染层(视图层 webview),逻辑层(JavaScript),系统层(底层)

    在架构上,WebViewJavascriptCore 都是独立的模块,并不具备数据直接共享的通道

    换而言之,若要将逻辑层中的data的数据渲染到页面中,他们之间是无法直接通信的,往往需要系统层作为中间角色

    我们都知道视图层的数据来源于逻辑层 data,而视图图层若想要改变逻辑层 data 的数据,需要借助setData这个方法去触发,以达到更新视图层的数据,具体的工作过程是怎么样的?

    ·  正  ·  文  ·  来  ·  啦  ·

    01

    setData是什么?

    定义: 设置数据,更改数据

    作用: setData函数用于将数据从逻辑层发送到视图层(异步),同时改变对应的 this.data的值(同步)

    仔细细品这句话,会包含了很多信息

    • setData它是微信小程序提供的一个内置的接口,是用于改变逻辑层中 data下的数据的

    • 视图层 view的数据挂载在逻辑层的 data下,发送到视图层中是异步的

    • 改变 this.data是同步,换句话说,若直接修改 this.data 而不调用 this.setData方法,是无法改变页面的状态的,还会造成数据不一致

    从上面的这张图中就可以看到,当逻辑层data数据渲染到界面的时候,逻辑层的数据需要经过系统层,当系统层接收到这个逻辑层的数据后

    系统层在把数据转发给渲染层,然后在渲染层展示出来,在这个过程当中是异步的 

    视图层和逻辑层的数据传输,实际上通过两边提供的 JavScript Core所实现,即用户传输的数据,需要将其转换为字符串形式传递

    同时把转换后的数据内容拼接成一份 JS 脚本,再通过执行 JS 脚本的形式传递到两边独立的环境

    02

    setData两个重要的参数

    从官方文档中看到这句Page.prototype.setData(Object data, Function callback),得知,setData方法是挂载当前页面实例Page原型下一个公用实例方法

    也就是说,Page 下面的任何一个方法内,都可以使用 setData 方法,它接收两个参数

    • 一个是Object data,第一个参数Object data是必传的,数据类型是Object,所代表的含义是,这次要改变的数据

    • 而第二个参数Function callback回调函数是非必填的,它所代表的含义是,setData引起的界面更新渲染完毕后的回调函数

    为了便于理解,在小程序中创建一个 page 页面,名为setdata,如下是逻辑层 js 文件

    // miniprogram/pages/setdata/setdata.js
    Page({
    
      /**
       * 页面的初始数据
       */
      data: {
        name: "itclanCoder"
      },
    
      /**
       * 生命周期函数--监听页面加载
       */
      onLoad: function (options) {
    
      }
    })

    而 wxml 文件如下

    <!--miniprogram/pages/setdata/setdata.wxml-->
    <text>{{name}}</text>

    在Web 开发中,开发者使用JavaScript通过Dom接口来完成界面的实时更新。而在小程序中,使用WXML语言所提供的数据绑定功能,来完成此项功能

    在小程序中是没有DOM,BOM的那一套东西的,没有document.getElementById等的

    小程序是数据驱动视图的,逻辑层中的 data 数据改变了,视图层 view 也会跟着改变,它是单向数据流的,如果想要触发视图中数据的更新,那么就需要借助setData这个方法

    上面的WXML通过{{变量名}}来绑定 WXML文件和对应的JavaScript文件中的data对象属性

    在上面的示例中,页面会显示itclanCoder,那如何更改逻辑层的数据呢

    在下面的示例中,演示了如何更改逻辑层的数据,在 wxml 中新增了一个按钮,用bindtap绑定了一个handleChangeName方法,触发按钮,改变 data 下的数据

    <!--miniprogram/pages/setdata/setdata.wxml-->
    <text>{{name}}</text>
    <button type="primary" bindtap="handleChangeName">更改data中数据</button>

    而在逻辑层 JS

    // miniprogram/pages/setdata/setdata.js
    Page({
    
      /**
       * 页面的初始数据
       */
      data: {
        name: "itclanCoder"
      },
    
      // 改变data的方法
      handleChangeName() {
        console.log("name开始的数据", this.data.name); // itclanCoder
        this.setData({
          name: "川川"
        })
        console.log("name经过setData后的数据", this.data.name); // 川川
      }
    
    })

    在上面的示例代码中,更改data下面的name字段值,使用的是setData方法,这个方法接收了一个参数,第一个参数是对象,这个Object 以 key: value 的形式表示,将 this.data中的 key对应的值改变成 value

    注意

    这个key可以以数据路径的形式给出,支持改变数组中的某一项或对象的某个属性,如 array[2].message,a.b.c.d,并且不需要在 this.data中预先定义,但凡是页面要显示的变量数据,最好先挂载在data下初始化定义,然后在使用

    也就是说在更改setData下的变量时,直接写key名就可以了的,不用写this.data.属性,如下所示

    this.setData({
       // this.data.name: "川川" // 这样写是会报错的
       name: "川川"               // 正确的写法
    })

    而setData接收第二个参数,是一个Function callback

    handleChangeName() {
        console.log("name开始的数据", this.data.name); // itclanCoder
        this.setData({
          name: "川川"
        }, () => { // 接收第二个回调函数
           console.log("执行setData引起的界面更新渲染完毕后的回调函数");
        })
        console.log("name经过setData后的数据", this.data.name); // 川川
      }

    上面代码的执行顺序是

    itclancoder
    川川
    执行setData引起的界面更新渲染完毕后的回调函数

    此结果说明这个setData方法是异步的,等待主线程任务做完了,然后在去执行第二个参数,回调异步函数

    03

    如何更改某个对象下的属性

    有时候,我们的接口数据类型是对象,并非是基本数据类型(number,boolean,string,null),但由于业务需求,我们往往需要改变对象下的某个属性

    如下所示,我想改变person下的 age 属性值

    // miniprogram/pages/setdata/setdata.js
    Page({
    
      /**
       * 页面的初始数据
       */
      data: {
        person: {
          name: "随笔川迹",
          sex: "男神",
          age: 20
        }
      },
    
      handleChangeName() {
        this.setData({
          person: {
            age: 24
          }
        })
      }
    })

    在上面的代码中,的确可以更改person对象下的age属性,但是随之带来的问题是,person对象下除了age属性,其他属性都消失了

    这非常令人郁闷

    那如何解决这个问题?

    • 方法 1: 指明具体的修改对象属性

    this.setData({
       "person.age": 24  // 注意要用双引号或单引号将属性给引起来
    })
    • 方法 2:使用中扩号['对象.属性']:属性值

    this.setData({
       ['person.age']: "川川"   // 访问对象下的属性可以用.也可以用中括号,中间代表是一个变量,需要用引号引起来
    })

    如下所示

    这个在以后的开发中,很有用,有时候,在需要更改对象下的某个属性值的时候,就可以使用这种方式

    04

    setData注意事项

    • 直接修改 this.data,而不调用this.setData是无法改变页面的状态的,还会造成数据不一致

    • 仅支持设置可JSON化的数据,如果不是 JSON 对象数据格式,需要将数据进行转化成json对象`,key:value形式

    • 单次设置的数据不能超过1024kB(1M),不要一次设置过多的数据(由于小程序运行逻辑线程与渲染线程之上,setData的调用会把数据从逻辑层传到渲染层,数据太大会增加通信时间,会增加脚本的编译执行时间,占用 WebView JS 线程,)

    • 不要把 data中任何一项的value设为undefined,否则这一项将不被设置并可能遗留一些潜在问题

    • 页面中需要显示的数据,可以挂载在data下面初始化,虽然这个值不一定要先设置,但是建议先声明然后在使用

    • 避免setData的调用过于频繁(setData接口的调用涉及逻辑层与渲染层间的线程通信,通信过于频繁可能导致处理队列阻塞,界面渲染不及时而导致卡顿,应避免无用的频繁调用)

    • 在Android下用户在滑动时会感觉到卡顿,操作反馈延迟严重,因为JS线程一直在编译执行渲染,未能及时将用户操作事件传递到逻辑层,逻辑层亦无法及时将操作处理结果及时传递到视图层

    • 渲染有出现延时,由于WebView的 JS 线程一直处于忙碌状态,所以,逻辑层到页面层的通信耗时上升,视图层收到的数据消息时距离发出时间已经过去了几百毫秒,渲染的结果并不是实时的

    • 避免 setData 数据冗余(setData操作会引起框架处理一些渲染界面相关的工作,避免将未绑定在 WXML 的变量传入setData,减少不必要的性能消耗)

    • 后台态页面进行setData(比如退出小程序),当页面进入后台态(用户不可见),不应该继续去进行 setData,后台态页面的渲染用户是无法感受到的,另外后台态页面去 setData 也会抢占前台页面的执行

    结语

    在本文中主要介绍了下setData的使用,它是用于修改挂载在 data 下面的数据的,当想要修改视图 view,那么需要借助 setData 函数,它接收两个参数,第一个参数时必传的,也就是要修改视图 view 层的对象,而第二个参数时非必传的

    setData 将数据从逻辑层发送到视图层是异步,同时改变对应的this.data的值是同步,它并不是实时的,这也导致了必须要考虑性能的因素

    从而介绍了 setData 的使用注意事项,值得注意的是,如何修改对象下的某个属性,这个在往后的开发中,是使用比较频繁的.

    如果小伙伴们有问题,欢迎大家下面留言,一起学习讨论

    这个世界很酷

    遇见您本就是命中注定

    知交零落已是人生常态

    能够偶尔话起

    而心中仍然温柔

    便是好朋友

    我希望您就是我的那个朋友

    终日守候

    看我码字,听我读书

    坚持给川川点赞

     愿少年您

    不畏风雨,砥砺"潜"行

      听川川,荡气回肠  

    看川川,码中怀孕

    读川川,浮想联翩

    写川川,镂骨铭心

    公众号(ID:itclanCoder)

    码能让您早脱菜籍,文能让您洗净铅华

      可能您还想看更多:

    小程序-云开发-多图片内容安全检测

    小程序-云开发-如何切换开发(测试)坏境与生产坏境

    小程序-云开发-如何对敏感词进行过滤即内容安全的检测(下)

    - End -

    在看点一下 大家都知道

    展开全文
  • 之前写的一篇利用setData进行局部渲染的文章,有些朋友可能看的不是很明白,那篇文章写的可能也有一些问题,今天我就把那篇文章重新做一个详细解说,希望大家都能看的明白。  看这篇文章的小伙伴肯定是遇到了这些...
  • 最近在使用微信小程序的setData时,遇到了以下问题。如下: 官网文档在使用setData()设置数组对象的某个元素的属性时,是这么使用的:   Page({ data: { array: [{text: 'init data'}], }, changeItemInArray: ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 179,094
精华内容 71,637
关键字:

setdata

友情链接: RTX51操作系统.zip