微信小程序初级教程
转载请注明原创地址,谢谢
小程序代码构成
- JSON 配置
- WXML 模版
- WXSS 样式
- JS 逻辑交互
JSON 配置
在小程序中,JSON扮演的静态配置的角色。
小程序配置 app.json
{
"pages": ["pages/index/index", "pages/logs/logs"],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "WeChat",
"navigationBarTextStyle": "black"
}
}
- pages字段 —— 用于描述当前小程序所有页面路径,这是为了让微信客户端知道当前你的小程序页面定义在哪个目录。
- window字段 —— 定义小程序所有页面的顶部背景颜色,文字颜色定义等。
全局配置
https://developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html
tabBar
如果小程序是一个多 tab 应用(客户端窗口的底部或顶部有 tab 栏可以切换页面),可以通过 tabBar 配置项指定 tab 栏的表现,以及 tab 切换时显示的对应页面。
其中 list 接受一个数组,只能配置最少 2 个、最多 5 个 tab。tab 按数组的顺序排序,每个项都是一个对象
{
"pages": ["pages/index/index", "pages/logs/index"],
"tabBar": {
"list": [
{
"iconPath": "assets/fonts/首页.png",
"selectedIconPath": "assets/fonts/home.png",
"pagePath": "pages/index/index",
"text": "首页"
},
{
"pagePath": "pages/logs/logs",
"text": "日志"
}
]
}
}
tabBar 还有其他属性
颜色仅支持十六进制,定位仅支持top和bottom,其中top时不支持图标。
{
"tabBar": {
"color": "#ff00ff",
"selectedColor": "#0000ff",
"backgroundColor": "#00ff00",
"position":"bottom"
}
}
页面配置
每一个小程序页面也可以使用 .json 文件来对本页面的窗口表现进行配置。页面中配置项在当前页面会覆盖 app.json 的 window 中相同的配置项
页面配置中只能设置 app.json 中 window 对应的配置项,以决定本页面的窗口表现,所以无需写 window 这个属性。
WXML 模版
WXML 充当的就是类似 HTML 的角色。
<view class="container">
<view class="userinfo">
<button wx:if="{{!hasUserInfo && canIUse}}">获取头像昵称</button>
<block wx:else>
<image src="{{userInfo.avatarUrl}}" background-size="cover"></image>
<text class="userinfo-nickname">{{userInfo.nickName}}</text>
</block>
</view>
<view class="usermotto">
<text class="user-motto">{{motto}}</text>
</view>
</view>
block标签的作用是直接解析里面的内容,不解析自身block标签。
WXSS 样式
WXSS 具有 CSS 大部分的特性,小程序在 WXSS 也做了一些扩充和修改。
新增了尺寸单位。在写 CSS 样式时,开发者需要考虑到手机设备的屏幕会有不同的宽度和设备像素比,采用一些技巧来换算一些像素单位。WXSS 在底层支持新的尺寸单位 rpx ,开发者可以免去换算的烦恼,只要交给小程序底层来换算即可,由于换算采用的浮点数运算,所以运算结果会和预期结果有一点点偏差。
提供了全局的样式和局部样式。和前边 app.json, page.json 的概念相同,你可以写一个 app.wxss 作为全局样式,会作用于当前小程序的所有页面,局部页面样式 page.wxss 仅对当前页面生效。
此外 WXSS 仅支持部分 CSS 选择器
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxss.html
iPhone6 1rpx = 0.5px 1px = 2rpx
JS 逻辑交互
<view>{{ msg }}</view>
<button bindtap="clickMe">点击我</button>
Page({
data:{
msg: '小程序'
},
clickMe() {
this.setData({msg: 'Hello World'})
}
})
更详细的资料:https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/event.html
小程序宿主环境
- 渲染层和逻辑层
- 程序与页面
- 组件
- API
渲染层和逻辑层
小程序的运行环境分成渲染层和逻辑层,其中 WXML 模板和 WXSS 样式工作在渲染层,JS 脚本工作在逻辑层。
小程序的渲染层和逻辑层分别由2个线程管理:渲染层的界面使用了WebView 进行渲染;逻辑层采用JsCore线程运行JS脚本。一个小程序存在多个界面,所以渲染层存在多个WebView线程,这两个线程的通信会经由微信客户端(Native)做中转,逻辑层发送网络请求也经由Native转发。
程序与页面
微信客户端在打开小程序之前,会把整个小程序的代码包下载到本地。
紧接着通过 app.json 的 pages 字段就可以知道你当前小程序的所有页面路径。
整个小程序只有一个 App 实例,是全部页面共享的,具体内容查看注册程序 App https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/app.html
组件
小程序提供了丰富的组件
https://developers.weixin.qq.com/miniprogram/dev/component/
<navigator
url="/page/navigate/navigate?title=navigate"
hover-class="navigator-hover"
>
跳转到新页面
</navigator>
<navigator
url="../../redirect/redirect/redirect?title=redirect"
open-type="redirect"
hover-class="other-navigator-hover"
>
在当前页打开
</navigator>
<navigator
url="/page/index/index"
open-type="switchTab"
hover-class="other-navigator-hover"
>
切换 Tab
</navigator>
API
为了让开发者可以很方便的调起微信提供的能力,例如获取用户信息、微信支付等等,小程序提供了很多 API 给开发者去使用。
wx.scanCode({
success: (res) => {
console.log(res)
}
})
https://developers.weixin.qq.com/miniprogram/dev/api/index.html
视图层
- WXML
- WXS
- 事件系统
- 动画
- 组件
WXML
WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。
数据绑定
<!--wxml-->
<view>{{message}}</view>
// page.js
Page({
data: {
message: 'Hello MINA!'
}
})
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/data.html
列表渲染
默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item
<!--wxml-->
<view wx:for="{{array}}">{{item}}</view>
// page.js
Page({
data: {
array: [1, 2, 3, 4, 5]
}
})
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/list.html
如不提供 wx:key,会报一个 warning
<switch wx:for="{{objectArray}}" wx:key="unique" style="display: block;">
{{item.id}}
</switch>
Page({
data: {
objectArray: [
{id: 5, unique: 'unique_5'},
{id: 4, unique: 'unique_4'},
{id: 3, unique: 'unique_3'},
{id: 2, unique: 'unique_2'},
{id: 1, unique: 'unique_1'},
{id: 0, unique: 'unique_0'}
]
}
})
条件渲染
<!--wxml-->
<view wx:if="{{view == 'WEBVIEW'}}">WEBVIEW</view>
<view wx:elif="{{view == 'APP'}}">APP</view>
<view wx:else="{{view == 'MINA'}}">MINA</view>
// page.js
Page({
data: {
view: 'MINA'
}
})
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/conditional.html
wx:if vs hidden
wx:if 是惰性的,如果在初始渲染条件为 false,框架什么也不做,在条件第一次变成真的时候才开始局部渲染。
相比之下,hidden 就简单的多,组件始终会被渲染,只是简单的控制显示与隐藏。
一般来说,wx:if 有更高的切换消耗而 hidden 有更高的初始渲染消耗。因此,如果需要频繁切换的情景下,用 hidden 更好,如果在运行时条件不大可能改变则 wx:if 较好。
<view hidden="{{hidden}}">
内容
</view>
模板
<!--wxml-->
<template name="staffName">
<view>
FirstName: {{firstName}}, LastName: {{lastName}}
</view>
</template>
<template is="staffName" data="{{...staffA}}"></template>
<template is="staffName" data="{{...staffB}}"></template>
<template is="staffName" data="{{...staffC}}"></template>
// page.js
Page({
data: {
staffA: {firstName: 'Hulk', lastName: 'Hu'},
staffB: {firstName: 'Shang', lastName: 'You'},
staffC: {firstName: 'Gideon', lastName: 'Lin'}
}
})
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/template.html
引用
WXML 提供两种文件引用方式import和include。
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/import.html
<!-- item.wxml -->
<template name="item">
<text>{{text}}</text>
</template>
在 index.wxml 中引用了 item.wxml,就可以使用item模板:
<import src="item.wxml" />
<template is="item" data="{{text: 'forbar'}}" />
WXS
WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxs/
页面渲染
<!--wxml-->
<wxs module="m1">
var msg = "hello world"; module.exports.message = msg;
</wxs>
<view>{{m1.message}}</view>
页面输出:
hello world
事件系统
https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/event.html
什么是事件
- 事件是视图层到逻辑层的通讯方式。
- 事件可以将用户的行为反馈到逻辑层进行处理。
- 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数。
- 事件对象可以携带额外信息,如 id, dataset, touches。
事件的使用方式
<view id="tapTest" data-hi="WeChat" bindtap="tapName">Click me!</view>
Page({
tapName(event) {
console.log(event)
}
})
事件绑定和冒泡
事件绑定的写法同组件的属性,以 key、value 的形式。
- key 以bind或catch开头,然后跟上事件的类型,如bindtap、catchtouchstart。
- value 是一个字符串,需要在对应的 Page 中定义同名的函数。不然当触发事件的时候会报错。
bind事件绑定不会阻止冒泡事件向上冒泡,catch事件绑定可以阻止冒泡事件向上冒泡。
如在下边这个例子中,点击 inner view 会先后调用handleTap3和handleTap2(因为tap事件会冒泡到 middle view,而 middle view 阻止了 tap 事件冒泡,不再向父节点传递),点击 middle view 会触发handleTap2,点击 outer view 会触发handleTap1。
<view id="outer" bindtap="handleTap1">
outer view
<view id="middle" catchtap="handleTap2">
middle view
<view id="inner" bindtap="handleTap3">
inner view
</view>
</view>
</view>
事件的捕获阶段
需要在捕获阶段监听事件时,可以采用capture-bind、capture-catch关键字,后者将中断捕获阶段和取消冒泡阶段。
在下面的代码中,点击 inner view 会先后调用handleTap2、handleTap4、handleTap3、handleTap1。
<view
id="outer"
bind:touchstart="handleTap1"
capture-bind:touchstart="handleTap2"
>
outer view
<view
id="inner"
bind:touchstart="handleTap3"
capture-bind:touchstart="handleTap4"
>
inner view
</view>
</view>
动画
方案1:写css样式
#box2{
height: 100px;
width: 100px;
background: blue;
}
#box2:hover{
transform: rotate(180deg) scale(.5, .5);
background: red;
transition: background 2s ease, transform 2s ease-in 1s;
}
方案2:animate.css 库
// app.wxss 在主页面引入,page页面就都可以使用了
@import './assets/animate.wxss';
<view class='{{a}}'></view>
this.setData({
a : ['box', 'animated', 'fadeOutRight']
})
方案3:写js函数
https://developers.weixin.qq.com/miniprogram/dev/api/wx.createAnimation.html
<button bindtap="fn">动画</button>
<view
animation="{{animationData}}"
style="background:red;height:100rpx;width:100rpx;position: absolute;top:1000rpx;"
></view>
data: {
animationData: {}
},
fn() {
const animation = wx.createAnimation({
duration: 3000
})
this.animation = animation
animation.scale(2, 2).rotate(45).step().width(400).top(10).step()
this.setData({
animationData: animation.export()
})
}
step方法表示动画完成。一组动画中的所有动画会同时开始,一组动画完成后才会进行下一组动画。
导出动画队列。export 方法每次调用后会清掉之前的动画操作。
组件
定义组件
鼠标右键->新建组件,会生成一组文件。
// components/toast/toast.js
Component({
//组件的属性列表
properties: {
str : String
},
//组件的生命周期函数
lifetimes: {
attached() {
// 在组件实例进入页面节点树时执行
console.log('attached:', this.properties.str);
},
detached() {
// 在组件实例被从页面节点树移除时执行
console.log('删除')
}
},
// 组件的初始数据
data: {
},
// 组件的方法列表
methods: {
show(){
}
}
})
// components/toast/toast.wxml
<view>
传过来的属性:{{str}}
</view>
使用组件
// pages/mine/mine.json
{
"usingComponents": {
"toast":"/components/toast/toast"
}
}
// pages/mine/mine.wxml
<toast id="abc" str="hello"></toast>
// pages/mine/mine.js
Page({
data: {
},
fn(){
this.toast = this.selectComponent("#abc");
this.toast.show();
}
})
逻辑层
- 生命周期
- 路由
- 模块化
生命周期
page页的生命周期:https://developers.weixin.qq.com/miniprogram/dev/guide/framework/page-life-cycle.html
page页生命周期钩子函数的示例代码:https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html
component页的生命周期:https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/lifetimes.html
组件的生命周期,指的是组件自身的一些函数,这些函数在特殊的时间点或遇到一些特殊的框架事件时被自动触发。
其中,最重要的生命周期是 created attached detached ,包含一个组件实例生命流程的最主要时间点。
- 组件实例刚刚被创建好时, created 生命周期被触发。此时,组件数据 this.data 就是在 Component 构造器中定义的数据 data 。 此时还不能调用 setData 。 通常情况下,这个生命周期只应该用于给组件 this 添加一些自定义属性字段。
- 在组件完全初始化完毕、进入页面节点树后, attached 生命周期被触发。此时, this.data 已被初始化为组件的当前值。这个生命周期很有用,绝大多数初始化工作可以在这个时机进行。
- 在组件离开页面节点树后, detached 生命周期被触发。退出一个页面时,如果组件还在页面节点树中,则 detached 会被触发。
自小程序基础库版本 2.2.3 起,组件的的生命周期也可以在 lifetimes 字段内进行声明(这是推荐的方式,其优先级最高)。
Component({
lifetimes: {
attached() {
// 在组件实例进入页面节点树时执行
},
detached() {
// 在组件实例被从页面节点树移除时执行
},
},
// 以下是旧式的定义方式,可以保持对 <2.2.3 版本基础库的兼容
attached() {
// 在组件实例进入页面节点树时执行
},
detached() {
// 在组件实例被从页面节点树移除时执行
},
// ...
})
页面路由
在小程序中所有页面的路由全部由框架进行管理。
页面栈
https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/route.html
打开新页面
调用 API wx.navigateTo
保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面。
wx.navigateTo({
url: 'test?id=1'
})
// test.js
Page({
onLoad(option) {
console.log(option.query)
}
})
使用组件
<navigator open-type="navigateTo"/>
页面重定向
调用 API wx.redirectTo
关闭当前页面,跳转到应用内的某个页面。但是不允许跳转到 tabbar 页面。
wx.redirectTo({
url: 'test?id=1'
})
使用组件
<navigator open-type="redirectTo"/>
页面返回
调用 API wx.navigateBack
关闭当前页面,返回上一页面或多级页面。
// 注意:调用 navigateTo 跳转时,调用该方法的页面会被加入堆栈,而 redirectTo 方法则不会。见下方示例代码
// 此处是A页面
wx.navigateTo({
url: 'B?id=1'
})
// 此处是B页面
wx.navigateTo({
url: 'C?id=1'
})
// 在C页面内 navigateBack,将返回A页面
wx.navigateBack({
delta: 2
})
使用组件
<navigator open-type="navigateBack">
用户按左上角返回按钮
Tab 切换
调用 API wx.switchTab
跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
{
"tabBar": {
"list": [
{
"pagePath": "index",
"text": "首页"
},
{
"pagePath": "other",
"text": "其他"
}
]
}
}
wx.switchTab({
url: '/index'
})
使用组件
<navigator open-type="switchTab"/>
用户切换 Tab
重启动
调用 API wx.reLaunch
关闭所有页面,打开到应用内的某个页面
wx.reLaunch({
url: 'test?id=1'
})
使用组件
<navigator open-type="reLaunch"/>
模块化
CommonJS规范
可以将一些公共的代码抽离成为一个单独的 js 文件,作为一个模块。模块通过 module.exports 能对外暴露接口。
// common.js
function sayHello(name) {
console.log(`Hello ${name} !`)
}
module.exports.sayHello = sayHello
const common = require('common.js')
Page({
helloMINA() {
common.sayHello('MINA')
}
})
文件作用域
在 JavaScript 文件中声明的变量和函数只在该文件中有效;不同的文件中可以声明相同名字的变量和函数,不会互相影响。
通过全局函数 getApp 可以获取全局的应用实例,如果需要全局的数据可以在 App 中设置,如:
// app.js
App({
globalData: 1
})
// a.js
// Get the app instance.
const app = getApp()
// Get the global data and change it.
app.globalData++
// b.js
// 如果是从a跳转到b,那么这次输出的是2
console.log(getApp().globalData)
能力
- 网络
- 存储
网络
服务器域名配置
每个微信小程序需要事先设置一个通讯域名,小程序只可以跟指定的域名与进行网络通信。包括普通 HTTPS 请求(wx.request)、上传文件(wx.uploadFile)、下载文件(wx.downloadFile) 和 WebSocket 通信(wx.connectSocket)
跳过域名校验
在微信开发者工具中,可以临时开启 开发环境不校验请求域名、TLS版本及HTTPS证书 选项,跳过服务器域名的校验。此时,在微信开发者工具中及手机开启调试模式时,不会进行服务器域名的校验。
wx.request({
url: 'test.php', // 仅为示例,并非真实的接口地址
data: {
x: '',
y: ''
},
header: {
'content-type': 'application/json' // 默认值
},
success(res) {
console.log(res.data)
}
})
https://developers.weixin.qq.com/miniprogram/dev/api/wx.request.html
存储
每个微信小程序都可以有自己的本地缓存
设置
单个 key 允许存储的最大数据长度为 1MB,所有数据存储上限为 10MB。
wx.setStorage({
key: 'key',
data: 'value'
})
try {
wx.setStorageSync('key', 'value')
} catch (e) { }
获取
wx.getStorage({
key: 'key',
success(res) {
console.log(res.data)
}
})
const value = wx.getStorageSync('key')
清理本地所有数据
wx.clearStorage({
success(){}
})
wx.clearStorageSync()
删除指定的key
wx.removeStorage({
key: 'key',
success(res) {
console.log(res.data)
}
})
wx.removeStorageSync('key')
界面交互
显示消息提示框
wx.showToast({
title: '成功',
icon: 'success',
duration: 2000
})
显示模态对话框
wx.showModal({
title: '提示',
content: '这是一个模态弹窗',
success(res) {
if (res.confirm) {
console.log('用户点击确定')
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
loading 提示框
显示 loading 提示框。需主动调用 wx.hideLoading 才能关闭提示框
wx.showLoading({
title: '加载中',
})
setTimeout(function () {
wx.hideLoading()
}, 2000)
显示操作菜单
wx.showActionSheet({
itemList: ['A', 'B', 'C'],
success(res) {
console.log(res.tapIndex)
},
fail(res) {
console.log(res.errMsg)
}
})
结束
微信小程序当然还提供其他能力,具体应查看官方文档。
微信小程序初级教程的更多相关文章
- 微信小程序开发教程目录
本系列教程是自己在工作中使用到而记录的,没有顺序之分 如有错误之处,请给与指正,也不希望误导了别人 微信小程序开发教程目录 微信小程序之注册和入门 微信小程序之HTTPS请求 微信小程序开发之选项卡 ...
- 微信小程序开发教程 #043 - 在小程序开发中使用 npm
本文介绍了如何在微信小程序开发中使用 npm 中包的功能,大大提高微信小程序的开发效率,同时也是微信小程序系列教程的视频版更新. 微信小程序在发布之初没有对 npm 的支持功能,这也是目前很多前端开发 ...
- 从零开始的微信小程序入门教程(一)
之前说要和同事一起开发个微信小程序项目,现在也在界面设计,功能定位等需求上开始实施了.所以在还未正式写项目前,打算在空闲时间学习下小程序.本意是在学习过程中结合实践整理出一个较为入门且不是很厚的教程, ...
- 微信小程序开发教程
9月21日晚发布的微信公众平台·小程序内侧邀请,微信应用号(小程序,「应用号」的新称呼)终于来了!目前还处于内测阶段,微信只邀请了部分企业参与封测.想必大家都关心应用号的最终形态到底是什么样子? 怎样 ...
- 微信小程序简易教程
刚接触到微信小程序开发,这里做一个简单的教程: 1. 获取微信小程序的 AppID 登录 https://mp.weixin.qq.com ,就可以在网站的"设置"-"开 ...
- 开发一个微信小程序项目教程
一.注册小程序账号 1.进入微信公众平台(https://mp.weixin.qq.com/),注册小程序账号,根据提示填写对应的信息即可.2.注册成功后进入首页,在 小程序发布流程->小程序开 ...
- 微信小程序实例教程(一)
序言 开始开发应用号之前,先看看官方公布的「小程序」教程吧!(以下内容来自微信官方公布的「小程序」开发指南) 本文档将带你一步步创建完成一个微信小程序,并可以在手机上体验该小程序的实际效果.这个小程序 ...
- 微信小程序实例教程(二)
第五章:微信小程序名片夹详情页开发 今天加了新干货!除了开发日志本身,还回答了一些朋友的问题. 闲话不多说,先看下「名片盒」详情页的效果图: 备注下大致需求:顶部背后是轮播图,二维码按钮弹出模态框信息 ...
- 开发一个微信小程序实例教程
一.注册小程序账号 1.进入微信公众平台(https://mp.weixin.qq.com/),注册小程序账号,根据提示填写对应的信息即可.2.注册成功后进入首页,在 小程序发布流程->小程序开 ...
随机推荐
- [Pandas] 05 - Parallel processing
相关资源 [Python] 09 - Multi-processing [Pandas] 01 - A guy based on NumPy [AI] 深度数学 - Bayes 这章非常有意思,但一定 ...
- Linux线程唤醒与等待
生产者消费者模式在程序设计中出现频率非常高,经常会有线程间通过消息队列或其他共享变量进行交互的场景.而这时就会出现一个问题,消费者如何知道生产者已经生产了数据呢?有的程序会采取消费者循环判断消息队列大 ...
- BOM之本地数据存储
JavaScript中本地存储数据常用的,且兼容性较好的有两种方式,cookie和Storage.另外还可以使用location.hash临时存储少量关键信息. 一 location.hash ...
- Python3.7.4入门-3函数
3 函数 3.1 定义函数 def fib(n): # write Fibonacci series up to n """Print a Fibonacci serie ...
- Windows认证 | Windows本地认证
Windows的登陆密码是储存在系统本地的SAM文件中的,在登陆Windows的时候,系统会将用户输入的密码与SAM文件中的密码进行对比,如果相同,则认证成功. SAM文件是位于%SystemRoot ...
- Android Studio [真机测试/开发者模式]
一.手机设置 首先根据自己的手机型号百度打开开发者模式, 我的是vivo,设置--->更多设置-->关于手机-->软件版本号连续点击会提示开启开发者模式. 并在开发者选项里打开USB ...
- Tomcat+Nginx+Linux+Mysql部署豆瓣TOP250的项目到腾讯云服务器
写在前面 因为前面有写过一篇关于豆瓣的top250的电影的可视化展示项目,你可以移步http://blog.csdn.net/liuge36/article/details/78607955了解这个项 ...
- Linux 查看端口状态netstat
netstat命令参数: -t : 指明显示TCP端口 -u : 指明显示UDP端口 -l : 仅显示监听套接字(所谓套接字就是使应用程序能够读写与收发通讯协议(protocol)与资料的程序) -p ...
- .Net Core 商城微服务项目系列(九):使用Jenkins构建自动发布
1.首先通过Docker运行Consul,并保证各个服务都成功注册: 然后运行jenkins,对MI.Web项目进行发布构建,至于怎么配置之前已经写过了,和上一篇一模一样,这里贴下批处理命令: cd ...
- [scrapy-redis] install and configure scrapy-redis on CentOS 7 (1)
0. 安装依赖 yum install -y zlib zlib-devel openssl openssl-devel bzip2 bzip2-devel sqlite-devel gcc wget ...