微信小程序基础知识3
再续一篇…
十四. 页面导航
声明式导航 :在页面上声明一个
<navigator>
导航组件,通过点击<navigator>
组件实现页面跳转导航到
tabBar
页面:在使用<navigator>
组件跳转到指定的tabBar
页面时,需要指定url
属性和open-type
属性,其中:url
表示要跳转的页面的地址,必须以/
开头 ;open-type
表示跳转的方式,必须为switchTab
<navigator url="/pages/message/message" open-type="switchTab">导航到tab页面</navigator>
导航到非
tabBar
页面:open-type
必须为navigate
(注意:在导航到非tabBar
页面时,open-type="navigate"
属性可以省略)<navigator url="/pages/info/info" open-type="navigate">导航到tab页面</navigator>
后退导航:
open-type
的值必须是navigateBack
,表示要进行后退导航 ;delta
的值必须是数字,表示要后退的层级**(注意:如果只是后退到上一页面,则可以省略delta
属性,因为其默认值就是 1)**<navigator open-type="navigateBack" delta="1">返回上一页</navigator>
编程式导航 :调用小程序的导航
API
,实现页面的跳转导航到
tabBar
页面:调用wx.switchTab(Object object)
方法,可以跳转到tabBar
页面,其中Object
参数对象的属性列表有:url
:跳转tabBar
页面的路径 (必填)success
:接口调用成功的回调函数fail
:接口调用失败的回调函数complete
:接口调用接收的回调函数(成功失败都会执行)
<button bindtap="gotoMessage">跳转至 tab 页面 </button>
gotoMessage() {wx.switchTab({url: '/page/message/message'}) }
导航到非
tabBar
页面:调用wx.navigateTo(Object object)
方法,可以跳转到非tabBar
的页面。<button bindtap="gotoInfo">跳转至非 tab 页面 </button>
gotoInfo() {wx.navigateTo({url: '/page/info/info'}) }
后退导航: 调用
wx.navigateBack(Object object)
方法,可以返回上一页面或多级页面。<button bindtap="gotoBack">后退 </button>
gotoBack() {wx.navigateBack() }
十五. 导航传参
声明式导航传参:
navigator
组件的url
属性用来指定将要跳转到的页面的路径。同时,路径的后面还可以携带参数:参数与路径之间使用 ? 分隔
参数键与参数值用 = 相连
不同参数用 & 分隔
<navigator url="/pages/info/info?name=zs&age=18">导航到tab页面</navigator>
编程式导航传参:
<button bindtap="gotoInfo">跳转至非 tab 页面 </button>
gotoInfo() {wx.navigateTo({url: '/page/info/info?name=ls&age=20'}) }
在
onLoad
中接收导航参数:通过声明式导航传参或编程式导航传参所携带的参数,可以直接在onLoad
事件中直接获取到data: {// 存储 onLoad 接收到的参数query: [] }onLoad: function (options) {console.log(options)this.setData({// 保存到 data 中的 query query: options}) }
十六. 停止下拉刷新效果
wx.stopPullDownRefresh()
:当处理完下拉刷新后,下拉刷新的loading
效果会一直显示,不会主动消失,所以需要手动隐藏下拉刷新的loading
效果
十七. 生命周期
应用生命周期(在
app.js
中进行声明):特指小程序从启动 -> 运行 -> 销毁的过程App({onLaunch() {console.log('onLaunch监听小程的初始化,全局只触发一次')},onShow(){console.log('onShow监听小程序的显示')},onHide(){console.log('onHide监听小程序隐藏')} })
页面生命周期(在页面的
.js
文件中进行声明):特指小程序中,每个页面的加载 -> 渲染 -> 销毁的过程Page({// 页面的初始数据data: {},// 生命周期函数--监听页面加载onLoad: function (options) {})// 生命周期函数--监听页面初次渲染完成onReady: function () {}, // 生命周期函数--监听页面显示onShow: function () {},// 生命周期函数--监听页面隐藏onHide: function () {},// 生命周期函数--监听页面卸载onUnload: function () {}, })
组件的生命周期函数(组件的的生命周期可以在
lifetimes
字段内进行声明,其优先级最高)Component({// 在该字段下声明lifetimes: {created: function() {// 在组件实例被创建时,会触发// 此时还不能调用 setData// 通常只应该用于给组件的 this 添加一些自定义的属性字段},attached: function() {// 在组件实例进入页面节点树时执行// 此时, this.data 已被初始化完毕// 绝大多数初始化的工作可以在这个时机进行(例如发请求获取初始数据)},ready: function() {// 在组件在视图层布局完成后执行},moved: function() {// 在组件实例被移动到节点树另一个位置时执行},detached: function() {// 在组件实例被从页面节点树移除时执行// 退出一个页面时,会触发,此时适合做一些清理性质的工作},error: function() {// 每当组件方法抛出错误时执行},}, })// 组件所在页面的生命周期,需要定义在 pageLifetimes 节点中 Component({pageLifetimes: {show: function() {}, // 页面被展示hide: function() {}, // 页面被隐藏resize: function(size) {} // 页面尺寸变化} })
十八. 自定义组件
创建组件:
- 在项目的根目录中,鼠标右键,创建
components -> test
文件夹 - 在新建的
components -> test
文件夹上,鼠标右键,点击“新建Component
” - 键入组件的名称之后回车,会自动生成组件对应的 4 个文件,后缀名分别为
.js,.json, .wxml 和 .wxss
- 在项目的根目录中,鼠标右键,创建
引用组件
局部引用:在页面的
.json
配置文件中引用组件的方式,叫做“局部引用”全局引用:在
app.json
全局配置文件中引用组件的方式,叫做“全局引用”"usingComponents": {// "自定义组件名": "路径""my-test": "/component/test/test" }// 在页面的 .wxml 文件中使用组件 <my-test></my-test>
组件与页面的区别
- 组件的
.json
文件中需要声明"component": true
属性 - 组件的
.js
文件中调用的是Component()
函数 - 组件的事件处理函数需要定义到
methods
节点中
- 组件的
组件样式隔离
- 组件之间的样式不会相互影响
- 页面的样式与全局样式对组件不会产生影响
- 注意:只有
class
选择器会有样式隔离效果,id
选择器、属性选择器、标签选择器不受样式隔离的影响
修改组件的样式隔离选项
默认情况下,自定义组件的样式隔离特性能够防止组件内外样式互相干扰的问题。但有时,我们希望在外界能够控制组件内部的样式,此时,可以通过
styleIsolation
修改组件的样式隔离选项,用法如下:// 方法1:在组件的 .js 文件中新增如下配置 Component({options: {styleIsolation: 'isolated'} })// 方法2:在组件的 .json 文件中新增如下配置 {"styleIsolation": "isolated" }
styleIsolation
的可选值:isolated
:启用样式隔离(默认)apply-shared
:页面样式会影响自定义组件,但自定义组件中的样式不会影响页面shared
:页面样式与组件样式会相互影响,也会影响其他设置了apply-shared
或shared
的自定义组件
自定义组件中的
properties
属性:在小程序组件中,properties
是组件的对外属性,用来接收外界传递到组件中的数据Component({properties: {// 方法1:完整定义属性的方式max: {type: Number, // 属性值的数据类型value: 10 // 属性默认值},// 方法2:简化方法(不能指定默认值)max: Number} })// 页面中(如果页面有传递相应数值,则会覆盖组件中的默认值) <my-test max="9"></my-test>
数据侦听器:用于监听和响应任何属性和数据字段的变化,从而执行特定的操作,类似于
VUE
中的watch
侦听器// 基本语法 Component({observers: {'字段A,字段B': function(字段A的新值, 字段B的新值) {// do something}} })// 例子(基本用法) Component({data: {n1: 0,n2: 0,sum: 0},methods: {addN1() {this.setData({n1: this.data.n1 + 1})},addN2() {this.setData({n2: this.data.n2 + 1})},},observers: {'n1, n2': function(newN1, newN2) {this.setData({sum: newN1 + newN2})}} })// 监听对象属性的变化 observers: {'list.n1, list.n2': function(newN1, newN2) {this.setData({sum: newN1 + newN2})} }// 监听对象中所有属性的变化,可以使用通配符 ** 来监听对象中所有属性的变化 observers: {'list.**': function(obj) {this.setData({sum: obj.n1 + obj.n2})} }
纯数据字段:那些不用于界面渲染的 data 字段。(纯数据字段有助于提升页面更新的性能。)
使用规则:在
Component
构造器的options
节点中,指定pureDataPattern
为一个正则表达式,字段名符合这个正则 表达式的字段将成为纯数据字段,示例代码如下Component({options: {// 指定所有 _ 开头的数据为纯数据字段pureDataPattern: /^_/},data: {a: true, // 普通数据字段_b: true // 纯数据字段} })
插槽:以提供一个
<slot>
节点(插槽),用于承载组件使用者提供的wxml
结构。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OOPuN80V-1666750576358)(C:\Users\zzx\AppData\Roaming\Typora\typora-user-images\image-20221022161231082.png)]
单个插槽
<!-- 组件的封装者 --> <view><view>这是组件的内部节点</view><!-- 使用 slot 插槽占位 --><slot></slot> </view><!-- 组件的使用者 --> <test1><!-- 这部分内容将被放置在组件 <slot> 的位置上 --><view>组件 slot 中的内容</view> </test1>
多个插槽:需要使用多个插槽时,可以在组件的
.js
文件中,通过如下方式进行启用:Component({options: {multipleSlots: true // 开启多个插槽} })
<!-- 组件的封装者 --> <view><!-- name 为 before 的第一个 slot 插槽占位 --><slot name="before"></slot><view>这是组件的内部节点</view><!-- name 为 after 的第二个 slot 插槽占位 --><slot name="after"></slot> </view><!-- 组件的使用者 --> <test1><!-- 这部分内容将被放置在组件中 name 为 before 的 <slot> 的位置上 --><view slot="before">组件 name 为 before 的 slot 中的内容</view><!-- 这部分内容将被放置在组件中 name 为 after 的 <slot> 的位置上 --><view slot="after">组件 name 为 after 的 slot 中的内容</view> </test1>
父子组件之间的通信
属性绑定:用于父组件向子组件的指定属性设置数据,仅能设置
JSON
兼容的数据(只能传递普通类型的数据,无法将方法传递给子组件)// 父组件中 data 节点 data: {count: 0 } // 父组件的 wxml 结构 // 引用子组件,向子组件传递 count 属性 <test1 count="{{count}}"></test1> <view>父组件中,count值为:{{count}}</view>
// 子组件的 properties 节点 properties: {// 接收父组件传递的 countcount: Number }// 子组件的 wxml 结构 <view>子组件中,count值为:{{count}}</view>
事件绑定:用于子组件向父组件传递数据,可以传递任意数据
在父组件的
.js
中,定义一个函数,这个函数即将通过自定义事件的形式,传递给子组件// 在父组件中定义 syncCount 方法 // 这个方法会传递给子组件,供子组件进行调用 syncCount(e) {console.log('syncCount') }
在父组件的
wxml
中,通过自定义事件的形式,将步骤 1 中定义的函数引用,传递给子组件<!-- 使用 bind:自定义事件名称 (推荐使用,结构清晰) --> <test1 count="{{count}}" bind:sync="syncCount"></test1><!-- 或在 bind 后面直接写上自定义事件名称 --> <test1 count="{{count}}" bindsync="syncCount"></test1>
在子组件的
js
中,通过调用this.triggerEvent('自定义事件名称', { /* 参数对象 */ })
,将数据发送到父组件// 子组件的 wxml 结构 <view>子组件中,count值为:{{count}}</view> <button type="primary" bindtap="addCount">+1 </button>
// 子组件的 js 代码 methods: {addCount() {this.setData({count: this.properties.count + 1})// 子组件将更新后的 count 值传递给父组件this.triggerEvent('sync', {value: this.properties.count}) } }
在父组件的
js
中,通过e.detail
获取到子组件传递过来的数据syncCount(e) {// console.log('syncCount')this.setData({count: e.detail.value}) }
获取组件实例:父组件还可以通过
this.selectComponent("id或class选择器")
获取子组件实例对象,这样就可以直接访问子组件的任意数据和方法<!-- 父组件中 wxml 结构 --> <!-- 使用 bind:自定义事件名称 (推荐使用,结构清晰) --> <test1 count="{{count}}" bind:sync="syncCount" class="customA"></test1> <button bindtap="getChild">获取子组件实例 </button>
// 父组件中 js 结构 getChild() {const child = this.selectComponent('.customA')child.setData({ count: child.porperties.count + 1 }) // 调用子组件的 setData 方法,使其的 count 自增加1child.adCount() // 调用子组件的 addCount 方法 }
组件中的
behaviors
:用于实现组件间代码共享的特性,类似于Vue.js
中的“mixins”
。每个
behavior
可以包含一组属性、数据、生命周期函数和方法。组件引用它时,它的属性、数据和方法会被合并到组件中。 每个组件可以引用多个behavior
,behavior
也可以引用其它behavior
。创建
behavior
(在项目根目录创建behaviors
文件夹,再在文件夹中创建相应的js
文件):调用Behavior(Object object)
方法即可创建一个共享的behavior
实例对象,供所有的组件使用:// 调用 Behavior() 方法,创建实例对象 // 使用 module.exports 将 behavior 实例对象共享出去 module.exports = Behavior({// 属性节点properties: {},// 私有数据节点data: { username: 'zs' },// 事件处理函数和自定义方法节点methods: {},// 其他节点... })
在组件中,使用
require()
方法导入需要的behavior
,挂载后即可访问behavior
中的数据或方法// 1. 使用 require() 方法导入需要的 behavior 模块 const myBehavior = require("../../behaviors/my-behavior")Component({// 2. 将导入的 behavior 实例对象,挂载到 behaviors 数组节点中behaviors: [myBehavior] })
十九. 使用 npm
包
Vant Weapp
: 是有赞前端团队开源的一套小程序UI
组件库,助力开发者快速搭建小程序应用。它所使用的是MIT
开源许可协议,对商业使用比较友好安装步骤:https://youzan.github.io/vant-weapp/#/quickstart#an-zhuang
如果项目初次使用
npm
,需执行npm init -y
,安装包管理文件(package.json
)通过
npm
安装(建议指定版本为@1.3.3
):npm i @vant/weapp@1.3.3 -S --production
修改
app.json
:将app.json
中的"style": "v2"
去除,小程序的新版基础组件强行加上了许多样式,难以覆盖,不关闭将造成部分组件样式混乱。构建
npm
包:打开微信开发者工具,点击 工具 -> 构建npm
,并勾选 使用npm
模块 选项,构建完成后,即可引入组件
使用
vant
组件(全局引入):在app.json
的usingComponents
节点中引入需要的组件,即可在wxml
中直接使用组件。// app.json "usingComponents": {"van-button": "@vant/weapp/button/index" }
// 页面的 .wxml 结构 <van-button type="primary">按钮</van-button>
API Promise
化默认情况下,小程序官方提供的异步
API
都是基于回调函数实现的,容易造成回调地狱的问题,代码的可读性、维护性差API Promise
化,指的是通过额外的配置,将官方提供的、基于回调函数的异步API
,升级改造为基于Promise
的异步API
,从而提高代码的可读性、维护性,避免回调地狱的问题。安装步骤:
npm install --save miniprogram-api-promise@1.0.4
(建议安装1.0.4版本)安装完成后,重新构建
npm
包(注意:如果项目中已存在miniprogram_npm
目录,需先删除再构建)在小程序入口文件中(
app.js
),只需调用一次promisefyAll()
方法,即可实现异步API
的Promise
化import { promisefyAll } from 'miniprogram-api-promise'const wxp = wx.p = {} promisefyAll(wx, wxp)
调用
Promise
化之后的异步API
// 页面结构 <van-button type="primary" bindtap="getInfo">按钮</van-button>
// 在页面的 .js 文件,定义对应的 getInfo 事件处理函数 async getInfo() {const { data: res } = await wx.p.request({method: 'GET',url: 'https://www.escook.cn/api/get',data: { name: 'zs', age: 20}})console.log(res) }
二十. 全局共享数据
全局数据共享(状态管理:是为了解决组件之间数据共享的问题(
Vuex、Redux、MobX
)在小程序中,可使用
mobx-miniprogram
配合mobx-miniprogram-bindings
实现全局数据共享。其中:mobx-miniprogram
用来创建Store
实例对象mobx-miniprogram-bindings
用来把Store
中的共享数据或方法,绑定到组件或页面中使用
安装步骤:
npm install --save mobx-miniprogram@4.13.2 mobx-miniprogram-bindings@1.2.1
MobX
相关的包安装完毕之后,删除miniprogram_npm
目录后,重新构建npm
创建
MobX
的Store
实例新建
Store
目录,再新建相应的.js
文件// 在这个 JS 文件中,专门来创建 Store 的实例对象 import { observable, action } from 'mobx-miniprogram'export const store = observable({// 数据字段numA: 1,numB: 2,// 计算属性get sum() {return this.numA + this.numB},// actions 方法,用来修改 store 中的数据updateNum1: action(function (step) {this.numA += step}),updateNum2: action(function (step) {this.numB += step}) })
将Store 中的成员绑定到页面中
- 页面的
.js
文件中:
// 页面的 .js 文件 import { createStoreBindings } from 'mobx-miniprogram-bindings' import { store } from '../../store/store'Page({onLoda: function () {// 完成绑定工作this.storeBindings = createStoreBindings(this, {store,fields: ['numA', 'numB', 'sum'], // 字段actions: ['updateNum1'] // 方法})},onUnload: function() {this.storeBindings.destroyStoreBindings() // 完成清除工作} })
- 在页面的
.wxml
中使用Store
中的成员
// 页面的 .wxml 结构 <view>{{numA}} + {{numB}} = {{sum}}</view> <van-button type="primary" bindtap="btnHandler1" data-step="{{1}}">numA + 1</van-button> <van-button type="danger" bindtap="btnHandler1" data-step="{{-1}}">numA - 1</van-button>
// 按钮事件处理函数 btnHander1(e) {this.updateNum1(e.target.dataset.step) }
- 页面的
将
Store
中的成员绑定到组件中在组件的
.js
文件中:import { storeBindingsBehavior } from 'mobx-miniprogram-bindings' import { store } from '../../store/store'Component({behaviors: [storeBindsBehavior], // 通过 storeBindingsBehavior 来实现自动绑定storeBindings: {store, // 指定要绑定的 Storefields: { // 指定要绑定的字段数据numA: () => store.numA, // 绑定字段的第 1 种方式numB: (store) => store.numB, // 绑定字段的第 2 种方式sum: 'sum' // 绑定字段的第 3 种方式},actions: { // 指定要绑定的方法// 自定义方法名: ’store 中的方法‘updateNum2: 'updateNum2'}} })
在组件的
.wxml
中使用Store
中的成员:// 组件的 .wxml 结构 <view>{{numA}} + {{numB}} = {{sum}}</view> <van-button type="primary" bindtap="btnHandler2" data-step="{{1}}">numB + 1</van-button> <van-button type="danger" bindtap="btnHandler2" data-step="{{-1}}">numB - 1</van-button>
// 组件的方法列表 methods: {btnHander1(e) {this.updateNum2(e.target.dataset.step)} }
二十一. 分包
概念:分包指的是把一个完整的小程序项目,按照需求划分为不同的子包,在构建时打包成不同的分包,用户在使用时按需进行加载。
优点:可以优化小程序首次启动的下载时间 ;对非
tabBar
页面进行按需加载;在多团队共同开发时可以更好的解耦协作。分包后,小程序项目由 1 个主包 + 多个分包组成:
主包:一般只包含项目的启动页面或
TabBar
页面、以及所有分包都需要用到的一些公共资源】分包:只包含和当前分包有关的页面和私有资源
配置方法
- 目录结构:
app.json
中相应代码,在subpackages
节点进行配置
独立分包:可以在不下载主包的情况下,独立运行(可以很大程度上提升分包页面的启动速度)
"subpackages": [{"root": "packageA","name": "pack1","pages": ["pages/apple","pages/banana"],"independent": true // 通过此节点,声明当前 moduleB 分包为“独立分包”} ]
分包预下载:在进入小程序的某个页面时,由框架自动预下载可能需要的分包,从而提升进入后续分包页面时的启动速度
在
app.json
中,与pages
节点平级,使用preloadRule
节点定义分包的预下载规则:{"preloadRule": {"pages/contact/contact": { // 触发分包预下载的页面途径"network": "all", // 可选值有“all”(不限网络进行预下载)和“wifi”(仅限wifi模式下)// packages 表示进入页面后,预下载哪些分包,可通过 root 或 name 指定预下载哪些分包"packages": ["pkgA"]}} }
微信小程序基础知识3相关推荐
- 【微信小程序】微信小程序基础知识篇
开发文档 小程序简介 | 微信开放文档 1.微信小程序的环境准备 1.1注册账号 1.2获取APPID 是开发者唯一的身份认证,应用要发布要上线必须提供APPID 1.3开发工具 由于微信小程序自带开 ...
- 微信小程序 基础知识
一.微信小程序是什么 微信小程序是一种不需要下载安装即可使用的应用 微信小是2017年1月9日,张小龙在2017微信公开课Pro上发布的微信小程序正式上线. 二.微信小程序商业价值 依托微信,有强大广 ...
- 微信小程序基础知识 || 如何让微信开发者工具显示切后台按键
文章目录 初识 小程序与普通网页开发的区别 体验小程序 获取AppID 开发者工具下载 在模拟器上查看项目效果 在真机上预览项目效果 主界面的 5 个组成部分 常用快捷键 宿主环境简介 通信模型 运行 ...
- 前端程序员需要了解的原生微信小程序-基础知识
前言:该学原生小程序啦 文档: 微信开放文档 工具下载: 稳定版 Stable Build | 微信开放文档 HBuilderX-高效极客技巧 你要是uniapp开发的就这个HB编译器打开项目 运行 ...
- 视频教程-2020最新微信小程序基础+实战精讲视频-微信开发
2020最新微信小程序基础+实战精讲视频 负责过多个软件项目的研发.设计和管理工作,拥有项目管理师认证.项目监理师中级认证.出版过的图书有<微信小程序开发图解案例教程><Axure ...
- 更改微信小程序的基础版本库;更改uni-app小程序基础库;更改用户的微信小程序基础库最低版本;设置用户的微信小程序版本库;
需求场景:微信小程序不少API都有最低版本支持,为了避免不必要的麻烦,我们可以根据需要给小程序设置基础库最低版本,这样若用户使用的基础库版本低于设置的最低版本要求,则无法正常使用小程序,并提示更新微信 ...
- 微信小程序在线知识答题有奖多开版源码
介绍: 微信小程序在线知识答题有奖源码是一款搭建在微擎上使用的 主要功能 答题有奖红包,可配合流量主推广,广告变现,后台含有区间余额区间奖励配置,自定义金额提现配置: 题库后台自己输入就可以了 .开 ...
- 《微信小程序-基础篇》初识微信小程序
大家好,好久不见了,前段时间各种原因分享不稳定,后面一段时间内参与了主站的原力计划,请麻烦各位支持一下,万分感谢- 本系列将从零开始介绍微信小程序的开发,介绍完基础以后会实际同步开发一个微信小程序的项 ...
- 微信小程序基础(全家福01)
微信小程序基础 目标 能够知道如何创建小程序项目 能够清除小程序项目的基本组成结构 能够知道小程序页面有几个部分组成 能够知道小程序中常见的组件如何使用 能够知道小程序如何进行协同开发和发布 讲解目录 ...
最新文章
- 【应用笔记】【AN001】VC#开发环境下基于以太网的4-20mA电流采集(基于modbus tcp 协议)...
- nginx+passenger下504 Gateway-Timeout问题的解决办法
- sql中的case when
- 张泉灵:时代抛弃你时,连一声再见都不会说
- Java基础_学习笔记_13_类的多态性(二)
- 北京理工大学计算机考研真题,北京理工大学计算机专业基础历年考研真题汇编附答案...
- OpenCV常用库函数
- VAE背后的哲学思想及数学原理
- win 7更改计算机用户名和密码错误,Win7旗舰版开机显示用户名和密码错误的解决教程...
- gentoo Cataclysm - Dark Days Ahead
- Ubuntu18.04之有道词典安装(五十九)
- PDF转PPT怎么转?一键完成格式转换,太方便了
- Oracle修改SEQUENCE起始值
- 卷妹的成长日记之javaweb day2
- 导入sql报错:1273 - Unknown collation: ‘utf8mb4_0900_ai_ci‘
- PacBio三代甲基化分析流程(不包含序列组装)
- python3 excel 图表导出图片_使用python代码将excel中的图表导出为图片
- QTP10破解时,运行mgn-mqt82.exe 就提示已停止工作
- 一文读懂 WebSocket 通信过程与实现
- WIFI之一:WIFI常识 基站定位原理
热门文章
- 如何在Go语言中调用DLL?
- 内向者优势 原版_性格内向的人如何笑傲职场?职业规划三步走,为你铺平道路...
- JS中常用的键盘事件与keycode属性
- Samsung eMCP LPDDR 2系列
- shiro漏洞工具简单配置
- Java 平台无关性的问题
- 华为机试中等难度题目
- 2021年信息学部物联网工程学院学生科协后端科普
- 苏小红c语言课后作业答案,《C语言程序设计》[苏小红]课后习题答案及解析高等教育出版社.doc...
- 【解析电脑为何要装驱动精灵】