Vue商城项目的前提工作

用脚手架3创建项目

  • vue create 项目名称

在GitHub上建一个仓库

将项目与github联系起来

  • git init
  • git add .
  • git commit -m ‘项目名称’
  • git remote add origin github地址
  • git push -u origin master

更新文件到github

  • git add 文件名称或者 git add .

  • git commit -m “这是注释内容”

  • 这一步从本地仓库或本地分支获取并集成(整合),输入指令:git pull origin master

  • 如果过程中出现‘please enter a commit message…’,首先按下esc退出键然后输入 :wq即可

  • 输入指令:git push -u origin master

划分目录结构

  • src

    • assets 放一些资源

      • css
      • img
    • components 放一些公共的组件
      • common 当前项目里面可以使用的组件 在下一个项目里面也可以使用的组件
      • content 与业务相关的组件 只针对于当前项目来说是公共的
    • views 对应视图的一些逻辑
    • router 路由相关的东西
    • store 公共状态的管理 vuex
    • network 网络相关的
    • common 公共的js文件
      • const.js 公共常量
      • utils.js 工具函数
      • mixin.js 一些混入

引入css文件

一般开发的是一个前端项目的话,会对项目里面很多css进行初始化

  • normalize.css 对浏览器上的很多标签进行统一 在github上搜索 文件链接
  • base.css 这是属于自己的css

配置别名

在vue.config.js中配置别名

首页功能的实现

项目模块划分

在components/common封装tabbar
在components/content封装mainTabbar

  1. npm install vue-router --save
  2. 在router的index.js中配置路由映射关系
    对组件进行懒加载
  3. 在main.js中挂载

请求首页的多个数据

  1. npm install axios --save 安装框架
  2. 在network文件夹下新建request.js
  3. import axios from 'axios' 导入
    注意:这里写的是export而不是export default,为什么?
    因为export default只能暴露一个对象,而export 可以暴露多个对象,以后需要用到多个的话就可以
  4. 在network文件夹下新建home.js获取首页所需数据的api
  5. 在Home组件中面向home.js进行开发,首页创建好之后就发送网络请求在create中
  6. 在data中保存数据

网络模块的封装

network->request.js
第一层是工具函数层,封装一个通用的axios,创建一个实例,包括请求的基本路径,请求拦截器,响应拦截器。

export function request(config) {// 创建axios实例const instance = axios.create({// 默认是get请求// 支持跨域 jsonp 在url后面写上callback// 这个接口不支持postbaseURL: "http://123.207.32.32:8000",timeout: 5000,})// 请求的拦截器instance.interceptors.request.use(config => {// 比如config中的一些信息不符合服务器的请求// 比如每次发送网络请求时,都希望界面中显示一个请求的图标// 某些网络请求(比如登录),需要携带一些信息return config}, err => {console.log(err);})// 响应的拦截器instance.interceptors.response.use(res => {return res}, err => {console.log(err);})//发送真正的网络请求return instance(config)
}

首页面向request发送网络请求
network->home.js
第二层封装,接口层,对首页所有数据的请求都在home.js中,统一管理。

export function getHomeMultidata(){return request({url:'/home/multidata'})
}

第三层,调用层,Home.vue中,首页创建完就进行网络请求

getHomeMultidata(){getHomeMultidata().then(res=>{//console.log(res);// result在组件中,会一直存在,保存在data中//this.result=res;this.banners=res.data.data.banner.list;// 轮播图this.recommends=res.data.data.recommend.list; // 推荐信息})},

导航栏的封装和使用

  1. 在common中封装NavBar,使用具名插槽
  2. 在Home中引入封装好的组件
    NavBar的封装
<template><div class="nav-bar"><div class="left"><slot name="left"></slot></div><div class="center"><slot name="center"></slot></div><div class="right"><slot name="right"></slot></div></div>
</template>

在Home.vue中的使用
固定在顶部,不跟随滚动条滚动

<nav-bar class="home-nav"><div slot="center">购物街</div>
</nav-bar>

轮播图的封装和使用

  1. 在componets/common下新建swiper文件下,封装Swiper和SwiperItem
  2. 在home/childComps下封装HomeSwiper组件,
  3. 在Home中引入封装好的组件
  4. 展示轮播图数据banners

推荐信息的展示

  1. 在home/childComps下封装HomeRecommendView组件
  2. 在Home中引入封装好的组件
  3. 展示推荐信息的数据recommend
<div class="recommend"><div v-for="(item,index) in recommends" :key="index" class="recommend-item"><a :href="item.link"><img :src="item.image" alt=""><div>{{item.title}}</div></a></div></div>

FeatureView的封装

  1. 独立组件封装。在home/childComps下封装FeatureView组件
  2. 放的是一张图片 div>a>img

TabControl选项卡的封装

  1. 在componets/content下封装TabControl,只是文字不一样的时候,就没必要弄插槽了
  2. props->titles div->根据titles v-for遍历 div->span{{title}}
  3. flex布局,均等分
  4. 选中谁,谁就变红色
    在data中弄一个变量currentIndex来记录当前谁被选中;
    动态绑定class属性,:class="{active:index == currentIndex}",默认第一个选中变红色;
  5. 点击谁的时候,谁就变,监听item的点击,绑定点击事件@click="itemClick(index)"
itemClick(index){this.currentIndex=index;}
  1. 吸顶效果,监听滚动,当滚动到一定位置的时候,将position设置成fixed,向下滚动的时候把fixed属性删除,就可以随着一起滚动了。position:sticky;必须设置top值,这个属性的作用是 在没有达到top值之前,position是sticky,达到之后改成fixed,但是很多浏览器不兼容这个属性。

商品列表数据的请求和展示

  1. 请求商品数据,既要展示流行数据,又要展示新款数据,还要展示精选数据,根据不同的点击,展示不同的数据
  2. 用变量保存数据,一次性把三个数据请求一下,在data中定义
    要先考虑设计什么数据结构,然后再去使用
    有自己对应的页码和数据,page用来记录当前加载到第几页了,list用来保存数据
goods:{'pop':{page:0,list:[]},'new':{page:0,list:[]},'sell':{page:0,list:[]},},
  1. 在network的home.js中获取商品所需数据的api,getHomeGoods
export function getHomeGoods(type,page) {return request({url: '/home/data',params:{type,page}})
}
  1. 在Home的create中请求商品数据
    默认情况下先加载第一页的数据,在以后的上拉加载更多的操作下再去请求更多的数据。
getHomeGoods(type){const page=this.goods[type].page + 1;getHomeGoods(type,page).then(res=>{//对象中的扩展运算符(...)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中this.goods[type].list.push(...res.data.data.list);this.goods[type].page += 1;})
},
  1. 在components/content下新建goods文件夹,在里面封装GoodsList.vue和GoodsListItem.vue,从某一个类型中取出商品的list传给GoodsList,然后遍历出小的item传给GoodsListItem,让GoodsListItem展示商品
  2. 在GoodsList.vue中,定义props:goods,商品一行显示两个,用flex布局,给子item设置固定的宽度
.goods{display: flex;flex-wrap: wrap;justify-content: space-around;
}
  1. 在GoodsListItem.vue中,定义props:goodsItem,父组件向子组件传数据,用props

TabControl点击切换商品

  1. 首先内部监听点击,将事件传到Home中去,之前点击的时候只是内部样式的改变,现在需要传递事件,子组件发生点击事件,将事件传给父组件,用自定义事件$emit,
methods: {itemClick(index){this.currentIndex=index;this.$emit('tabClick',index)}}

在父组件Home中监听事件,@tabClick="tabClick",根据监听决定goodslist显示商品的类型。

  1. 定义一个当前显示的商品类型,默认是pop,currentType:'pop',根据点击切换显示类型
<goods-list :goods="goods[currentType].list"/>tabClick(index){switch (index) {case 0:this.currentType='pop'break;case 1:this.currentType='new'break;case 2:this.currentType='sell'break;}
}
  1. :goods="goods[currentType].list"这一串太长了,弄一个计算属性computed,来展示商品
<goods-list :goods="showGoods"/>computed: {showGoods(){return this.goods[this.currentType].list}},

吸顶效果

  1. 必须知道滚动到多少时,开始有吸顶效果,获取到tabcontroloffsetTop,在data中保存tabOffsetTop:0,为了能够拿到,绑定一个属性ref="tabControl",拿到组件,组件没有offsetTop属性,而是要拿到组件对应的元素,所有的组件都有一个属性$el,用来获取组件中的元素mounted中DOM加载完毕,但是图片不一定加载完了,所以要等图片加载完了之后计算出一个最终的offsetTop
  2. 监听轮播图是否加载完成,只需要发出一次事件,弄一个变量记录状态,和之前的防抖的区别

在HomeSwiper.vue中

<img :src="item.image" @load="imageLoad">data(){return{isLoad:false; // 只需要发出一次事件}},imageLoad(){if(!this.isLoad){this.$emit('swiperImageLoad');this.isLoad=true;}}

在Home.vue中

<home-swiper :banners="banners" @swiperImageLoad="swiperImageLoad"/>swiperImageLoad(){this.tabOffsetTop=this.$refs.tabControl.$el.offsetTop;},
  1. 监听滚动,动态改变tabControl的样式,弄一个变量,isTabFixed:false,默认情况下不吸顶,当滚动到一定位置的时候,改变状态,动态绑定class
<tab-control :titles="['流行','新款','精选']" @tabClick="tabClick"ref="tabControl" :class="{fixed:isTabFixed}"/>contentScroll(position){//1.判断回到顶部是否显示this.isShowBackTop = (-position.y) > 1000//2.判断tabControl是否吸顶this.isTabFixed = (-position.y) > this.tabOffsetTop},.fixed{position: fixed;left: 0;right: 0;top: 44px;
}

问题:这种方法下面的商品内容会一下子往上移,虽然tabControl设置了fixed,但是也随着better-scroll一起滚出去了,因为tabControl会脱标。better-scroll滚动是根据translate属性移动的,设置了fixed还是能跟着一起滚动。
可以把tabControl再复制一份,来实现停留效果。


但是选项卡会被标题导航给盖住。
标题购物车可以不定位,这样就不会脱标,使用定位是在用浏览器原生滚动的时候。复制的tabControl放到navbar的下面,此时在轮播图的后面,再设置相对定位给一个层级关系,相对定位是因为还在原来的位置。默认它是不显示的,v-show="isTabFixed",当滚动到一定位置的时候再显示,当滚动没有达到一定位置时,隐藏。

swiperImageLoad(){this.tabOffsetTop=this.$refs.tabControl2.$el.offsetTop;},

问题:现在两个tabControl并没有保持一致。

tabClick(index){switch (index) {case 0:this.currentType='pop'break;case 1:this.currentType='new'break;case 2:this.currentType='sell'break;}this.$refs.tabControl1.currentIndex=index;this.$refs.tabControl2.currentIndex=index;},

我们并不能保证用户点击的是哪一个,所以两个都要赋值。

当把项目部署到服务器之后,用手机端去请求网页的时候,样式各方面没什么问题,但是滚动的时候,没有一个滚动的时候的滑动效果,滑动的时候也很卡顿,此时用的是原生的滚动,什么是原生的滚动呢?当里面的内容超过了当前的窗口的时候,自动就可以滚动了。但是用在移动端,会非常卡顿。以前用iScroll来适配移动端的滚动,但是这个框架现在作者不更新了。better-scroll在iscroll基础上,还加入了一些c3的属性。可以实现移动端的顺滑滚动,还在顶部和底部都增加了弹簧效果。

原生的滚动

.content{height:150px;overflow-y:scroll;
}

Better-Scroll的安装和使用

npm install better-scroll --save
在外层弄一个wrapper,wrapper需要固定的高度,在 wrapper里面放内容content,只能是一个标签组成的content,它是父元素的第一个子元素,滚动的部分是content元素。

  1. 使用
    import BScroll from 'better-scroll'
    new BScroll(el,options) el挂载一个要滚动的元素
    new BScroll(document.querySelector('.wrapper'))
    也可以直接传一个类,根据类型查找标签
    new BScroll('.wrapper',{})

  2. 实时监听当前滚动到什么位置了
    (默认情况下,BScroll不能实时监听滚动的位置)
    需要设置一个属性 probeType
    probeType值为0,1 不侦测实时的位置
    2 在手指滚动的过程中侦测,手指离开后的惯性滚动过程中不侦测
    3 只要是在滚动,都侦测

  3. 上拉加载更多 设置pullUpLoad为true,要调用finishPullUp方法才能实现下一次的上拉加载更多
    要监听什么时候滚动到最底部了

  4. 滚动区域包裹的元素需要监听点击 ,设置click属性是true,better-scroll会阻止浏览器的原生 click 事件(现在好像可以了)

BScroll的基本使用

on方法

scroll事件 滚动的实时坐标

bscroll.on("scroll",(position)=>{console.log(position);
})

pullingUp 上拉加载更多

bscroll.on("pullingUp",()=>{// 发送网络请求,请求更多页数据// 等数据请求完,并且将新的数据展示出来后bscroll.finishPullUp(); // 因为只能上拉加载一次,执行完这个函数之后,才能进行下一次上拉加载更多
})

封装better-scroll与使用

  1. 在components/common下创建一个scroll文件夹,在里面封装Scroll
  2. 需要一个插槽
  3. 引入better-scroll,
  4. DOM被挂载时,初始化BScroll,querySelector不能明确的指定拿到的是哪个元素,绑定ref属性。
    例如在Home.vue中也有class=“wrapper”,在App.vue中也有class=“wrapper”,不知道到底取的是哪个,querySelector获取的可能是第一个。

ref如果绑定在组件中,this.$refs.refname获取到的是一个组件对象 。一般绑定在子组件。
ref如果绑定在普通的元素中,获取到的是一个元素

  1. home的高度太高了,相当于所有内容的高度,给一个100的视口高度,在Home中给滚动的区域content一个固定的高度
#home{height: 100vh;position: relative;
}
.content{overflow: hidden;position: absolute;top:44px;bottom: 49px;left:0;right:0;
}

可滚动区域的问题

在决定有多少区域可以滚动时,根据scrollerHeight属性决定的,scrollerHeight属性是根据放在better-scroll的content中的子组件的高度,
但是在首页中,刚开始在计算scrollerHeight属性时,是没有将图片计算在内的,后来图片加载进来之后有了新的高度,但是scrollHeight属性并没有更新。

监听每一张图片是否加载完成,只要有一个图片加载完成了,执行一次refresh()。
如何监听图片是否加载完成?

原生js img.οnlοad=function() {}
vue @load=‘方法’
事件总线:和vuex很像,不是管理状态的,而是管理事件的。因为涉及到非父子组件通信。

在GoodsListItem中监听图片是否加载完成,

<img :src="showImage" alt="" @load="imageLoad"">
imageLoad(){this.$bus.$emit('itemImageLoad')},

在main.js中

Vue.prototype.$bus=new Vue()

在Scroll中

refresh(){this.scroll && this.scroll.refresh && this.scroll.refresh()},

在Home.vue的mounted中接收事件总线,refresh会执行很多次

this.$bus.$on('itemImageLoad',()=>{this.$refs.scroll.refresh()})

刷新频繁防抖处理
debounce

如果直接执行refresh,会执行很多次,可以将refresh函数传到debounce函数中,生成一个新的函数,之后在调用非常频繁的时候,就用新生成的函数,而新生成的函数,并不会非常频繁的调用,如果下一次执行来的非常快,那么会将上一次取消掉。
在common/utils.js中封装防抖函数,

export function debounce(func, delay){let timer = null// ...可以传几个参数return function (...args) {if (timer) clearTimeout(timer)timer = setTimeout(() => {func.apply(this, args)}, delay);}
}

回到顶部

按钮的封装和使用

  1. 在components/content下创建一个backTop文件夹,在里面封装BackTop
  2. 在BackTop里面放一个图片,定位在右下角
  3. 在Home中引入,不需要放在滚动区域scroll中
  4. 在BackTop中监听回到顶部不太好,回到顶部需要拿到滚动区域scroll对象,所以监听回到顶部的点击事件放到Home中比较好
  5. 监听组件的点击事件,要调用.native修饰符(监听一个组件的原生事件时);也可以在BackTop.vue内部监听点击,用$emit传给父组件Home.vue。像button,div是可以直接监听点击的。组件不能直接监听点击。
<back-top @click.native="backTopClick"></back-top>
  1. 在Scroll中封装scrollTo()方法
scrollTo(x,y,time=300){this.scroll && this.scroll.scrollTo(x,y,time)},
  1. <scroll>绑定ref,拿到滚动的对象
backTopClick(){this.$refs.scroll.scrollTo(0,0,500)},

按钮的显示和隐藏

滚动到一定区域的时候才显示,回到的时候隐藏

  1. 在Scroll中监听滚动的位置,在props中定义probeType
props:{probeType:{type:Number,default:0,},
  1. 在Home中要监听scroll的实时滚动,不加冒号会把probe-type当成字符串
    <scroll class="content"ref="scroll":probe-type="3">
  1. 在Scroll中要根据在不同地方的应用的时候,有没有传入probeType的值,决定别人要不要实时监听,在父组件中监听子组件传过来的自定义事件@scroll="contentScroll"
if(this.probeType===2 || this.probeType === 3){this.scroll.on('scroll',(position)=>{this.$emit('scroll',position)})}
<scroll class="content"ref="scroll":probe-type="3"@scroll="contentScroll">

5.在Home中根据滚动的位置决定是否显示还是隐藏,用v-show ,默认一进去的时候是不显示的,isShowBackTop:false,

<back-top @click.native="backTopClick" v-show="isShowBackTop"></back-top>contentScroll(position){//1.判断回到顶部是否显示this.isShowBackTop = (-position.y) > 1000},

完成上拉加载更多

  1. 监听什么时候滚动到底部。在Scroll中,定义pullUpLoad属性,
props:{pullUpLoad:{type:Boolean,default:false}},

在Home.vue中

    <scroll class="content"ref="scroll":probe-type="3"@scroll="contentScroll":pull-up-load="true">

在Scroll中,向父组件传递事件,pullingUp在一次上拉加载的动作后,这个时机一般用来去后端请求数据。

if(this.pullUpLoad){this.scroll.on('pullingUp',()=>{this.$emit('pullingUp')})}
  1. 在Home的<scroll>中定义属性 @pullingUp="loadMore",加载更多的时候是针对商品类型来加载的,选中谁就给谁上拉加载更多
<scroll class="content"ref="scroll":probe-type="3"@scroll="contentScroll":pull-up-load="true"@pullingUp="loadMore">loadMore(){//只能上拉加载一次this.getHomeGoods(this.currentType)},

但是此时只能上拉加载一次,在数据加载完成之后,调用finishPullUp可以实现多次

getHomeGoods(type){const page=this.goods[type].page + 1;getHomeGoods(type,page).then(res=>{this.goods[type].list.push(...res.data.data.list)this.goods[type].page += 1//可以多次上拉加载this.$refs.scroll.finishPullUp()})},

Home离开时记录状态和位置

当滚动一半的时候,切换去了其他页面,再回到首页的时候,并没有保持在原来的位置,而是回到了顶部。

让Home不要随意销毁掉

使用keep-alive

<keep-alive><router-view/>
</keep-alive>

让Home保持原来的位置

离开时,保存一个位置信息saveY
进来时,将位置设置为原来保存的位置信息saveY即可
进来的时候可能刷新一下,不然可能会回到顶部
在Scroll.vue中

getCurrentY(){return this.scroll ? this.scroll.y : 0}

在Home.vue中

 // 进来的时候设置位置
activated() {this.$refs.scroll.scrollTo(0,this.saveY,0)this.$refs.scroll.refresh();// 不然可能出现一些问题},// 离开的时候记录位置
deactivated() {this.saveY=this.$refs.scroll.getCurrentY()},

点击首页中的商品跳转到商品详情页

点击商品进去详情页,根据点击请求更加详细的信息,要传过来goodsItem的iid,根据id去服务器请求更加详细的信息;配置路由映射关系,点击进行跳转,带参数传递跳转。
在GoodsListItem中

itemClick(){this.$router.push('/detail/'+this.goodsItem.iid)/* this.$router.push({path:'/detail',query:{iid:this.goodsItem.iid}}) */}

但是获取到的iid在更换点击商品时没有改变,并没有发生新的请求,因为发生了路由跳转,router-view由keep-alive包着,不会每次销毁并重新创建,所以不会给iid给新的值,详情页不要使用keep-alive,使用exclude属性

<keep-alive exclude="Detail"><router-view></router-view>
</keep-alive>

Vue商城——首页功能相关推荐

  1. 【第九篇】商城系统-商城首页功能

    一.商品上架功能 ElasticSearch实现商城系统中全文检索的流程. 1.商品ES模型 商品的映射关系 PUT product {"mappings": {"pro ...

  2. 基于vue2.0打造移动商城页面实践 vue实现商城购物车功能 基于Vue、Vuex、Vue-router实现的购物商城(原生切换动画)效果...

    基于vue2.0打造移动商城页面实践 地址:https://www.jianshu.com/p/2129bc4d40e9 vue实现商城购物车功能 地址:http://www.jb51.net/art ...

  3. 淘淘商城第51讲——从商城首页跳转到搜索页面

    通过上文的学习,我们已经学会了如何把商品数据导入到索引库中,本文我将会教大家如何从淘淘商城首页跳转到搜索页面. 我们要访问淘淘商城首页就得先启动Redis服务,大家根据自己使用的情况来启动,使用的是单 ...

  4. 大型多商户商城系统-功能表

    下载  http://souhuai.oss-cn-hangzhou.aliyuncs.com/php/php_mall_232M.zip Mall商城篇 前台 页面 说明 商城首页 包括PC,H5( ...

  5. 简易的网上购物商城首页设计流程

    这里写目录标题 前言 1 整体构造思想 2 设计前的摸索 3 网页顶端和导航栏的设计 4 nav导航栏的固定效果 5 轮播图部分 6 明星机型设计 7 精选配件设计 8 搜索欧珀区域 9 服务和售后区 ...

  6. 【40-系统性能压力测试基本概念-相关性能指标HPSTPSQPSRT-安装Jmeter教程-JMeter测试流程-线程组-取样器-监视器-测试商城首页-JMeter Address 占用的问题】

    一.知识回顾 [0.三高商城系统的专题专栏都帮你整理好了,请点击这里!] [1-系统架构演进过程] [2-微服务系统架构需求] [3-高性能.高并发.高可用的三高商城系统项目介绍] [4-Linux云 ...

  7. 加速度jsudo:立创电子元器件商城网站功能测评

    对于从事元器件的销售来说,最终的职业规划,都是希望能有个自己的公司.但是对于没有资金,人脉不广,又没有产品的人来说,要是搁在10年前,这实在是太难了.但是,这是21世纪,一切皆有可能.如果你会一点网络 ...

  8. 加速度jsudo:电子元器件商城网站功能测评——华强电子

    华强电子成立于2003年,计划创业板上市,主要是为为客户提供现货采购.海外代购.BOM配单及PCB制板服务. 对于从事元器件的销售来说,最终的职业规划,都是希望能有个自己的公司.但是对于没有资金,人脉 ...

  9. 前端vue实现分页功能

    前端Vue实现分页功能 我们都知道在spring boot项目中安装pagehelper可以实现分页功能,但是在vue中也能在前端实现分页. 1. 首先,在data中定义以下变量: data() {r ...

最新文章

  1. PHP函数库之BC高精确度函数库
  2. 2018/Province_Java_C/2/猴子分香蕉
  3. es 同义词 热更新 1.1版本
  4. Unity Android解决信息流广告关闭报错
  5. 操作系统复习题+最终版
  6. QT5开发及实例学习之十七Qt5双缓冲机制
  7. 09-Elasticsearch重要的系统配置
  8. 最新 UI 色彩渐变素材模板|设计师好帮手
  9. 建立高可用性的数据库群集
  10. Unicode编码详解
  11. 可变临时邮箱,亲测可用,附使用教程
  12. 苹果应用商店审核_苹果应用商店AppStore审核规则指南
  13. ubuntu防火墙安装arm架构说明
  14. 一元高次方程c语言实现,c语言实现一元二次方程求解
  15. C语言怎样提取一个数的十位个位百位千位
  16. java月份下拉菜单_实现一个日期下拉菜单
  17. JS逆向hook通用脚本合集
  18. python安装hyperlpr
  19. 理想评价鸿蒙系统,鸿蒙系统来了!前期如何发育?后期的潜力有多大?苹果真豁口了!...
  20. elk之拼音插件可选参数

热门文章

  1. w10桌面计算机图标箭头去除,Win10怎么去除桌面快捷方式图标左下角的小箭头
  2. Word无法打开该文件,因为文件格式与扩展名不匹配
  3. python辅助u盘数据恢复
  4. 读书笔记:杨家成的英语学习之路(附带作者人生感悟)
  5. PerformanceManagementSystem
  6. 25.JavaScript的Symbol类型、隐藏属性、全局注册表
  7. Intel(Altera)FPGA的SOF转JIC文件和下载详细教程
  8. 积水成渊之python——os.path.join()
  9. prometheus+alertmanager 企业微信告警
  10. C/C++ 下标运算符subscript、后缀表达式、正负下标