小程序 便查手册

小程序巧应用,微信小程序开发实战

配置

app.json

  • pages -> 所有的页面
  • window -> 窗口的属性
    • "navigtionBarBackgroundColor":"#00000" ->导航栏背景颜色
    • "navgationBarTextStyle":"black/white" -> 导航栏标题颜色
    • "navgationBarTitleText":"标题" -> 导航栏文字
    • "backgroundColor":"#ffffff" -> 窗口的背景色
    • "backgroundTextStyle":"dark/light" -> 下拉背景字体,loading的样式
    • "enablePullDownRefresh":"false" -> 是否下拉刷新
  • tabBar -> bottomNav
    • 是一个list列表,最少2个,最多5个."tabBar": {"list": [{"pagePath": "pages/index/index", "text": "首页"}, {"pagePath": "pages/logs/logs", "text": "日志"}] },
    • list对象中支持 pagePath,text,iconPath,selectedIconPath(选中icon的图片路径)
  • "debug" -> true(默认是false)
  • networkTimeout ->
    • "request":30000 -> wx.request超时时间
    • "connectSocket":30000 -> wx.connectSocket 超时时间
    • "uploadFile":30000 -> wx.uploadFile超时时间
    • "downloadFile":3000 -> wx.downloadFile 超时时间

逻辑层

app.js

  • app({ function,function })

  • onLaunch -> 触发一次,初始化

  • onShow -> 启动/后台切换到前台 会触发onShow

  • onHide -> 进入后台

  • onError ->

  • 可以添加任意函数,用this可以访问(在app()中this可以拿到app实例)

  • 全局的getApp()

  • globalData:{} 全局参数 (类型Object)

page.js

  • page({ data:{},xx:funcation{} })

  • data -> 页面初始数据 (类型Object)

  • onLoad -> 生命周期-页面加载

    • options可以获取wx.navigateTowx.redirectTo以及<navigator/>中的query
  • onReady -> 生命周期-初次渲染完成

    • wx.setNavigationBarTitleonReady之后调用
  • onShow -> 生命周期-页面显示

  • onHide -> 生命周期-页面隐藏

    • navigateTo或者底部进行tab切换时调用
  • onUnload -> 生命周期-页面卸载

  • onPullDownRefreash -> 监听用户下拉

    • 需要在page.json中开启enablePullDownRefresh
  • onReachBottom -> 页面上拉触底事件的处理函数

  • onShareAppMessage -> 点击右上角分享

    • 只有定义了此事件,右上角才会显示分享
    • 需要return一个Object return{}
  • 可以添加任意函数,用this可以访问

  • 事件处理函数

    • <view bindtap="viewTap"></view> page({ viewTap:funcation(){console.loag('somethin')} })
  • getCurrentPage() 获取当前页面栈的实例,返回的是一个数组

    • 第一个是首页
    • 最后一个是当前页面
  • 路由相关

    • wx.navigateTo(Object) 保留当前页面,跳转到应用内的某个页面
    • wx.redirectTo(onject)关闭当前页面,跳转到应用内的某个页面
    • wx.navigateBack()关闭当前页面
  • 在page()中使用setData函数将数据从逻辑层发送到视图层,同时改变对应的this.data的值

    • this是包含它的函数作为方法被调用时所属的对象,在小程序中一般指调用页面
    • 我的理解是在data中定义value,在<view>中引用value,通过bindtap绑定方法,然后可以通过setData改变value的值,进而改变,view中的value
    • 上面这条未测试
  • 公共代码可以抽出来,通过module.exports={xx:funcation}暴露出来才能使用 var common = require('common.js')

微信原生Api

下面有单独的模块来展示

微信原生API有八大类,网络/媒体/文件.数据缓存/位置/设备/界面/微信开发接口

视图层

.wxml 与 .wxss结合

WXML

数据绑定

数据绑定 <view>{{message}}</view> Page({ data:{message:'Hello'} })

  • 简单绑定
    • 尖括号外面:使用Mustache语法{{}}将变量包起来
    • 组件属性(尖括号里面):需要在双引号之内
    • 控制属性(尖括号里面):例如下面的事件绑定中if后面的
  • 运算
    • 三元运算符<view hidden="{{flag?true:false}}"></view>
    • 算数,可以做正常的运算
    • 逻辑判断
    • 字符串拼接
  • 组合
    • 数组
    • 对象
    • 扩展运算符,可以将Object展开显示
列表渲染

列表渲染 <view wx:for="{{array}}">{{item}}</view> Page({ data:{array:[1,2,3,4,5]}})

  • 也可以使用<block/>属性
  • wx.key -> 列表中的位置会动态改变,或者有新的项目添加到列表中,希望列表中的项目保持自己的特征和状态 233页中有示例代码
条件渲染

条件渲染 <view if="{{view=='WEBVIEW'}}">WEBVIEW</view> <view elif="{{view=='APP'}}">APP</view> <view else="{{view=='MINA'}}">MINA</view> Page({data:{view:'MINA'}})

  • <block/>可以包裹多个组件,在<block/>属性中添加条件判断.<block/>不是一个组件,是一个包装元素,在页面中不做任何渲染,只是接受控制属性
  • wx:if与hidden的区别 : wx:if -> 是惰性的,如果初始渲染条件是false,框架什么也不做,在条件第一次变成真的时候才开始局部渲染. hidden初始就会被渲染. 频繁切换判断情景下用hidden,否则wx:if
模板

模板 <template> 这个 -> 在模板中定义代码片段,在其他地方调用

  • is声明需要使用的模板
  • 模板有自己的作用域,只能使用data传入数据
事件绑定

事件绑定 <view bindtap="add">{{count}}</view> Page({ data:{count:1}, add:funchtion(e){this.setData({count:this.data.count+1})} })

  • 视图层到逻辑层的通信方式,事件可以将用户行为反馈到逻辑层处理
  • 冒泡事件 : 当组件被触发后,该事件会向父节点传递
    • touchstart -> 手指触摸
    • touchmove -> 手指触摸后移动
    • touchcancel -> 手指触摸动作被打断(来电提醒,弹窗)
    • touchend -> 手指触摸动作结束
    • tap -> 手指触摸后离开
    • longtap -> 手指触摸后,超过350ms再离开
  • 非冒泡事件
    • 除上面6个之外,其他组件自定义事件都是非冒泡事件
    • <form/>的submit
    • <input/>的input
    • <scroll-view/>的scroll
  • 事件绑定的写法同组件的属性,以key,value的形式(key以bind或catch开头,如bindtap,catchtouchstart)(value是字符串,需要在page中定义同名函数)
  • bind事件不会阻止冒泡事件向上冒泡,catch会阻止
  • 事件触发的时候,逻辑层会受到一个事件对象
    • type(String) -> 事件类型
    • timeStamp(Integer) -> 事件生成时间
    • target(Object) -> 触发事件组件的一些属性集合(id:事件组件ID,tagName:事件组件的类型,dataset:事件组件上有data-开头的自定义属性组成的集合)
    • currentTarget(Object) -> 当前组件的属性集合
    • touches(Array) -> 触摸事件,当前停留在屏幕中触摸点信息的数组
    • changedTouches(Array) -> 触摸事件,当前变化的触摸点信息的数组
    • detail(Object) -> 课外的信息
引用

引用

  • import,会引用目标文件中定义的template
  • incloud,可将目标文件除模板代码 (<template/>)块的所有代码引入,相当于拷贝到 include位置

WXSS

  • 使用@import语句来导入外联样式表
  • wxss 选择器???/ .class #id element element,element ::after ::before 251页
  • rpx单位,iphone6尺寸设计
  • 所有组件都有的共同属性
    • id(String) -> 唯一标识
    • class(String) -> 样式
    • style(String) -> 内联样式
    • hidden(Boolean) -> 是否显示
    • data-*(Any) -> 自定义属性,组件上触发事件时,会发送给事件处理函数
    • bind* / catch*(EventHandler) -> 组件事件

组件

视图容器组件

  • view -> 相当于<div>
    • hover(Boolean) -> 是否启用点击
    • hover-class(String) -> 点击效果
    • hover-start-time(Number) -> 多久出现点击效果
    • hover-stay-time(Number) -> 手指松开后点击效果保留时间
  • scroll-view
    • scroll-x(Boolean) -> 允许横向滚动
    • scroll-y(Boolean) -> 允许纵向滚动
    • upper-threshole(Number) -> 默认值50 距离top/left多远(px),触发scrolltoupper事件
    • lower-threshold(Number) -> 默认值50 距离bottom/right多远(px),触发scrolltoupper事件
    • scroll-top(Number) -> 设置竖向滚动条的位置
    • scroll-left(Number) -> 设置横向滚动条的位置
    • scroll-into-view(String) -> 值为某个子元素的id,滚动到该元素,元素顶部对齐滚动区域顶部
    • bindscrolltoupper(EventHandle) -> 滚动到top/left ,触发scrolltoupper事件
    • bindscrolltoupper(EventHandle) -> 滚动到bottom/right ,触发scrolltoupper事件
    • bindscroll(EventHandle) -> 滚动时触发,event.detail={........}
  • swiper 其中只可以放置<swiper-item/>组件
    • indicator-dots(Boodlea) -> 是否显示指示点
    • indicator-color(Color) -> 默认gba(0,0,0,0.3) 指示点颜色
    • indicator-active-color(Color) -> 默认#000000 指示点选中颜色
    • autoplay(boolean) -> 自动
    • current(Number) -> 当前所在页面的index
    • interval(Number) -> 自动切换事件间隔
    • duration(Number) -> 滑动动画时长
    • circular(Boolean) -> 是否采用衔接滑动
    • bindchange(EventHandle) -> current改变时会触发change事件,event.detail={current:current}

基础内容组件

  • icon 图标组件
    • type(String) -> icon的类型,有效值:success,success_no_circle,info,warn,waiting,cancel,download,search,clear
    • size(Number) -> icon的大小(px),默认是23
    • color(Color) -> icon的颜色
  • text
  • progress 长的 进度条
    • percent(Float) -> 0~100
    • show-info(Boolean) -> 在进度条右侧显示百分比
    • stroke-width(Number) -> 默认值6 进度条的宽度
    • color(Color) -> 进度条的颜色
    • active(Boolean) -> 进度条从左到右的动画
  • 表单组件 button from input checkbox radio picker slider switch label
  • button
    • size(S) -> 有效值:default mini
    • typr(S) -> 按钮的样式类型,有效值:primary,default,warn
    • plain(Boolean) -> 按钮是否镂空,背景色透明
    • disabled(Boolean) -> 是否禁用
    • loading(B) -> 是否带loading图标
    • form-type(String) -> 有效值:submit,reset.用于<from>组件,点击分别处罚submit/reset事件
    • hover-class(String) -> 指定按钮按下去的样式类,当为none时,表示没有点击效果
    • hover-start-time(Number) -> 按住后对酒出现点击态
    • hover-stay-time(Number) -> 手指松开后点击态保留时间
  • checkbox-group 多项选择器组件,内部多个checkbox组成
    • bindchange(Eventhandle) -> 触发change事件,detail={value:[选中的checkbox的value的数组]}
  • checkbox
    • value(String) -> checkbox携带的value
    • disabled(Boolean) -> 是否禁用
    • checked(Boolean) -> 是否选中
    • color(Color) -> checkbox的颜色
  • from 为表单组件,用于提交用户输入的<switch> <input><checkbox><slider><radio><picker>
    • report-submit(Boolean) -> 是否返回formId用于发送模板消息
    • bindsubmit(EventHandle) -> 携带from中的数据出发submit事件,event.derail={value:{name:value},formId}
    • bindreset(EventHandle) -> 表单重置时会触发reset事件
  • input 用户输入字段
    • value(String)->输入框内容
    • type(String)->类型,有效值:text,number,idcard,digit,time,date
    • password(Boolean) -> 是否为密码
    • placeholder->占位
    • placeholder-style ->指定placeholder样式
    • placeholder-class ->placeholder样式类
    • disabled->是否禁用
    • maxlength->最大程度,默认140,0为无限制
    • cursor-spacing->光标与键盘的距离
    • focus->获取焦点
    • bindconfirm(EventHandle)->点击完成按钮触发,event.detail={value:value}
    • bindinput->除了date/time,键盘输入触发event.detail={value:value},处理函数可以返回一个字符串,替换输入框的内容
    • bindfocus->输入框聚焦时触发event.detail={value:value}
    • bindblur->失去焦点时触发event.detail={value:value}
  • label 组件标签,可以绑定的标签<button><checkbox><radio><switch>.用来改进表单组件的可用性,支持使用for属性找到对应的id,或者将控件放在该标签下,用户点击时,会触发对应的控件.for的优先级高于内部控件,内部多个控件时,默认触发第一个
  • picker 普通选择器,时间选择器,日期选择器
    • 普通选择器(mode=selector)
      • range(Array/Object Array) -> model为selector时,range有效
      • range-key(String) -> 当range为Object Array时,可以通过range-key开指定Object中key的值作为选择器的显示内容
      • value(Number) -> model为selector时,是数字,表示选择了range中的第几个
      • bindchange(Eventhandle) -> value改变时触发change事件,event.detail={value:value}
      • disable(B) -> 是否禁用
    • 时间选择器(mode-seletor) 格式 hh:mm
      • value(S) -> 选中时间
      • start(S) -> 有效时间范围的开始
      • end(S) -> 有效时间范围的结束
      • bindchange(Eventhandle) -> value改变时触发change事件,event.detail={value:value}
      • disable(B) -> 是否禁用
    • 日期选择器(mode=data) 格式 "yyy-MM-dd"
      • value(S) -> 选中日期
      • start(S) -> 有效日期范围的开始
      • end(S) -> 有效日期范围的结束
      • fields(S) -> 有效值year,month,day 表示选择器的粒度
      • bindchange(EventHandle) (S) -> 触发事件
      • disable(B) -> 是否禁用
  • picker-view嵌入页面的滚动选择组件,其中只能放<picker-view-column>
    • value(Number Array) -> 数组中的数字依旧表示picker-view内的picker-view-colume选择的第几项(下标从0开始),数字大于picker-view-column可选长度时,选择最后一项
    • indicator-style(S) -> 设置选择器中间选中框的样式
    • bindchange(EventHandle) -> detail={value:value};value为数组,表示选择第几项
  • radio-group 单项选择器
    • value
    • checked(B) -> 是否选中
    • disable(B) -> 是否禁用
    • color
  • slider 滑动选择器
    • min(N) -> 最小值 默认0
    • max(N) -> 最大值 默认100
    • step(N) -> 步长 默认1
    • value(N) -> 当前取值 默认0
    • color -> 背景条颜色
    • selected-color -> 已经选择的颜色
    • show-value(B) -> 是否显示当前value
    • bindchange -> 完成一次拖动后触发的事件 event.detail={value:value}
  • switch 开关
    • checked(B) -> 是否选中
    • type(S) -> 样式:switch checkbox
    • color
    • bindchange(eventhandle) -> 事件event.detail={value:value}
  • textarea 多行输入控件,属性太多了 318页

互动操作组件

  • action-sheet就是bottom Dialog
  • modal 模态弹窗组件 Dialog
    • title
    • no-cancle(B) -> 是否隐藏cancel按钮
    • confirm-text(S) -> confirm按钮文字
    • cancel-text(S) -> cancel按钮文字
    • bindconfirm -> confirm触发回调
    • bindcancel -> cancel以及蒙层触发回调
  • toast
    • duration
    • bindchange -> duration延时后触发
  • loading

页面导航组件

  • vavigator

媒体组件

  • image
    • src(S) -> 图片资源地址
    • mode(S) -> 图片裁剪,缩放的模式(缩放模式scaleToFill,aspectFit,aspectFill,widthFix)(裁剪模式Top,bottom,center,Left,right......等组件)
    • binderro -> 图片发生错误时
    • bindload -> 图片载入完毕
  • audio 音频组件
  • video 视频组件

地图组件

画布组件

WXML组件与HTML的差异

API接口的开发应用

网络API

  • wx.request(Object)发起https请求

  • wx.uploadfile(Object)上传开发者服务器

  • wx.downloadFile(Object)下载文件到本地

  • wx.connectSocket(Object)创建WebSocket连接

  • wx.onSocketOpen(Callback)监听WebSocket连接打开事件

  • wx.onSocketError(Callback)监听WebSocket错误

  • wx.onSocketMessage(Callback)监听WebSocket接收到服务器的消息事件

  • wx.closeSocket()关闭WebSocket连接

  • wx.onSocketClose(Callback)监听WebSocket关闭

媒体API

  • 图片
    • wx.chooseImage(Object) 本地选择或者拍照
    • wx.previewImage(Object) 预览图片
    • wx.getImageInfo(Object) 获取图片信息
  • 录音API
    • wx.startRecord(Object) 开始录音
    • wx.stopRecord(Object) 停止录音
  • 音频播放控制API
  • 音乐播放控制API
  • 视频API

文件API

  • wx.saveFile(Object) 保存
  • wx.getSavedFileInfo(Object) 获取本地文件信息
  • wx.removeSaveFile(Object) 删除
  • wx.openDocument(Object) 打开页面文档 (doc,xls,ppt,pdf,docx,xlsx,ppyx)

数据缓存API

  • wx.setStorage(Object) 接口实现将数据存 储在本地缓存中指定的key中。
  • wx.setStorageSync(Key,data) 接口实现将数据存 储在本地缓存中指定的key中。
  • wx.getStorage(Object) 接口用于从本地缓 存中异步获取指定key对应的内容。
  • wx.getStorageSync(Key) 接口用于从本地缓 存中同步获取指定key对应的内容。
  • wx.getStorageInfo(Object) 接口用于异步 获取当前storage的相关信息。
  • wx.getStorageInfoSync 接口用于同步获取当前 storage的相关信息。
  • wx.removeStorage(OBJECT) 接口用于从本 地缓存中异步移除指定key。
  • wx.removeStorageSync(KEY)接口用于从本 地缓存中同步移除指定key。
  • wx.clearStorage() 接口用于清理本地数据缓 存。
  • wx.clearStorageSync()接口用于同步清理本 地数据缓存。

位置API

  • wx.getLocation(OBJECT)获取当前的地理位

置、速度。

  • wx.chooseLocation(OBJECT)接口用于打开 地图选择位置。

  • wx.openLocation(OBJECT)接口用于实现使 用微信内置地图查看位置。

  • wx.createMapContext(mapId)接口用于创建 map上下文对象mapContext。

设备信息API

  • wx.getNetworkType(OBJECT)接口用于获取 网络类型。

  • wx.getSystemInfo(OBJECT)接口用于获取 系统信息。

  • wx.getSystemInfoSync()接口用于获取系统 信息同步。

  • wx.onAccelerometerChange(CALLBACK)接

口监听重力感应数据。

  • wx.onCompassChange(CALLBACK)接口实 现监听罗盘数据。

  • wx.makePhoneCall(OBJECT)接口用于拨打 电话。

  • wx.scanCode(OBJECT)接口用于调取客户 端进行扫码。

界面API

交互API
  • wx.showToast(OBJECT)接口用于显示消息

提示框。

  • wx.hideToast()接口用于隐藏消息提示框。

  • wx.showModal(OBJECT)接口用于显示模态 弹窗。

  • wx.showActionSheet(OBJECT)用于显示操 作菜单

页面导航API
  • wx.setNavigationBarTitle(OBJECT):动态 设置当前页面的标题。

  • wx.showNavigationBarLoading():接口实现 在当前页面显示导航条加载动画。

  • wx.hideNavigationBarLoading():接口实现 隐藏导航条加载动画。

  • wx.navigateTo(OBJECT):接口实现保留当 前页面,跳转到应用内的某个页面,使用 wx.navigateBack()可以返回到原页面。

  • wx.redirectTo(OBJECT):接口实现关闭当 前页面,跳转到应用内的某个页面。

  • wx.switchTab(OBJECT):接口实现跳转 tabBar页面并关闭其他所有非tabBar页面。

  • wx.navigateBack(OBJECT):接口实现关闭 当前页面,回退前一页面或多级页面。可通过 getCurrentPages())获取当前的页面栈,决定需 要返回几层。

动画API
  • wx.createAnimation(OBJECT), 接口用于实现创建动画,并在通过相应方法在页面 上描述动画过程
绘图API
其他API
  • wx.hideKeyboard()接口用于收起键盘。

  • wx.stopPullDownRefresh()接口用于停止当前页面下拉刷新。

  • Page.onPullDownRefresh是在Page方法中定义 的onPullDownRefresh处理函数,以监听该页面用户 下拉刷新的事件。需要在页面json文件的window配 置项中开启enablePullDownRefresh。当处理完数据 刷新后,使用wx.stopPullDownRefresh()就可以 停止当前页面的下拉刷新。

开放API
  • wx.login(OBECT)接口用于获取登录凭证 (code)及用户登录态信息。

  • wx.checkSession(OBJECT)接口用于检查登录态是否过期。

  • wx.getUserInfo(OBJECT)接口用于获取用户信息,需要先调用wx.login接口。

  • wx.requestPayment(OBJECT)接口用于发起微信支付。

  • 模板消息接口用于给用户发送如通知类的模板消息。

  • 客户消息接口用于客服会话消息的接收与发送。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342