最近博客的访问量越来越大,导致使用阿里云的限制流量的云服务器超出了流量备关停,分析了以后大部分是一些下载的资源和图片资源占用的流量比较大。所以希望能把这些资源缓存起来,刚好最近经常用七牛云,发现有类似的功能。所以自己做了一下顺便记录一下步骤(网上大部分教程已经比较老,不太好与现在七牛云的对应了)

继续阅读

macOS 启动项大家众所周知的是 系统偏好设置->用户与群组->登录项 里面的设置,但有时候我通过这里无法找到系统自动启动的应用程序,比如 Microsoft Office AutoUpdate 组件,它会在系统启动时自动加载,但登录项里面却看不见。所以网络上搜索一下,摘录了部分重要的内容,原文在此:
https://www.jianshu.com/p/49dabd8ec9bb

继续阅读

本文介绍了 LNMP 环境搭建的 wecenter 如何开启伪静态的方法,从后台开启到配置 nginx 的配置文件,本文都有详细介绍。

开启后台伪静态功能

登录到后台开启伪静态功能,在全局设置-站点功能中。如果你之前开启过伪静态功能,但是没有配置伪静态规则,那么此时可能无法访问后台,显示 404。那么你可以直接跳过这一步,因为你已经开启了伪静态功能,直接去修改一下 nginx 的配置文件就可以了。

修改 nginx 的配置文件

LNMP 环境为我们自动创建好了站点的配置文件,我是通过 lnmp vhost add 脚本来添加的站点,生成的配置文件在 /usr/local/nginx/conf/vhost/站点名称.conf,如果你在使用 lnmp vhost add 命令创建站点时就已经启用了伪静态规则,那么 lnmp 会让你指定一个伪静态的规则文件。如这里所示:https://lnmp.org/faq/lnmp-vhost-add-howto.html,我创建站点的时候选择的是 other 这个规则。你也可以通过查看 /usr/local/nginx/conf/vhost/站点名称.conf 中的配置判断当前使用了哪个规则,如下图:

我们使用的是 other 规则,但实际这个规则什么内容都没有,规则的文件在 /usr/local/nginx/conf 目录。用 vim 打开 /usr/local/nginx/conf/other.conf 文件,写入如下内容然后保存:

location / {
        if (!-e $request_filename)
        {
                rewrite (.*) /index.php;
        }
}

保存成功后,我们就成功配置完成 nginx 的伪静态规则了。此时执行命令 /etc/init.d/nginx restart 来重启 nginx 让规则生效。

如果你在使用 lnmp 创建站点的时候没有选择开启伪静态,那么你可以根据这篇文章手动进行添加:https://lnmp.org/faq/lnmp-vhost-add-howto.html(建议学习一下 vim 的基本用法,让自己可以更自由的在 linux 中翻滚)

锚点是通过在界面中增加一些特征(比如 id),然后在 URL 地址后面加上 #id 就可以访问到指定页面的指定位置,这样可以让我们快速跳转到页面的某个位置,但是在 react-router 中这种方法遇到了问题,因为 react-router 会把 # 当做是 hash 来处理。导致即使跳转到指定页面后,# 后面的锚点也不生效。针对这个问题,在 react-router 的一个 issue 中大家也展开了激烈的讨论。以下是我看过以后整理的几种解决办法。

继续阅读

本文阐述了如何在一个使用了 react-router 的 react 项目中合理的使用 antd-mobile tabbar 功能。在 antd-mobile 官方的例子中可以看到,只需要将不同的组件放置到每个 TabBar.Item 里面就可以了,这样就可以实现简单的切换效果,但是存在几个问题。

一个是切换过程中,路由是不会跟着切换的。比如我们想分享一个地址,当其他人打开这个地址时自动就跳转到第二个 tab 上。如果按上面的方法做是无法实现的。

另外一个问题是这样的设计不太符合大型项目的框架设计,我们往往会制作一些 layouts,给不同的组件匹配不同的 layout。如果按上面介绍的方法做,也是不好实现的。

综合以上两点问题,再加上 Google 了一些资料后,写下本文,以帮助更多遇到类似问题的人。

解决方案

首先定义四个路由分别指定不同的 component,要注意的是这四个路由都统一使用一个 layout,这也就解决了一些大型项目中分多种 layout 的问题。如下代码所示:

<Router history={browserHistory}>
  {/* MainLayout 中包含了 antd-mobile tabbar */}
  <Route path='/' component={MainLayout}>
    {/* 默认跳转到 questions 页面 */}
    <IndexRedirect to='/questions' />
    <Route path='/questions' component={Questions} />
    <Route path='/activities' component={Activities} />
    <Route path='/videos' component={Videos} />
    <Route path='/mine' component={Mine} />
  </Route>
</Router>

随后我们看一下 mainLayout 的代码:

const MainLayout = ({children}) => {
  const pathname = children.props.location.pathname

  return (
    <TabBar
      unselectedTintColor='#949494'
      tintColor='#33A3F4'
      barTintColor='white'
    >
      <TabBar.Item
        title='问答'
        key='questions'
        icon={<div className='questions-icon' />}
        selectedIcon={<div className='questions-selected-icon' />}
        selected={pathname === '/questions'}
        onPress={() => {
          browserHistory.push('/questions')
        }}
      >
        { pathname === '/questions' ? children : null }
      </TabBar.Item>
      <TabBar.Item
        title='活动'
        key='activities'
        icon={<div className='activities-icon' />}
        selectedIcon={<div className='activities-selected-icon' />}
        selected={pathname === '/activities'}
        onPress={() => {
          browserHistory.push('/activities')
        }}
      >
        { pathname === '/activities' ? children : null }
      </TabBar.Item>
      <TabBar.Item
        title='视频'
        key='videos'
        icon={<div className='videos-icon' />}
        selectedIcon={<div className='videos-selected-icon' />}
        selected={pathname === '/videos'}
        onPress={() => {
          browserHistory.push('/videos')
        }}
      >
        { pathname === '/videos' ? children : null }
      </TabBar.Item>
      <TabBar.Item
        title='我的'
        key='mine'
        icon={<div className='mine-icon' />}
        selectedIcon={<div className='mine-selected-icon' />}
        selected={pathname === '/mine'}
        onPress={() => {
          browserHistory.push('/mine')
        }}
      >
        { pathname === '/mine' ? children : null }
      </TabBar.Item>
    </TabBar>
  )
}

这里重点的代码就是 pathname === '/questions' ? children : null,根据当前路由判断加载不同的 component,并且在点击任何一个按钮的时候,自动跳转到指定的路由上。其中 selected 属性也根据路由动态的变换样式。路由传递给 mainLayout 是一个 children,这个 children 中就包含了组件的信息,我们根据路由的不同加载即可。

总结

这样处理后无论我们直接访问 URL 还是点击 tabbar 下面的任意按钮,不但可以切换页面,路由也会随之变动。最重要的是我们套用了 layout,让项目看起来更加合理。

在远程工作中,并不是所有项目都是从头开始的,有很多项目是已经做了一部分,或者需要按着其要求来创建项目和编码的。所以这其中就有一些公司或者团队会使用一些代码规范,以保证无论是公司内部还是远程工作的同事都可以保持一致的代码规范,让代码不会过于凌乱。

继续阅读