谈CSS的设计模式

  什么是设计模式?

曾有人调侃,设计模式是工程师用于跟别人显摆的,显得高大上;也曾有人这么说,不是设计模式没用,是你还没有到能懂它,会用它的时候。

先来看一下比较官方的解释:“ 设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。”

今天我们来聊聊CSS的设计模式。(以下排名不分先后)

一、OOCSS——Object Oriented CSS

  接触过计算机的应该都知道,OOP——Object Oriented Programming,如果你是第一次接触OOCSS,你会很困惑,难道是“面向对象的CSS”吗?它不是一本真正的编程语言啊,如何面向对象?

  OOCSS,最早被提及,是在2009年,它的两大原则是:

  separating structure from skin and container from content.

  直译过来就是,结构和皮肤分离,容器和内容分离。

  即不要把结构和皮肤以及内容进行强耦合,而是相互独立,所要达到的目标是更易复用和组合,可以选择使用,选择引用等。

   详细了解 :https://www.smashingmagazine.com/2011/12/an-introduction-to-object-oriented-css-oocss/

二、SMACSS – Scalable and Modular Architecture for CSS

  从实践上说,OOCSS给出了一种值得借鉴的思想,但在代码的组织方面,它并未给出具体的实施方法,从这一点上来说,SMACSS更进一步。

  它的核心是:

  1、Base(基础)

  基础的样式,就是一些需要最先定义好,针对于某一类元素的通用固定样式。

  2、Layout(布局)

  布局样式,是跟页面整体结构相关,譬如,列表,主内容,侧边栏的位置、宽高、布局方式等。

  3、Module(模块)

  模块样式,就是我们在对页面进行拆的过程中,所抽取分类的模块,这类的样式分别写到一起。

  4、State(状态)

  页面中的某些元素会需要响应不同的状态,比如,可用、不可用、已用、过期、警告等等。将这类样式可以组织到一起。

  5、Theme(主题)

  主题是指版面整个的颜色、风格之类,一般网站不会有频繁的较大的改动,给我们印象比较深的是QQ空间,其他应用的不是很多,所以,这个一般不会用到,但有这样一个意识是好的,需要用到的时候,就知道该怎样规划。

  有了以上5点分类策略,我们的代码组织起来,思路就会很清晰,会安排的很有序,另外的好处是,可以解决命名难和混乱,之所以有这个问题,主因便是我们不知道以怎样的标准去定义元素的所属和特点,有了分类之后,我们不会很随意和混乱的去命名,有了依据,就能更轻松,也不易冲突。

  详细了解:https://smacss.com/

  三、Meta CSS

  原子类,也可以称之为“无语义”类,像这样:

Meta CSS 案例

  它的特点是什么?样式和结构、内容无关,预先定义好这么一组规则,在需要的地方加上即可。

  虽然它有缺点,我个人赞成另外的一些东西分出来,比如:浮动(float)、文本布局(text-align)、Flexbox布局等,这些是没有那么多可能性的值,而且使用频繁,复用方便,改动较少,除此之外,你还可以提取另外一些公共的小颗粒类,比如按钮的种类,文字颜色的种类等,这些和CSS本身无关,和项目相关,这就是借鉴其思想,而不是直接拿来用。

四、BEM

  严格说来,BEM不是一套有骨有肉的模式,也不仅仅局限你在CSS的层面去规划,它是一种怎样去组织、编写代码的思想,而且,看似简单的它,对前端界的影响却是巨大的。

  它的核心如下:

  Block(块)、Element(元素)、Modifier(修饰符)

  它帮助我们定义页面中每一部分的级别属性,从某种意义上说,也是一种“拆”。命名规则如下:

BEM案例

   详细了解 : https://en.bem.info/

VUE 中的 provide/inject 的浅析

前段时间在看 element-UI 的源码,发现了这样 一个属性: inject,于是去官网翻了翻文档 provider / inject

provider / inject:简单的来说就是在父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量。

需要注意的是这里不论子组件有多深,只要调用了 inject 那么就可以注入 provider 中的数据。而不是局限于只能从当前父组件的 prop 属性来获取数据。

下面我们来验证下猜想:

// 定义一个 Parent Component

<template>
<div id="app">
<child1 />
</div>
</template>

<script>
import child1 from "./components/child1.vue";

export default {
name: "app",
components: {
child1
},
provide() {
return {
vflyweb: "这是Parent Component传递过来的数据"
};
}
};
</script>

// 这里我们在父组件中provide 声明vflyweb这个变量。
// 定义一个子组件 child1

<template>
<div class="child1">
<h1>child1: {{ data1 }}</h1>
<child2 />
</div>
</template>

<script>
import child2 from "./child1.vue";
export default {
name: "Child1",
inject: ["vflyweb"],
data() {
return {
data1: this.vflyweb
};
},
components: {
child2
}
};
</script>

// inject: ["vflyweb"]
// 定义另外一个子组件 child2 

<template>
<div class="child2">
<h1>Child2: {{ data2 }}</h1>
</div>
</template>

<script>
export default {
name: "Child2",
inject: ["vflyweb"],
data() {
return {
data2: this.vflyweb
};
}
};
</script>

// 同样 inject: ["vflyweb"]
运行结果如上图

从上面这个例子可以看出,只要在父组件中调用了,那么在这个父组件生效的生命周期内,所有的子组件都可以调用inject来注入父组件中的值。

left join、right join 和 inner join 之间的区别

关于 inner join left join 之间的区别,以前以为自己搞懂了,今天从前端取参数的时候发现不是预想中的结果,才知道问题出在 inner join 上了。

需求是从数据库查数据,在前端以柱形图的形式展现出来,查到的数据按行业分组,显示每个行业的户数及户数占比,涉及到的字段有A表的用户数、总用户数和B表的行业名称。本来是不管查不查的到数据,在X轴都应该显示行业名称的,结果是X、Y轴都没有任何数据显示。问题就是我用错了联结方式。 继续阅读“left join、right join 和 inner join 之间的区别”

java中变量作用域的理解

在Java中,变量的作用域分为四个级别:类级、对象实例级、方法级、块级

类级变量又称全局级变量或静态变量,需要使用static关键字修饰。类级变量在类定义后就已经存在,占用内存空间,可以通过类名来访问,不需要实例化。 对象实例级变量就是成员变量,实例化后才会分配内存空间,才能访问。 方法级变量就是在方法内部定义的变量,就是局部变量。 继续阅读“java中变量作用域的理解”

强大的CSS3动画库Animate.css

Animate.css 是一个来自国外的 CSS3 动画库,它预设了抖动(shake)、闪烁(flash)、弹跳(bounce)、翻转(flip)、旋转(rotateIn/rotateOut)、淡入淡出(fadeIn/fadeOut)等多达 60 多种动画效果,几乎包含了所有常见的动画效果。

虽然借助 Animate.css 能够很方便、快速的制作 CSS3 动画效果,但还是建议看看 Animate.css 的代码,也许你能从中学到一些东西。 继续阅读“强大的CSS3动画库Animate.css”