一、项目基本结构

(一)tabbar页面

首页                                                 分类

购物车

我的(用户中心)

(二)非tabbar页面

搜索

商品列表

商品详情

微信支付

结构解析:

1. 构建一个小程序,需要先将小程序的页面结构分类、理清。

现大多数小程序页面结构分为tabbar页面和非tabbar页面。tabbar页面作为小程序的主体框架,所以应该先搭建好tabbar页面,非tabbar页面在此框架上运行。

2. 由于存在tabbar页面和非tabbar页面,因此将小程序项目分为主包和分包

  • 主包:小程序启动页或tabbar页面以及公共资源
  • 分包:非tabbar页面和私有资源

普通分包页面:先下载主包,再跳转至普通分包运行普通分包的页面

独立分包页面:不依赖于主包,可自己独立运行(配置时加上:"independent" : true)

配置pages.json

// 主包----pages:tabbar页面放入"pages": [{"path" : "pages/home/home","style" : {}},{"path" : "pages/cate/cate","style" : {}},{"path" : "pages/cart/cart","style" : {}},{"path" : "pages/my/my","style" : {}}],
--------------------------------------------------
// subPackages(数组):每个分包为一个对象,每个分包的pages(数组)可包含多个非tabbar页面(对象)
// {root: 该分包在项目中的目录name: 分包别名pages: [{path: 非tabbar页面在此分包下的路径style: 非tabbar页面的配置}]independent: true   // 与root平级,加上independent:true,则此分包为独立分包}
--------------------------------------------------"subPackages":[{"root":"subpkg","name":"p1","pages":[{"path" : "goods_detail/goods_detail","style" : {}},{"path" : "goods_list/goods_list","style" : {"onReachBottomDistance":150,"enablePullDownRefresh":true,"backgroundColor":"#F8F8F8"}},{"path" : "search/search","style" : {}}]}],

分包预下载:在进入某页面时,可预先下载可会用到的某分包,提高性能

配置pages.json

 "preloadRule": {        // preloadRule 关键字与pages平级"pages/index": {        // pages/index 触发预下载的路径"network": "all",        // network 表示在指定网络模式下进行预下载 可选all/wifi"packages": ["package1"]    // packages 预下载哪个分包 ["分包root或name"]},"sub1/index": {"packages": ["package2", "package3"]},}

即:当页面为 /pages/index 时,预下载 package1分包;当页面为 /sub1/index 时,预下载 package2和package3分包。

限制:同一个分包中的页面享有共同的预下载大小限额 2M,限额会在工具中打包时校验。

如,页面 A 和 B 都在同一个分包中,A 中预下载总大小 0.5M 的分包,B中最多只能预下载总大小 1.5M 的分包。

3. tabbar徽标的配置

以此项目为例:cart页面需要右上角徽标,且切换至其他tabbar页面时,cart页面的徽标也要显示(当数值为零时移除徽标)

当多个页面都有相同业务逻辑时,封装一个mixins(js),然后引入至各个页面使用

## uni.setTabBarItem( ) 和 uni.setTabBarItem( )的使用

## minxins/tabbar-badge.jsimport {mapGetters} from 'vuex'export default {computed:{...mapGetters('cart',['totalCount'])    // 用作设置徽标的数值},watch:{// 当totalCount改变时,再次设置徽标totalCount:{immediate:true,handler(){this.setTabbarBadge()}}},onLoad(){this.setTabbarBadge()},// 再次进入onShow() {this.setTabbarBadge()},methods:{setTabbarBadge(){// 当购物车中商品数量为0时,去除徽标if(this.totalCount==0){uni.removeTabBarBadge({index:2})return}uni.setTabBarBadge({index:2,text:this.totalCount.toString()  // 字符串类型!!!!})}}
}
-----------------------------------------
## home.vue  cate.vue  cart.vue  my.vueimport badgeMix from '@/mixins/tabbar-badge.js'    // 引入
export default {minxins:[badgeMix]    // 使用}

其他注意事项

  • 配置manifest.json
 "mp-weixin" : {/* 小程序特有相关 */"setting" : {/*其他代码*/"checkSiteMap":false},
},
  • 若项目是他人的(接口地址涉及权限的),要他人在开发管理人员添加自己,才能有权限请求接口
  • 配置store以及挂载至vue的原型对象上

二、起步

工具:1.HBuilderX:2.7.14.20200618(安装 scss/sass 编译)   2.微信开发者工具:1.05.2105170

新建项目,在项目根目录中新建 .gitignore 忽略文件,并配置如下:

# 忽略 node_modules 目录
/node_modules
/unpackage/dist

在 unpackage 目录下创建一个叫做 .gitkeep 的文件进行占位

三、框架搭建(即搭建tabbar页面)

配置pages.json--tabBar(注意路径前均没有 "/")

四、配置网络请求

在main.js中引入和配置,具体参考:

@escook/request-miniprogram - npm

项目根目录打开终端 ==> npm init -y ==> npm i @escook/request-miniprogram ==> main.js引入

==> 挂载至uni.$http ==> 设置请求根路径(hostip单独设置,从utils/hostip.js引入)

==> 请求拦截器(showLoading)、响应拦截器(hideLoading)、封装弹窗函数

五、使用Git管理项目

1.本地管理、把项目托管至远程仓库

git init ==> git add . ==> git commit -m "初始化项目" ==> git remote add origin SSH

==> git branch -M main ==> git push -u origin main

2.每开始一个页面(分支)的搭建,先创建分支

git checkout -b tabbar(分支名称)

3.完成了该分支

1)本地分支提交:git add . ==> git commit -m "完成了 tabbar 的开发"

2)将本地分支推送至远程仓库:git push -u origin tabbar

3)将本地分支合并至main分支上:git checkout main ==> git merge tabbar

4)删除本地tabbar分支:git branch -d tabbar

六、页面、组件的搭建,以及数据的获取

(一)home.vue搭建

(二)cate.vue搭建

1.使用<scroll-view>:

1)指定滑动方向:scroll-y

2)给定一个宽度或高度:onLoad()时,获取可使用窗口高度

<scroll-view :style="{height:height+'px'}">...</scroll=view>data() {return {height:0}
},
onLoad() {// 获取可使用高度const info=uni.getSystemInfoSync()this.height=info.windowHeight-50    // 动态给高度赋值this.getCatelist()},

首次渲染时,默认一级分类(选中)==>一级分类children(二级分类)

onLoad==>调用获取数据的函数(){// 二级分类数据首次渲染第一个一级分类的childrenthis.cateLevel2 = res.message[0].children
}// 当点击一级分类切换时==>调用点击切换函数(index){this.cateLevel2 = res.message[index].children
}

解决切换一级分类后重置滚动条的位置

<scroll-view :scroll-top="scrollTop"></scroll-view>data() {return {// 滚动条距离顶部的距离scrollTop: 0}
}// 点击切换一级分类的函数(){this.scrollTop = this.scrollTop === 0 ? 0.01 : 0    // scrollTop前后数据要不一致
}

(三)搜索

封装自定义组件my-search、新建分包页面search

1.cate页面中,<scroll-view>高度的调整

my-search组件使用在cate.vue中,由于my-search的高度为50px

因此,scroll-view的高度 = 可使用屏幕高度 - my-search的高度(50)

2.my-search组件实现吸顶效果

<view class="search-box"><my-search @click="gotoSearch"></my-search>
</view>.search-box {// 设置定位效果为“吸顶”position: sticky;        // 不用固定定位,固定定位不占位置,脱离文档流// 吸顶的“位置”top: 0;// 提高层级,防止被轮播图覆盖z-index: 999;
}

3.使用<uni-search-bar></uni-search-bar>内置组件

对内置的<uni-search-bar>组件进行调整:

1)修改背景色:使用深度选择器

// 深度选择器:
// 1)原生css: >>> 子组件中的类名
// 2)less: /deep/ 子组件中的类名
// 3)sass: :v-deep 子组件中的类名
// 4)其他格式: ::v-deep 子组件中的类名
// 注意:要加上 !important::v-deep .uni-searchbar {background-color: #c00000 !important;
}

2)实现搜索框自动获取焦点

<uni-search-bar>组件中,实现自动获取焦点的属性show和showSync在data中默认为false,可设置props属性,由父组件传入值,实现搜索框自动获取焦点

## uni-search-bar源代码修改
props: {.....// 修改showInit:{type:Boolean,default:false},showSyncInit:{type:Boolean,default:false}},data() {return {show: this.showInit,showSync: this.showSyncInit,searchVal: ""}},// 组件使用时,在父组件传入值
<uni-search-bar :showInit="true" :showSyncInit="true"></uni-search-bar>// 当传入值非字符型类型时,前面均需要用:绑定

3)搜索框防抖效果

input(e) {// 清除 timer 对应的延时器clearTimeout(this.timer)// 重新启动一个延时器,并把 timerId 赋值给 this.timerthis.timer = setTimeout(() => {// 如果 500 毫秒内,没有触发新的输入事件,则为搜索关键词赋值this.kw = e.valueconsole.log(this.kw)}, 500)
}

4.搜索建议与搜索历史的渲染以及切换

搜索历史的渲染:1)使用内置组件<uni-tag></uni-tag>

2)注意最新历史在第一位(unshift),以及去重问题(splice(index,1))

3)点击图标,清空历史记录(vuex,本地存储的都清空)

两个页面的切换:根据搜索建议列表的长度(length)

数据存储的构思:

  • 构思:哪些数据是不随刷新(重新进入小程序)而改变的(存在于本地)?哪些数据是要跨页面、跨组件使用的(存于vuex中)?
  • 基本上存储于vuex中的数据,大多数都有update,saveToStorage。。。的需求

search页面的搜索历史记录(history)、cart页面的商品(即已加入购物车的商品cart)、cart页面的地址(address)、my页面的用户信息(userInfo)、鉴定用户是否已登录的token、重定向信息(redirectInfo)等等。。。

将以上符合条件的数据存储于vuex中,并且存储于本地,同时使vuex中的数据和本地保持同步!

流程:请求回来的数据==>dispatch/commit(handler,数据)==>在commit中,state.xxx=数据

==>调用本地存储handler()==>在本地存储handler(state)中,拿state.xxx存储于本地

==>state.xxx=从本地取回数据==>getters:对state.xxx进行进一步改造调整

## 当组件或页面需要数据时,从vuex的state中拿

## 不要将getters里的数据存储于本地,因为其来源于state,要将源头存储于本地(保持数据更新同步),而不是改造后的数据

(四)商品列表

1.新建分包页面my-goods_list

1)页面跳转所携带过来的参数,在onLoad(options)函数的options中

onLoad(options) {// 将页面参数转存到 this.queryObj 对象中this.queryObj.query = options.query || ''this.queryObj.cid = options.cid || ''
}

2)请求数据前,先整理请求参数(具体参考请求文档)

data() {return {// 请求参数对象queryObj: {// 查询关键词query: '',// 商品分类Idcid: '',// 页码值pagenum: 1,// 每页显示多少条数据pagesize: 10}}
}

2.在分包页面my-goods_list中,将商品 item 项封装为自定义组件my-goods

因为:商品列表中的每个商品的结构与购物车中要展示的商品的结构类似,可以复用

使用:<my-goods :goods="goods"></my-goods>        传入的是每个商品项

3.使用过滤器处理价格

// 在 my-goods 组件中,和 data 节点平级,声明 filters 过滤器节点如下:filters: {// 把数字处理为带两位小数点的数字tofixed(num) {return Number(num).toFixed(2)}
}// 在渲染商品价格的时候,通过管道符 | 调用过滤器:<view class="goods-price">¥{{goods.goods_price | tofixed}}</view>

4.上拉加载更多、下拉刷新

1)上拉加载更多(可配置文件调整onReachBottomDistance,默认50)

  • 节流阀
  • 判断数据是否加载完毕(当前页码值 * 每页展示数据条数 >= 总数据条数)
// 触底的事件
onReachBottom() {// 让页码值自增 +1this.queryObj.pagenum += 1// 重新获取列表数据this.getGoodsList()
}// 改造 methods 中的 getGoodsList 函数,当列表数据请求成功之后,进行新旧数据的拼接处理:
this.goodsList = [...this.goodsList, ...res.message.goods]

2)下拉刷新(配置文件开启下拉刷新enablePullDownRefresh)

  • 重点:重置数据
// 下拉刷新的事件
onPullDownRefresh() {// 1. 重置关键数据this.queryObj.pagenum = 1this.total = 0this.isloading = falsethis.goodsList = []// 2. 重新发起请求this.getGoodsList(() => uni.stopPullDownRefresh())    // 完成后,关闭下拉
}

(五)商品详情

新建分包页面goods_detail

1.轮播图预览效果

preview(i) {// 调用 uni.previewImage() 方法预览图片uni.previewImage({// 预览时,默认显示图片的索引current: i,// 所有图片 url 地址的数组urls: this.goods_info.pics.map(x => x.pics_big)})
}

2.渲染商品详情信息

1)rich-text

<rich-text :nodes="goods_info.goods_introduce"></rich-text>

2)解决图片空白间隙问题

// 因为行内块元素(这里的图片)默认是与文字基线对齐的
// 解决:1.vertical-align: top;vertical-align: middle;2.display: block;// 使用字符串的 replace() 方法,为 img 标签添加行内的 style 样式,从而解决图片底部空白间隙的问题
res.message.goods_introduce = res.message.goods_introduce.replace(/<img /g, '<img style="display:block;" ')

3)解决.web格式图片在ios设备上无法正常显示问题

// 使用字符串的 replace() 方法,将 webp 的后缀名替换为 jpg 的后缀名
res.message.goods_introduce = res.message.goods_introduce.replace(/<img /g, '<img style="display:block;" ').replace(/webp/g, 'jpg')

4)解决商品价格闪烁问题

导致问题的原因:在商品详情数据请求回来之前,data 中 goods_info 的值为 {},因此初次渲染页面时,会导致 商品价格、商品名称 等闪烁的问题。

解决方案:判断 goods_info.goods_name 属性的值是否存在,从而使用 v-if 指令控制页面的显示与隐藏

3.商品详情底部导航

使用内置组件:uni-gods-nav

(六)加入购物车

1.在vuex中存储购物车的相关数据,cart.js

  state: () => ({// 购物车的数组,用来存储购物车中每个商品的信息对象// 每个商品的信息对象,都包含如下 6 个属性:// { goods_id, goods_name, goods_price, goods_count, goods_small_logo, goods_state }cart: [],}),
  • 将商品加入购物车的实现思路关键:遍历cart数组,在其中先find( )即将加入购物车的商品,若存在,则该商品数量++;若不存在,则push( )入cart数组
  • goods_id:商品唯一id
  • goods_state:加入购物车的商品,默认为true(勾选状态)

2.在 getters 节点下定义一个 total ,用来统计购物车中商品的种类数量,同时通过 wtach 侦听器,监听 total 的变化,动态为 cart 徽标赋值

(七)购物车页面

1.<radio></radio>

1)为my-goods组件封装radio勾选状态,使用内置组件<radio></radio>,父组件传入值,v-if/v-else来调整显示与隐藏,同时 : checked="goods.goods_state" 绑定商品的勾选状态

2)为<radio></radio>绑定自定义事件@onClick,emit出去(goods_state),在父组件中处理业务逻辑

## 封装的自定义组件,一般不自己处理业务逻辑,emit出去,让父组件处理,封装的组件一般是公共组件

2.<uni-number-box></uni-number-box>

1)动态渲染商品数量的值

<!-- 商品数量 -->
<uni-number-box :min="1" :value="goods.goods_count"></uni-number-box>

2)props 属性,来控制当前组件中是否显示 NumberBox 组件

3)@change="numChange(value)",emit(goods_id,value)出去

  • 解决numberbox数据不合法问题

3.uni-swiper-action/uni-swiper-item

实现滑动删除商品效果:

1)配置 options

2)滑动事件:uni-swiper-item 绑定@click时间

3)删除商品:filter( ),筛选出不是要删除的商品

4.封装获取地址和展示地址的自定义组件my-address

1)点击按钮,获取地址,使用uni.chooseAddress( )

2)获取地址按钮、展示地址的页面的切换

5.封装结算区组件my-settle

1)全选勾选框

<label class="radio">// 为 radio 组件动态绑定 checked 属性的值<radio color="#C00000" :checked="isFullCheck" /><text>全选</text></label>

全选框的勾选状态:some( )、every( )。。。

2)全选影响每个复选框;每个复选框影响全选

3)购物车为空、购物车不为空的两个页面结构的切换

(八)登录

封装自定义组件my-login和my-userInfo

1.点击结算按钮进行条件判断

1)是否勾选了要结算的商品        2)是否填写了地址        3)是否已经登录

情况一:1、2不满足,3满足。则提醒用户勾选商品和填写地址

情况二:1、2满足,3不满足。则提醒用户登录,并在3秒后自动跳转至登录页

情况三:1、2、3均满足。则整理参数,发起微信支付

// 去结算
goCheck(){// 是否勾选了商品if(!this.checkedCount) return uni.$showMsg('请选择要结算的商品!')// 是否选择了地址if(!this.addr) return uni.$showMsg('请选择收货地址!')// 是否登录了(token)// if(!this.token) return uni.$showMsg('请先登录!')// 重定向if(!this.token) return this.delayNavigate()// 以上条件均符合,则进行支付this.payOrder()
},

2.my-login与my-userInfo的切换:是否有token

3.实现登录

按钮@click事件==>【getUserInfo】获取userInfo和请求参数 uni.getUserProfile( {desc:"login"} )

==>【getToken】获取code uni.login( ) ==>请求参数+code(整理参数queryObj)

==> 发请求获取token uni.$http.post(url,queryObj) ==> 得到token ==> 将token存储于vuex中

my-login与my-userInfo依据token的有无进行切换

4.重定向 & 微信支付

1)重定向

data() {return {second:3,timer:null};
},methods:
// 倒计时提示
showTip(second){uni.showToast({title:`请登录后再结算! ${second} 秒后自动跳转到登录页`,icon:'none',mask:true})
},
// 延时跳转到my页面进行登录
delayNavigate(){// 每次开始时,重置secondthis.second=3this.showTip(this.second)// 定时器this.timer=setInterval(()=>{this.second--if(this.second<=0){// 倒计时为零时,1)清除定时器 2)跳转至my页面 3)return后续代码不再进行clearInterval(this.timer)uni.switchTab({url:'/pages/my/my',success: () => {this.$store.commit('userInfo/updateRedirectInfo',{openType:'switchTab',from:'/pages/cart/cart'})}})// 终止后续代码的运行(当秒数为 0 时,不再展示 toast 提示消息)return}this.showTip(this.second)},1000)
}

2)实现微信支付

发请求:创建订单 ==> 得到订单编号 ==> 发请求:订单预支付==> 得到预支付对象(payInfo)

==>发起微信支付 uni.requestPayment( payInfo )(具体参考请求文档)

==>完成(提示用户)

async payOrder(){// 具体关键字段,参考请求文档// 1.创建订单(订单金额、收货地址、订单中包含的商品信息)--返回 订单编号// 1.1整理请求参数let orderInfo={// order_price:0.001,   // 开发时,可用此总价格order_price:this.checkedGoodsAmount,    // 订单总价格consignee_addr:this.addr,goods:this.cart.filter(item=>item.goods_state).map(item=>({goods_id:item.goods_id,goods_number:item.goods_count,goods_price:item.goods_price}))}// 1.2发请求let {data:res1}=await uni.$http.post('/api/public/v1/my/orders/create',orderInfo)if(res1.meta.status!=200) return uni.$showMsg('创建订单失败!')// 1.3得到订单编号let order_number=res1.message.order_number// 2.订单预支付(订单编号)--返回 订单预支付的参数对象// 2.1发请求let {data:res2}=await uni.$http.post('/api/public/v1/my/orders/req_unifiedorder',{order_number})if(res2.meta.status!=200) return uni.$showMsg('预付订单生成失败!')// 2.2得到订单预支付对象let payInfo=res2.message.pay// 3.发起微信支付(订单预支付对象)--监听 success fail complete回调函数// 3.1 调用 uni.requestPayment() 发起微信支付let [err,succ]=await uni.requestPayment(payInfo)   // 将payInfo传入// 3.2未完成支付if(err) return uni.$showMsg('订单未支付!')// 3.3完成了支付,进一步查询支付结果--查询订单支付状态let {data:res3}=await uni.$http.post('/api/public/v1/my/orders/chkOrder',{order_number})// 3.4检测到订单未支付if(res3.meta.status!=200) return uni.$showMsg('订单未支付!')// 3.5检测到订单支付完成uni.showToast({title:'支付完成!',icon:'success'})
},

(九)发布

1.发布为小程序

2.发布为 Android App

【记录】基于uni-app开发的微信小程序商城项目相关推荐

  1. jee-weapp是一套基于jfinal,dubbo微服务开发的微信小程序商城项目,首次开放全部拼团前后台源码

    介绍: jee-weapp 简介 jee-weapp基于微信第三方开放平台基础框架, 多模块化开发不同的微信营销插件, 支持微信第三方平台扫码授权公众号,小程序 支持微信第三方平台覆盖全网发布 支持小 ...

  2. node mysql商城开发_NideShop:基于Node.js+MySQL开发的微信小程序商城开源啦

    NideShop:基于Node.js+MySQL开发的微信小程序商城开源啦 发布时间:2020-04-14 04:23:37 来源:51CTO 阅读:2894 作者:ch10mmt 高仿网易严选的微信 ...

  3. 公众号商城开发和微信小程序商城开发有什么区别?

    小程序和公众号商城都属于微商城,但是有很多朋友也不知道这两者之间有什么区别.对于选择做公众号商城还是小程序商城时,出现了选择困难症.既然微信小程序商城和微信公众号商城都是微信内的产品aigao0607 ...

  4. 都2020年,开发制作微信小程序商城,需要准备什么资料?应该不会不知道吧!

    微信小程序使用越来越广泛,而还未入局的对于微信小程序开发需要什么材料甚至不清楚,其实这些材料很简单.总结就是微信支付.微信小程序注册.小程序代码,下面展开说说. 小程序红利 从腾讯刚发布的财报看,微信 ...

  5. 微信小程序商城项目实战(完结篇:意见反馈)

    微信小程序商城项目完结 意见反馈 代码实现 首先修改标题并且使用之前写好的tab组件 编写界面 编写样式 逻辑处理js 效果图 意见反馈 做假的意见反馈,主要练习一下微信小程序文件上传api以及样式界 ...

  6. 推荐一个微信小程序商城项目

    推荐一款实用的微信小程序商城项目,这个项目不仅有商城基本的功能,比如:商品管理.订单管理.用户管理,还有分销功能,具备广告.优惠券等功能. 技术选型 后端采用 Spring 技术栈,使用到的框架主要包 ...

  7. 一款开源的微信小程序商城项目,接外包直接拿去改改,就能用(附源码)。。。...

    大家好,今天,推荐一个小程序商城项目. 上次是谁要小程序商城项目啊,猿哥帮你找到了. 这是我目前见过的最好的小程序商城项目.功能完整,代码结构清晰.值得推荐. 后端部分虽然是PHP的,但是建议有研究精 ...

  8. 微信小程序商城搭建,微信小程序商城源码,微信小程序商城项目

    项目背景和意义 目的:本课题主要目标是设计并能够实现一个基于微信小程序商城系统,前台用户使用小程序,小程序使用微信开发者工具开发:后台管理使用基PP+MySql的B/S架构,开发工具使用phpstor ...

  9. 记录--uniapp 应用APP跳转微信小程序

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 最近APP项目开发完成,在评审会上老板提了一个需求,想在开发的APP上添加一个链接,可以跳转公司的小程序商城. 原以为会很复杂,结果只有短 ...

最新文章

  1. 解决:无法创建该DNS 服务器的委派
  2. python编写爬虫的步骤-零基础写python爬虫之爬虫编写全记录
  3. C++ const 学习
  4. 【控制】《多智能体系统一致性协同演化控制理论与技术》纪良浩老师-第9章-二阶连续时间时延多智能体系统加权一致性
  5. 【转】Ubuntu16.04安装 Matlab2018a详细教程
  6. Web高效管理多个项目的SVN仓库
  7. jeecg框架日常开发问题解决方法
  8. 扩散(洛谷-P1661)
  9. shell读取php 数组长度,shell数组的定义、数组长度
  10. 2.4 使用ARDUINO控制MC20进行GPS数据的获取和解析
  11. BZOJ3639 Query on a tree VII
  12. mysql实现递归查询的方法
  13. 汉诺塔问题解析(C语言)
  14. 如何选出好用的仓库库存管理系统软件?看文章就知道了
  15. PS三种切图方式,干货满满,不看绝对后悔
  16. C语言编写 小企鹅表情包
  17. 塑造棋牌游戏文化内涵
  18. Power BI业绩杜邦分析
  19. GetItemText
  20. Java——环境变量的配置

热门文章

  1. inherit和initial:两个特殊的css值
  2. Oracle 手工锁表
  3. 用一个小故事告诉你什么叫做大数据
  4. 安装android+手机usb+驱动程序,一加手机驱动怎么安装 一加手机USB驱动手动安装详细教程图解...
  5. c语言程序设计医院就医,C语言程序设计(医院信息管理系统)附源代码[精品].doc...
  6. C4D的GPU渲染器Octane和Redshift的渲染对比
  7. eclipse building workspace sleeping rapidly
  8. 推断速度达seq2seq模型的100倍,谷歌开源文本生成新方法LaserTagger
  9. 困扰老子好久啊!!tomcat的两个错…
  10. mysql删去root用户无法登录_MySQL误删root用户导致无法登陆解决方法