Skip to content
Permalink
Browse files

feat: support toc reward and view counter

  • Loading branch information
saltbo committed Mar 24, 2019
1 parent ed7bc46 commit 4fcb41a3fe391486cbe30fe670564e72b0da12e7
@@ -38,6 +38,16 @@ copyright = "© This post is licensed under a Creative Commons Attribution-NonCo
description = "A programer from feature."
paginate = 10

[[params.rewards]]
name = "微信"
url = "/images/reward/wechat.png"
[[params.rewards]]
name = "支付宝"
url = "/images/reward/alipay.png"
[[params.rewards]]
name = "EOS"
url = "/images/reward/eos.png"

# Choose your social networks
email = "saltbo@foxmail.com"
github = "saltbo"
@@ -2,16 +2,14 @@
title: "基于Docker搭建开发测试环境--网络·缓存"
date: 2017-07-15T22:59:11+08:00
tags: ["docker"]

---

Docker网络类型 docker有三种网络类型bridge、host、none,默认bridge。bridge的意思是容器拥有独立的网络环境通...

<!--more-->

### Docker网络类型

```
```bash
[www@BJ-TEST-SHZF ~]$ ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.0.1 netmask 255.255.240.0 broadcast 0.0.0.0
@@ -84,7 +82,7 @@ server{
这里的话主要就是修改下server_name和root即可,注意Dockerfile里提到了,我们是挂载到/data/web下,所以如图的路径就是/data/web/project-x
##### 部署Shell
```
```bash
#!/bin/bash
appname="store-dev"
@@ -129,7 +127,7 @@ docker run -v $logpath:/data/logs -v $apppath:/data/web/ -p 80:80 --name $name -
这里主要说下docker化后的项目如何部署。
##### deploy.sh
```
```bash
#!/bin/bash
port=""
@@ -164,7 +162,7 @@ fi
```
##### project-a.sh
```
```bash
#!/bin/bash
export env="testing"
@@ -247,7 +245,7 @@ server{
}
}
```
```
```bash
# 加入代理并重启
if [ $appport ] ; then
echo $appport
@@ -294,7 +292,7 @@ ENTRYPOINT ["docker/entrypoint.sh"]
CMD ["supervisord"]
```
```
```dockerfile
FROM registry-internal.cn-beijing.aliyuncs.com/xxxx/golang:1.7-govendor AS build-env
ENV ROOT_PATH /go/src/gitlab.xxxx.com/shzf/goscron
@@ -4,42 +4,36 @@ date: 2018-04-20T00:46:52+08:00
tags: ["Vue", "iView"]
---

作为一个正正经经的后端开发,虽然早年自称过全栈,但是随着前端技术发展的越来越快,技术栈越来越多,现在已经不敢自称全栈。早年搭建管理后台都是采用bootstrap,由后端渲染页面。但是有很多东西是后端渲染无法做到的。偶然发现一个组件库——[iView](https://www.ivie wui.com/),这是一个高质量的vue组件库,涵盖了你可以想象到的任何组件。但是因为之前没有vue基础,所以踩了很多坑,这里总结一下。
作为一个正正经经的后端开发,虽然早年自称过全栈,但是随着前端技术发展的越来越快,技术栈越来越多,现在已经不敢自称全栈。早年搭建管理后台都是采用bootstrap,由后端渲染页面。但是有很多东西是后端渲染无法做到的。偶然发现一个组件库——[iView](https://www.iviewui.com/),这是一个高质量的vue组件库,涵盖了你可以想象到的任何组件。但是因为之前没有vue基础,所以踩了很多坑,这里总结一下。
<!--more-->

>本文适用有前端基础但没有Vue基础的读者。

作为一个正正经经的后端开发,虽然早年自称过全栈,但是随着前端技术发展的越来越快,技术栈越来越多,现在已经不敢自称全栈。

早年搭建管理后台都是采用bootstrap,由后端渲染页面。但是有很多东西是后端渲染无法做到的。偶然发现一个组件库——[iView](https://www.iviewui.com/),这是一个高质量的vue组件库,涵盖了你可以想象到的任何组件。但是因为之前没有vue基础,所以踩了很多坑,这里总结一下。


#### 0x00如何跳转页面
# 0x00如何跳转页面
由这个问题就引出了vue-router。它是一个前端路由,也就是说,通过它进行的跳转操作是并没有经过后端的。

```
```js
<router-link to="/foo">Go to Foo</router-link>
```

```
```js
this.$router.push({ path: '/user', params: { userId: 123 }})
```
上面是两种页面跳转方式,其中push的方式最常见,这里为了方便理解使用了path,在实际应用中路由表会给每个路由分配一个name,在push的时候就可以直接push name进去了。

参考文档:https://router.vuejs.org/

#### 0x01如何获取参数
# 0x01如何获取参数
上面说了跳转,如果跳转的时候带了参数,那么如何获取到传递过来的参数呢?

```
```js
this.$route.params['id']
```
```
```js
this.$route.query.id
```

#### 0x02如何变更数据
# 0x02如何变更数据
这里就要了解双向绑定这个东西了。何为双向绑定?

其实简单来说就是在vue中也会有model和view的概念。双向绑定就是针对他们来说,当我们用JavaScript代码更新Model时,View就会自动更新。当用户变更了View,Model的数据也自动被更新了,这种情况就是双向绑定。
@@ -49,9 +43,9 @@ this.$route.query.id
同样,在表格中,如果你要删除一行表格需要如何操作呢?在没有双向绑定之前你需要分别去删除dom结构中的dom和数据中相应的行数据。而现在,你只需要删除掉数据中的行数据,dom结构压根不需要你关心。当然这个只是例子,实际应用中一般都是重新调用接口刷新全部数据,表格dom也会全部重新刷新。


#### 0x03如何在表格中渲染自定义内容
# 0x03如何在表格中渲染自定义内容
在一个表格中我们经常需要渲染一些复杂的内容,这里就需要用到reader函数。
```
```js
{
columns: [
{
@@ -89,10 +83,10 @@ this.$route.query.id

还有需要注意的是:h函数是可以互相嵌套的,就是通过这种嵌套组合不同的dom结构。当然这种方式其实并不友好,还有更方便的方式是jsx,通过jsx你可以直接在render函数里返回一个dom,这里就不展开讲了。

#### 0x04如何格式化日期
# 0x04如何格式化日期
实际开发中后端接口有时候会返回UTC时间,那么如何优雅的对其进行格式化呢。答案是moment。`npm install moment` 然后在main.js里添加如下代码即可

```
```js
Vue.prototype.$moment = moment;
Vue.filter('moment', function(value, formatString) {
formatString = formatString || 'YYYY-MM-DD HH:mm:ss';
@@ -110,15 +104,15 @@ if (!String.prototype.moment) {
在使用的时候,如果是在dom结构中,用法是`{{ data.time | moment }}`
如果是在js中,用法是`params.row.create_time.moment()`

#### 0x05如何提交数据
# 0x05如何提交数据

原先vue官方推荐的网络库是vue-resource,现在已经改成axios了。一样`npm install axios`,然后再main.js中加入如下代码

```
```js
Vue.prototype.$http = axios;
```
这样,你就可以在任意vue文件中通过下面这种方式使用了
```
```js
this.$http.get('/api/stacks/').then((response) => {
console.log(response.data)
})
@@ -134,17 +128,17 @@ this.$http.post('/api/stacks/').then((response) => {

 参考文档:https://github.com/axios/axios

#### 0x06箭头函数
# 0x06箭头函数
通过上面的几段代码不知道你有没有发现一个东西
```
```js
render: (h, params) => {
},
click: () => {
this.show(params.index)
}
```
这个其实也是一种函数的形式,一般情况下你可能更习惯用传统的function,但是你没有想过为什么很多示例中都用箭头函数?
```
```js
<script>
export default {
data () {
@@ -164,7 +158,7 @@ click: () => {
</script>
```
就像上面的代码,如果不用箭头函数会怎样?
```
```js
<script>
export default {
data () {
@@ -185,10 +179,10 @@ click: () => {
```
如果你运行上面这段代码你就会发现报错了。在传统的function中this是访问不到data中return的数据的。

#### 0x07如何组件化
# 0x07如何组件化
组件化有两个好处,一是代码复用,二是解耦。
最常见的需求是把模态框组件化,这样就可以避免模态框的代码耦合在页面的代码中。
```
```js
<script>
export default {
props: {
@@ -217,29 +211,29 @@ click: () => {
</script>
```
组件的代码其实跟普通页面的代码差别不大。就是多了一个props,里面包含了这个组件的属性。比如这里定义了一个title,那么在使用的时候你就可以传一个title进来。
```
```js
<ModalCreation ref="modalCreation" @on-success="refreshList" title="创建服务"></ModalCreation>
```
可以看到,这个组件还提供了一个on-success的事件,那么这是怎么做到的呢?

其实也很简单,只需要在组件内执行`this.$emit('on-success', body.data.id);`即可发送一个事件出来。

那么如何优雅的调起组件呢?
```
```js
$refs.modalCreation.open()
```


#### 0x08Vue到底是什么
# 0x08Vue到底是什么

官方的介绍是:**它是一套用于构建用户界面的渐进式框架。** 但是对于初学者来说还是云里雾里。这里的重点其实是构建,简单来说就是你按照vue的方式写html、css和js,然后它会帮你编译成浏览器可以运行的js文件。从本质上说,前端技术还是html、css和js这三大件,早期前端开发是直接写原生js代码,现在是用vue或者react的方式。其实跟后端常见的MVC结构类似,早期PHP也是直接写原生PHP,每个php文件里各种include、require,后来才有的各种框架,像Yaf、TP等。

#### 0x09如何部署
# 0x09如何部署

这个问题的答案其实有很多种。它是由你的系统架构决定的。但是在将如何部署之前需要先讲一个概念——SPA(单页面应用)。

SPA即一个html,全站只有一个html,内容如下
```
```html
<!DOCTYPE html>
<html lang="zh-CN">

@@ -268,7 +262,7 @@ Vue编译出来的文件其实初始的html就只有上面这一点。也就是

这里有一个坑是前后端路由问题。前端路由实际上有三种模式,具体解释如下:

```
```js
### mode
* 类型: `string`
@@ -293,7 +287,7 @@ hash模式实际上是采用锚的方式,也就是你见过的一些后台网
但是,如果你想去掉#号呢,那就需要使用history模式,这种模式就要求服务端所有的路由全部输出那个html。
#### 0x0A开发环境下如何访问静态文件
# 0x0A开发环境下如何访问静态文件
如果你是采用后端渲染的方式,那么为了统一流程,在开发环境下也是需要由后端代理前端路由。那么问题就来了,线上环境时`npm run build`打包出来的静态文件,直接挂载静态文件所在目录就行了。那在开发环境还没有打包,如何访问到正在开发的静态文件呢?这里就有一个webpack-dev-server的坑。
@@ -303,7 +297,7 @@ hash模式实际上是采用锚的方式,也就是你见过的一些后台网
![image.png](https://upload-images.jianshu.io/upload_images/1846751-0dae150bcaefce6b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
找到这些静态文件就好办了,既然没有生成文件,那我们只能在后端服务中代理这些静态文件
```
```go
func main() {
app := neo.App()
app.Conf.Parse("conf/local.toml")
@@ -334,8 +328,8 @@ func main() {
}
```
#### 0x0B结语
# 0x0B结语
前端的技术栈实在是太零散了,几乎每走一步都是坑。越来越佩服前端大牛们了~
######***我是闫大伯,一直在踩坑,踩完后端踩前端***
###***我是闫大伯,一直在踩坑,踩完后端踩前端***
@@ -1,3 +1,6 @@
var html=document.querySelector('html');var body=document.querySelector('body');var menuToggle=document.querySelector('.menu-toggle');var menuIcon=document.querySelector('.icon-menu');var siteMenu=document.querySelector('.site-menu');var socialMenu=document.querySelector('.social-menu');var toTopBtn=document.querySelector('.to-top');menuToggle&&menuToggle.addEventListener('click',function(){siteMenu.classList.toggle('collapsed');socialMenu.classList.toggle('collapsed');menuIcon.classList.toggle('icon-menu');menuIcon.classList.toggle('icon-close');var expandStatus=menuToggle.getAttribute('aria-expanded');if(expandStatus==='false')menuToggle.setAttribute('aria-expanded','true');else menuToggle.setAttribute('aria-expanded','false');});var zoomables=document.querySelectorAll('.zoomable > img, img.zoomable');zoomables.length&&mediumZoom(zoomables);function randomErrorEmoji(){var error=document.getElementsByClassName('error-emoji')[0];var emojiArray=['\\(o_o)/','(o^^)o','(˚Δ˚)b','(^-^*)','(≥o≤)','(^_^)b','(·_·)',"(='X'=)",'(>_<)','(;-;)','\\(^Д^)/',];if(error){var errorEmoji=emojiArray[Math.floor(Math.random()*emojiArray.length)];error.appendChild(document.createTextNode(errorEmoji));}};randomErrorEmoji();var lastPosition=0;var ticking=false;window.addEventListener('scroll',function(){lastPosition=body.scrollTop===0?html.scrollTop:body.scrollTop;if(!ticking){window.requestAnimationFrame(function(){if(lastPosition>=600){toTopBtn.classList.remove('is-hide');}else{toTopBtn.classList.add('is-hide');}
var html=document.querySelector('html');var body=document.querySelector('body');var menuToggle=document.querySelector('.menu-toggle');var menuIcon=document.querySelector('.icon-menu');var siteMenu=document.querySelector('.site-menu');var socialMenu=document.querySelector('.social-menu');var toTopBtn=document.querySelector('.to-top');var tocMenu=document.querySelector('#TableOfContents');var collapseBtn=document.querySelector('.toc-btn');var rewardBtn=document.querySelector(".reward-btn");var rewardWay=document.querySelector(".reward-ways");rewardBtn&&rewardBtn.addEventListener('click',function(){rewardWay.classList.toggle('reward-ways-collapsed');})
collapseBtn&&collapseBtn.addEventListener('click',function(){var collapse=tocMenu.classList.contains('toc-menu-collapsed');collapseBtn.innerHTML=!collapse?'显示目录':'隐藏目录'
tocMenu.classList.toggle('toc-menu-collapsed');})
menuToggle&&menuToggle.addEventListener('click',function(){siteMenu.classList.toggle('collapsed');socialMenu.classList.toggle('collapsed');menuIcon.classList.toggle('icon-menu');menuIcon.classList.toggle('icon-close');var expandStatus=menuToggle.getAttribute('aria-expanded');if(expandStatus==='false')menuToggle.setAttribute('aria-expanded','true');else menuToggle.setAttribute('aria-expanded','false');});var zoomables=document.querySelectorAll('.zoomable > img, img.zoomable');zoomables.length&&mediumZoom(zoomables);function randomErrorEmoji(){var error=document.getElementsByClassName('error-emoji')[0];var emojiArray=['\\(o_o)/','(o^^)o','(˚Δ˚)b','(^-^*)','(≥o≤)','(^_^)b','(·_·)',"(='X'=)",'(>_<)','(;-;)','\\(^Д^)/',];if(error){var errorEmoji=emojiArray[Math.floor(Math.random()*emojiArray.length)];error.appendChild(document.createTextNode(errorEmoji));}};randomErrorEmoji();var lastPosition=0;var ticking=false;window.addEventListener('scroll',function(){lastPosition=body.scrollTop===0?html.scrollTop:body.scrollTop;if(!ticking){window.requestAnimationFrame(function(){if(lastPosition>=600){toTopBtn.classList.remove('is-hide');}else{toTopBtn.classList.add('is-hide');}
ticking=false;});}
ticking=true;});var scroll=new SmoothScroll('a[href*="#"]');toTopBtn&&toTopBtn.addEventListener('click',function(){scroll.animateScroll(0);});

Large diffs are not rendered by default.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -7,6 +7,23 @@ var siteMenu = document.querySelector('.site-menu');
var socialMenu = document.querySelector('.social-menu');
var toTopBtn = document.querySelector('.to-top');


var tocMenu = document.querySelector('#TableOfContents');
var collapseBtn = document.querySelector('.toc-btn');

var rewardBtn = document.querySelector(".reward-btn");
var rewardWay = document.querySelector(".reward-ways");

rewardBtn && rewardBtn.addEventListener('click', function() {
rewardWay.classList.toggle('reward-ways-collapsed');
})

collapseBtn && collapseBtn.addEventListener('click', function() {
var collapse = tocMenu.classList.contains('toc-menu-collapsed');
collapseBtn.innerHTML = !collapse ? '显示目录' : '隐藏目录'
tocMenu.classList.toggle('toc-menu-collapsed');
})

// Site and social menu toggle
menuToggle &&
menuToggle.addEventListener('click', function() {
@@ -1,6 +1,7 @@
@import 'partials/reset';
@import 'partials/variables';
@import 'partials/icons';
@import 'partials/scrollbar';
@import 'partials/skeleton';
@import 'partials/header';
@import 'partials/summary';
@@ -8,7 +8,7 @@
transition: all $easing $speed;

&:hover {
transform: rotate(180deg);
transform: rotate(360deg);
}

@media screen and (max-width: $tablet) {
@@ -87,6 +87,51 @@
}
}

.toc {
position: relative;
top: -16rem;
& .toc-btn {
position: absolute;
right: 1.5rem;
border: 1px solid #dbdada;
border-radius: 5%;
font-size: 14px;
width: 4rem;
font-weight: bold;
color: #000000;
padding: 0.1rem;
}

& .toc-btn:hover {
background: red;
color: #ffffff;
font-weight: bold;
}
& #TableOfContents {
width: 15rem;
height: 20rem;
margin: 0 auto;
border-radius: 2%;
background: #dbdada;
position: relative;
top: 2rem;
transition: height 0.3s;
overflow-y: scroll;
}
& .toc-menu-collapsed {
height: 0 !important;
}
& ul {
padding: 0;
width: 10rem;
margin: 1rem auto;
list-style: none;
text-align: left;
line-height: 2;
word-break: break-all;
}
}

.social-menu {
position: absolute;
left: 1rem;

0 comments on commit 4fcb41a

Please sign in to comment.
You can’t perform that action at this time.