如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里
附Java/C/C++/機器學習/算法與數據結構/前端/安卓/Python/程序員必讀書籍書單大全:
書單導航頁(點擊右側 極客俠棧 即可打開個人博客):極客俠棧
①【Java】學習之路吐血整理技術書從入門到進階最全50+本(珍藏版)
②【算法數據結構+acm】從入門到進階吐血整理書單50+本(珍藏版)
③【數據庫】從入門到進階必讀18本技術書籍網盤吐血整理網盤(珍藏版)
④【Web前端】從HTML到JS到AJAX到HTTP從框架到全棧幫你走更少彎路(珍藏版)
⑤【python】書最全已整理好(從入門到進階)(珍藏版)
⑥【機器學習】+python整理技術書(從入門到進階已經整理好)(珍藏版)
⑦【C語言】推薦書籍從入門到進階帶你走上大牛之路(珍藏版)
⑧【安卓】入門到進階推薦書籍整理pdf書單整理(珍藏版)
⑨【架構師】之路史詩級必讀書單吐血整理四個維度系列80+本書(珍藏版)
⑩【C++】吐血整理推薦書單從入門到進階成神之路100+本(珍藏)
?【ios】IOS書單從入門到進階吐血整理(珍藏版)
--------------------------------------------------------------------------------------------------------------------
如果您已經入門reactjs,請繞道~ 這篇博客只適合初學者,初學reactjs的時候,如果你不會webpack,相信很多人都會被官方的例子繞的暈頭轉向。 ES6的例子也會搞死一批入門者。之前一直用的gulp,突然換了webpack,我也非常不習慣。在這塊也卡住了,對于想學reactjs的朋友,我的學習建議是這樣的:
nodejs => webpack => ES6 => reactjs
官方的很多例子都是ES6語法+webpack打包的,所以在學習reactjs之前,最好是會ES6和webpack,這樣能事半功倍!
1、首先來說說nodejs
先安裝版本的nodejs,npm一般都是自帶的。安裝成全局的比較方便構建項目。
npm install -g grunt-cli # 全局安裝
npm可安裝的插件可以在這里去找找 www.npmjs.com/ 如果不能安裝,可以使用淘寶的鏡象資源
2、webpack
webpack是一款打包工具,可以做一些js壓縮,sass,less轉換,圖片處理,js代碼合成,ES6轉ES5語法等很多功能,如果用過grunt,或者gulp的朋友,webpack也就不陌生了。都是需要寫配置文件。
3、ES6
github上很多案例都是用到了ES6的語法,所以,這里我們可以通過webpack的工具 babel ,把ES6的語法轉化為ES5的語法,這樣我們就可以使用github上面的demo了。
比如:
import '../css/common.scss';
import React from 'react'
import { render } from 'react-dom'
import { Router, Route, Link, IndexRoute } from 'react-router'
import { browserHistory } from 'react-router'
這里的import 就是ES6的語法,在webpack里面使用babel工具將其轉化為 ES5的語法。我這里用了JSX(reactjs 提供的一種簡潔的語法)如果對JSX不了解的,可以去百度下。
4、快速開發
每次我們在修改JSX文件,或者SASS文件后,都要執行webpack命令進行打包,這樣的開發效率很慢,官方提供了一個很牛X的工具,react-hot-loader + webpack-dev-server 可以幫助你快速開發,自動刷新頁面。
5、DEMO小試牛刀
這里我把自己做的一個DEMO分享給大家,如果你已經安裝了nodejs,并且npm也是全局的。下載后解壓,打開 start.bat,輸入 npm install 安裝所需的插件,安裝成功后執行 npm start ,等項目跑起來后,在瀏覽器輸入 http://127.0.0.1:3000 就可以訪問項目了。
這里是一個 react-router 的一個例子。
github 地址:https://github.com/mtsee/react-router-demo
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務。
如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里
按照這個來配置就好了,這里相當于是幫你把webpack需要的繁瑣的配置給你都弄好了,然后你直接從那里全部下下來就可以
記得先下好nodejs,安裝的代碼記得全都c v,不要自己敲
安裝完nodejs之后再安裝淘寶npm鏡像,安裝完了之后后面的安裝速度會快一點
npm install -g cnpm --registry=https://registry.npm.taobao.org
1
然后按照下面的五步流程一個一個來
1、全局安裝vue-cli
npm install -g vue-cli
1
2、進入目錄–初始化項目
vue init webpack my-project //這個要進入項目目錄再用,會創建一個my-project的文件夾
1
3、進入項目
cd my-project
1
4、安裝依賴
npm install
1
5、啟動項目
npm run dev
1
以上執行完后會出現一個 my-project 項目文件夾,用vscode打開后會看到以下目錄
下面解釋一下這些文件及目錄分別是干什么的
目錄結構的分析
1、bind
├── build // 項目構建(webpack)相關代碼 記憶:(夠賤) 9個
│ ├── build.js // 生產環境構建代碼
│ ├── check-versions.js // 檢查node&npm等版本
│ ├── dev-client.js // 熱加載相關
│ ├── dev-server.js // 構建本地服務器
│ ├── utils.js // 構建配置公用工具
│ ├── vue-loader.conf.js // vue加載器
│ ├── webpack.base.conf.js // webpack基礎環境配置
│ ├── webpack.dev.conf.js // webpack開發環境配置
│ └── webpack.prod.conf.js // webpack生產環境配置
2、config
├── config// 項目開發環境配置相關代碼 記憶: (環配) 3個
│ ├── dev.env.js // 開發環境變量(看詞明意)
│ ├── index.js //項目一些配置變量
│ └── prod.env.js // 生產環境變量
3、node_modules
├──node_modules// 項目依賴的模塊 記憶: (依賴) *個
4、src
├── src// 源碼目錄 5
1
│ ├── assets// 資源目錄
│ │ └── logo.png
2
│ ├── components// vue公共組件
│ │ └── Hello.vue
3
│ ├──router// 前端路由
│ │ └── index.js// 路由配置文件
4
│ ├── App.vue// 頁面入口文件(根組件)
5
│ └── main.js// 程序入口文件(入口js文件)
5、static
└── static// 靜態文件,比如一些圖片,json數據等
│ ├── .gitkeep
6、剩余的文件
├── .babelrc// ES6語法編譯配置
├── .editorconfig// 定義代碼格式
├── .gitignore// git上傳需要忽略的文件格式
├── index.html// 入口頁面
├── package.json// 項目基本信息
├── README.md// 項目說明
---------------------
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務。
如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里
加粗樣式
***@TOC
歡迎使用Markdown編輯器
你好! 這是你第一次使用 Markdown編輯器 所展示的歡迎頁。如果你想學習如何使用Markdown編輯器, 可以仔細閱讀這篇文章,了解一下Markdown的基本語法知識。
新的改變
我們對Markdown編輯器進行了一些功能拓展與語法支持,除了標準的Markdown編輯器功能,我們增加了如下幾點新功能,幫助你用它寫博客:
全新的界面設計 ,將會帶來全新的寫作體驗;
在創作中心設置你喜愛的代碼高亮樣式,Markdown 將代碼片顯示選擇的高亮樣式 進行展示;
增加了 圖片拖拽 功能,你可以將本地的圖片直接拖拽到編輯區域直接展示;
全新的 KaTeX數學公式 語法;
增加了支持甘特圖的mermaid語法1 功能;
增加了 多屏幕編輯 Markdown文章功能;
增加了 焦點寫作模式、預覽模式、簡潔寫作模式、左右區域同步滾輪設置 等功能,功能按鈕位于編輯區域與預覽區域中間;
增加了 檢查列表 功能。
功能快捷鍵
撤銷:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜體:Ctrl/Command + I
標題:Ctrl/Command + Shift + H
無序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
檢查列表:Ctrl/Command + Shift + C
插入代碼:Ctrl/Command + Shift + K
插入鏈接:Ctrl/Command + Shift + L
插入圖片:Ctrl/Command + Shift + G
合理的創建標題,有助于目錄的生成
直接輸入1次#,并按下space后,將生成1級標題。
輸入2次#,并按下space后,將生成2級標題。
以此類推,我們支持6級標題。有助于使用TOC語法后生成一個完美的目錄。
如何改變文本的樣式
強調文本 強調文本
加粗文本 加粗文本
標記文本
刪除文本
引用文本
H2O is是液體。
210 運算結果是 1024.
插入鏈接與圖片
鏈接: link.
圖片:
帶尺寸的圖片:
居中的圖片:
居中并且帶尺寸的圖片:
當然,我們為了讓用戶更加便捷,我們增加了圖片拖拽功能。
如何插入一段漂亮的代碼片
去博客設置頁面,選擇一款你喜歡的代碼片高亮樣式,下面展示同樣高亮的 代碼片.
// An highlighted block
var foo = 'bar';
1
2
生成一個適合你的列表
項目
項目
項目
項目1
項目2
項目3
計劃任務
完成任務
創建一個表格
一個簡單的表格是這么創建的:
項目 Value
電腦 $1600
手機 $12
導管 $1
設定內容居中、居左、居右
使用:---------:居中
使用:----------居左
使用----------:居右
第一列 第二列 第三列
第一列文本居中 第二列文本居右 第三列文本居左
SmartyPants
SmartyPants將ASCII標點字符轉換為“智能”印刷標點HTML實體。例如:
TYPE ASCII HTML
Single backticks 'Isn't this fun?' ‘Isn’t this fun?’
Quotes "Isn't this fun?" “Isn’t this fun?”
Dashes -- is en-dash, --- is em-dash – is en-dash, — is em-dash
創建一個自定義列表
Markdown
Text-to-HTML conversion tool
Authors
John
Luke
如何創建一個注腳
一個具有注腳的文本。2
注釋也是必不可少的
Markdown將文本轉換為 HTML。
KaTeX數學公式
您可以使用渲染LaTeX數學表達式 KaTeX:
Gamma公式展示 Γ(n)=(n?1)!?n∈N \Gamma(n) = (n-1)!\quad\foralln\in\mathbb NΓ(n)=(n?1)!?n∈N 是通過歐拉積分
Unexpected text node: ' 'Unexpected text node: ' '
Γ(z)=∫
0
∞
t
z?1
e
?t
dt.
你可以找到更多關于的信息 LaTeX 數學表達式here.
新的甘特圖功能,豐富你的文章
Mon 06
Mon 13
Mon 20
已完成
進行中
計劃一
計劃二
現有任務
Adding GANTT diagram functionality to mermaid
關于 甘特圖 語法,參考 這兒,
UML 圖表
可以使用UML圖表進行渲染。 Mermaid. 例如下面產生的一個序列圖::
張三
李四
王五
你好!李四, 最近怎么樣?
你最近怎么樣,王五?
我很好,謝謝!
我很好,謝謝!
李四想了很長時間,文字太長了不適合放在一行.
打量著王五...
很好... 王五, 你怎么樣?
張三
李四
王五
這將產生一個流程圖。:
鏈接
長方形
圓
圓角長方形
菱形
關于 Mermaid 語法,參考 這兒,
FLowchart流程圖
我們依舊會支持flowchart的流程圖:
開始
我的操作
確認?
結束
yes
no
關于 Flowchart流程圖 語法,參考 這兒.
導出與導入
導出
如果你想嘗試使用此編輯器, 你可以在此篇文章任意編輯。當你完成了一篇文章的寫作, 在上方工具欄找到 文章導出 ,生成一個.md文件或者.html文件進行本地保存。
導入
如果你想加載一篇你寫過的.md文件或者.html文件,在上方工具欄可以選擇導入功能進行對應擴展名的文件導入,
繼續你的創作。
mermaid語法說明 ??
注腳的解釋 ??
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務。
如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里
1. 如何實現一個響應式對象
最近在看 Vue 的源碼,其中最核心基礎的一塊就是 Observer/Watcher/Dep, 簡而言之就是,Vue 是如何攔截數據的讀寫, 如果實現對應的監聽,并且特定的監聽執行特定的回調或者渲染邏輯的??偟目梢圆鸪扇髩K來說。這一塊,主要說的是 Vue 是如何將一個 plain object 給處理成 reactive object 的,也就是,Vue 是如何攔截攔截對象的 get/set 的
我們知道,用 Object.defineProperty 攔截數據的 get/set 是 vue 的核心邏輯之一。這里我們先考慮一個最簡單的情況 一個 plain obj 的數據,經過你的程序之后,使得這個 obj 變成 Reactive Obj (不考慮數組等因素,只考慮最簡單的基礎數據類型,和對象):
如果這個 obj 的某個 key 被 get, 則打印出 get ${key} - ${val} 的信息
如果這個 obj 的某個 key 被 set, 如果監測到這個 key 對應的 value 發生了變化,則打印出 set ${key} - ${val} - ${newVal} 的信息。
對應的簡要代碼如下:
Observer.js
export class Observer {
constructor(obj) {
this.obj = obj;
this.transform(obj);
}
// 將 obj 里的所有層級的 key 都用 defineProperty 重新定義一遍, 使之 reactive
transform(obj) {
const _this = this;
for (let key in obj) {
const value = obj[key];
makeItReactive(obj, key, value);
}
}
}
function makeItReactive(obj, key, val) {
// 如果某個 key 對應的 val 是 object, 則重新迭代該 val, 使之 reactive
if (isObject(val)) {
const childObj = val;
new Observer(childObj);
}
// 如果某個 key 對應的 val 不是 Object, 而是基礎類型,我們則對這個 key 進行 defineProperty 定義
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: () => {
console.info(`get ${key}-${val}`)
return val;
},
set: (newVal) => {
// 如果 newVal 和 val 相等,則不做任何操作(不執行渲染邏輯)
if (newVal === val) {
return;
}
// 如果 newVal 和 val 不相等,且因為 newVal 為 Object, 所以先用 Observer迭代 newVal, 使之 reactive, 再用 newVal 替換掉 val, 再執行對應操作(渲染邏輯)
else if (isObject(newVal)) {
console.info(`set ${key} - ${val} - ${newVal} - newVal is Object`);
new Observer(newVal);
val = newVal;
}
// 如果 newVal 和 val 不相等,且因為 newVal 為基礎類型, 所以用 newVal 替換掉 val, 再執行對應操作(渲染邏輯)
else if (!isObject(newVal)) {
console.info(`set ${key} - ${val} - ${newVal} - newVal is Basic Value`);
val = newVal;
}
}
})
}
function isObject(data) {
if (typeof data === 'object' && data != 'null') {
return true;
}
return false;
}
index.js
import { Observer } from './source/Observer.js';
// 聲明一個 obj,為 plain Object
const obj = {
a: {
aa: 1
},
b: 2,
}
// 將 obj 整體 reactive 化
new Observer(obj);
// 無輸出
obj.b = 2;
// set b - 2 - 3 - newVal is Basic Value
obj.b = 3;
// set b - 3 - [object Object] - newVal is Object
obj.b = {
bb: 4
}
// get b-[object Object]
obj.b;
// get a-[object Object]
obj.a;
// get aa-1
obj.a.aa
// set aa - 1 - 3 - newVal is Basic Value
obj.a.aa = 3
這樣,我們就完成了 Vue 的第一個核心邏輯, 成功把一個任意層級的 plain object 轉化成 reactive object
2. 如何實現一個 watcher
前面講的是如何將 plain object 轉換成 reactive object. 接下來講一下,如何實現一個watcher.
實現的偽代碼應如下:
偽代碼
// 傳入 data 參數新建新建一個 vue 對象
const v = new Vue({
data: {
a:1,
b:2,
}
});
// watch data 里面某個 a 節點的變動了,如果變動,則執行 cb
v.$watch('a',function(){
console.info('the value of a has been changed !');
});
// watch data 里面某個 b 節點的變動了,如果變動,則執行 cb
v.$watch('b',function(){
console.info('the value of b has been changed !');
})
Vue.js
// 引入將上面中實現的 Observer
import { Observer } from './Observer.js';
import { Watcher } from './Watcher.js';
export default class Vue {
constructor(options) {
// 在 this 上掛載一個公有變量 $options ,用來暫存所有參數
this.$options = options
// 聲明一個私有變量 _data ,用來暫存 data
let data = this._data = this.$options.data
// 在 this 上掛載所有 data 里的 key 值, 這些 key 值對應的 get/set 都被代理到 this._data 上對應的同名 key 值
Object.keys(data).forEach(key => this._proxy(key));
// 將 this._data 進行 reactive 化
new Observer(data, this)
}
// 對外暴露 $watch 的公有方法,可以對某個 this._data 里的 key 值創建一個 watcher 實例
$watch(expOrFn, cb) {
// 注意,每一個 watcher 的實例化都依賴于 Vue 的實例化對象, 即 this
new Watcher(this, expOrFn, cb)
}
// 將 this.keyName 的某個 key 值的 get/set 代理到 this._data.keyName 的具體實現
_proxy(key) {
var self = this
Object.defineProperty(self, key, {
configurable: true,
enumerable: true,
get: function proxyGetter() {
return self._data[key]
},
set: function proxySetter(val) {
self._data[key] = val
}
})
}
}
Watch.js
// 引入Dep.js, 是什么我們待會再說
import { Dep } from './Dep.js';
export class Watcher {
constructor(vm, expOrFn, cb) {
this.cb = cb;
this.vm = vm;
this.expOrFn = expOrFn;
// 初始化 watcher 時, vm._data[this.expOrFn] 對應的 val
this.value = this.get();
}
// 用于獲取當前 vm._data 對應的 key = expOrFn 對應的 val 值
get() {
Dep.target = this;
const value = this.vm._data[this.expOrFn];
Dep.target = null;
return value;
}
// 每次 vm._data 里對應的 expOrFn, 即 key 的 setter 被觸發,都會調用 watcher 里對應的 update方法
update() {
this.run();
}
run() {
// 這個 value 是 key 被 setter 調用之后的 newVal, 然后比較 this.value 和 newVal, 如果不相等,則替換 this.value 為 newVal, 并執行傳入的cb.
const value = this.get();
if (value !== this.value) {
this.value = value;
this.cb.call(this.vm);
}
}
}
對于什么是 Dep, 和 Watcher 里的 update() 方法到底是在哪個時候被誰調用的,后面會說
3. 如何收集 watcher 的依賴
前面我們講了 watcher 的大致實現,以及 Vue 代理 data 到 this 上的原理?,F在我們就來梳理一下,Observer/Watcher 之間的關系,來說明它們是如何調用的.
首先, 我們要來理解一下 watcher 實例的概念。實際上 Vue 的 v-model, v-bind , {{ mustache }}, computed, watcher 等等本質上是分別對 data 里的某個 key 節點聲明了一個 watcher 實例.
<input v-model="abc">
<span>{{ abc }}</span>
<p :data-key="abc"></p>
...
const v = new Vue({
data:{
abc: 111,
}
computed:{
cbd:function(){
return `${this.abc} after computed`;
}
watch:{
abc:function(val){
console.info(`${val} after watch`)
}
}
}
})
這里,Vue 一共聲明了 4 個 watcher 實例來監聽abc, 1個 watcher 實例來監聽 cbd. 如果 abc 的值被更改,那么 4 個 abc - watcher 的實例會執行自身對應的特定回調(比如重新渲染dom,或者是打印信息等等)
不過,Vue 是如何知道,某個 key 對應了多少個 watcher, 而 key 對應的 value 發生變化后,又是如何通知到這些 watcher 來執行對應的不同的回調的呢?
實際上更深層次的邏輯是:
在 Observer階段,會為每個 key 都創建一個 dep 實例。并且,如果該 key 被某個 watcher 實例 get, 把該 watcher 實例加入 dep 實例的隊列里。如果該 key 被 set, 則通知該 key 對應的 dep 實例, 然后 dep 實例會將依次通知隊列里的 watcher 實例, 讓它們去執行自身的回調方法
dep 實例是收集該 key 所有 watcher 實例的地方.
watcher 實例用來監聽某個 key ,如果該 key 產生變化,便會執行 watcher 實例自身的回調
相關代碼如下:
Dep.js
export class Dep {
constructor() {
this.subs = [];
}
// 將 watcher 實例置入隊列
addSub(sub) {
this.subs.push(sub);
}
// 通知隊列里的所有 watcher 實例,告知該 key 的 對應的 val 被改變
notify() {
this.subs.forEach((sub, index, arr) => sub.update());
}
}
// Dep 類的的某個靜態屬性,用于指向某個特定的 watcher 實例.
Dep.target = null
observer.js
import {Dep} from './dep'
function makeItReactive(obj, key, val) {
var dep = new Dep()
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: () => {
// 收集依賴! 如果該 key 被某個 watcher 實例依賴,則將該 watcher 實例置入該 key 對應的 dep 實例里
if(Dep.target){
dep.addSub(Dep.target)
}
return val
},
set: (newVal) => {
if (newVal === val) {
return;
}
else if (isObject(newVal)) {
new Observer(newVal);
val = newVal;
// 通知 dep 實例, 該 key 被 set,讓 dep 實例向所有收集到的該 key 的 watcher 實例發送通知
dep.notify()
}
else if (!isObject(newVal)) {
val = newVal;
// 通知 dep 實例, 該 key 被 set,讓 dep 實例向所有收集到的該 key 的 watcher 發送通知
dep.notify()
}
}
})
}
watcher.js
import { Dep } from './Dep.js';
export class Watcher {
constructor(vm, expOrFn, cb) {
this.cb = cb;
this.vm = vm;
this.expOrFn = expOrFn;
this.value = this.get();
}
get() {
// 在實例化某個 watcher 的時候,會將Dep類的靜態屬性 Dep.target 指向這個 watcher 實例
Dep.target = this;
// 在這一步 this.vm._data[this.expOrFn] 調用了 data 里某個 key 的 getter, 然后 getter 判斷類的靜態屬性 Dep.target 不為null, 而為 watcher 的實例, 從而把這個 watcher 實例添加到 這個 key 對應的 dep 實例里。 巧妙!
const value = this.vm._data[this.expOrFn];
// 重置類屬性 Dep.target
Dep.target = null;
return value;
}
// 如果 data 里的某個 key 的 setter 被調用,則 key 會通知到 該 key 對應的 dep 實例, 該Dep實例, 該 dep 實例會調用所有 依賴于該 key 的 watcher 實例的 update 方法。
update() {
this.run();
}
run() {
const value = this.get();
if (value !== this.value) {
this.value = value;
// 執行 cb 回調
this.cb.call(this.vm);
}
}
}
總結:
至此, Watcher, Observer , Dep 的關系全都梳理完成。而這些也是 Vue 實現的核心邏輯之一。再來簡單總結一下三者的關系,其實是一個簡單的 觀察-訂閱 的設計模式, 簡單來說就是, 觀察者觀察數據狀態變化, 一旦數據發生變化,則會通知對應的訂閱者,讓訂閱者執行對應的業務邏輯 。我們熟知的事件機制,就是一種典型的觀察-訂閱的模式
Observer, 觀察者,用來觀察數據源變化.
Dep, 觀察者和訂閱者是典型的 一對多 的關系,所以這里設計了一個依賴中心,來管理某個觀察者和所有這個觀察者對應的訂閱者的關系, 消息調度和依賴管理都靠它。
Watcher, 訂閱者,當某個觀察者觀察到數據發生變化的時候,這個變化經過消息調度中心,最終會傳遞到所有該觀察者對應的訂閱者身上,然后這些訂閱者分別執行自身的業務回調即可
參考
Vue源碼解讀-滴滴FED
代碼參考
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務。
如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里
如何爬去爬去今日頭條動態數據,
網上有很多教程,我就不在啰嗦了
第一步如何分析得到存儲數據的真實url
首先打開https://www.toutiao.com/,搜索街拍,會跳轉https://www.toutiao.com/search/?keyword=%E8%A1%97%E6%8B%8D
你如果用傳統的方式你將的得不到任何有價值的信息
這個時候你怎么辦呢?
你這個時候注意查看requests url,
Request URL: https://www.toutiao.com/api/search/content/?aid=24&app_name=web_search&offset=0&format=json&keyword=街拍&autoload=true&count=20&en_qc=1&cur_tab=1&from=search_tab&pd=synthesis×tamp=1559831008973
到這里我們就找到了數據春芳的真正url了
你好! 這是你第一次使用 Markdown編輯器 所展示的歡迎頁。如果你想學習如何使用Markdown編輯器, 可以仔細閱讀這篇文章,了解一下Markdown的基本語法知識。
后面就簡單了,直接上代碼
import os
import re
import json
import requests
from requests import RequestException
from requests import exceptions
from urllib.parse import urlencode
from demo01.util import buid_proxy
‘’’
抓取今日頭條圖片圖片集
因為今天頭條數據是動態,因此第一步是找到存儲圖片的真正url
第二步就是構造瀏覽器(偽瀏覽器),因為現在防爬網站做的很好,他會更具某項標準你是否是機器人,因此這步很重要
‘’’
proxies=buid_proxy()
def get_one_page(offset, keyword):
‘’’
獲取網頁html內容并返回
‘’’
params = {
‘aid’: ‘24’,
‘app_name’: ‘web_search’,
‘offset’: offset,
‘format’: ‘json’,
‘keyword’:keyword,
‘autoload’: ‘true’,
‘count’: ‘20’,
‘cur_tab’: ‘1’,
‘from’: ‘search_tab’,
‘pd’: ‘synthesis’,
‘timestamp’: ‘1559660659001’}
header = {
"User-Agen":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36",
"referer":"https://www.toutiao.com/search/?keyword=%E8%A1%97%E6%8B%8D",
"cookie":"tt_webid=6692573135994799624; UM_distinctid=16ace1c56988c-06f62adc4fd369-7a1437-144000-16ace1c5699a3; csrftoken=368635b7c1d736ff1889c2b70705afa9; tt_webid=6692573135994799624; WEATHER_CITY=%E5%8C%97%E4%BA%AC; s_v_web_id=152a5d87eb7690f9953388e50371f37b; CNZZDATA1259612802=1893030441-1558619693-https%253A%252F%252Flanding.toutiao.com%252F%7C1559662594; _ga=GA1.2.569135354.1559664708; _gid=GA1.2.419995265.1559664708; __tasessionId=wb39ej38m1559741348358",
}
url = 'https://www.toutiao.com/api/search/content/?' + urlencode(params)
#print(url)
try:
# 獲取網頁內容,返回json格式數據
response = requests.get(url, headers=header,proxies=proxies)
# 通過狀態碼判斷是否獲取成功
if response.status_code == 200:
#此處必須這樣寫不然會出現中文亂碼
response=response.content.decode('utf-8')
html=response
return html
return None
except RequestException:
return None
def parse_one_page(html):
‘’’
解析出組圖網址,并將網頁中所有圖集的標題及圖片地址返回
‘’’
urls = []
data = json.loads(html,encoding=‘utf-8’)
if data and ‘data’ in data.keys():
for item in data.get(‘data’):
#print(item)
page_urls = []
title = item.get(‘title’)
#print(title)
image_list = item.get(‘image_list’)
if image_list !=None:
for i in range(len(image_list)):
# 獲取large圖片地址
url = image_list[i][‘url’]
# 替換URL獲取高清原圖
url = url.replace(‘large’, ‘origin’)
page_urls.append(url)
urls.append({‘title’: title,‘url_list’: page_urls})
return urls
def save_image_file(url, path):
‘’’
保存圖像文件
‘’’
ir = requests.get(url)
if ir.status_code == 200:
with open(path, ‘wb’) as f:
f.write(ir.content)
f.close()
def main(offset, word):
html = get_one_page(offset, word)
#print(html)
urls = parse_one_page(html)
print(urls)
#圖像文件夾不存在則創建
root_path = 'E:/test001/photo/TOUTIAO'
if not os.path.exists(root_path):
os.mkdir(root_path)
for i in range(len(urls)):
print('---正在下載 %s'%urls[i]['title'])
folder = root_path + '/' + urls[i]['title']
if not os.path.exists(folder):
try:
os.mkdir(folder)
except NotADirectoryError:
continue
except OSError:
continue
url_list = urls[i]['url_list']
try:
for j in range(len(url_list)):
path = folder + '/index_' + str("%02d"%j) + '.jpg'
if not os.path.exists(path):
save_image_file(urls[i]['url_list'][j], path)
except exceptions.ProxyError:
return None
if name == ‘main’:
main(0,‘街拍’)
新的改變
我們對Markdown編輯器進行了一些功能拓展與語法支持,除了標準的Markdown編輯器功能,我們增加了如下幾點新功能,幫助你用它寫博客:
全新的界面設計 ,將會帶來全新的寫作體驗;
在創作中心設置你喜愛的代碼高亮樣式,Markdown 將代碼片顯示選擇的高亮樣式 進行展示;
增加了 圖片拖拽 功能,你可以將本地的圖片直接拖拽到編輯區域直接展示;
全新的 KaTeX數學公式 語法;
增加了支持甘特圖的mermaid語法1 功能;
增加了 多屏幕編輯 Markdown文章功能;
增加了 焦點寫作模式、預覽模式、簡潔寫作模式、左右區域同步滾輪設置 等功能,功能按鈕位于編輯區域與預覽區域中間;
增加了 檢查列表 功能。
功能快捷鍵
撤銷:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜體:Ctrl/Command + I
標題:Ctrl/Command + Shift + H
無序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
檢查列表:Ctrl/Command + Shift + C
插入代碼:Ctrl/Command + Shift + K
插入鏈接:Ctrl/Command + Shift + L
插入圖片:Ctrl/Command + Shift + G
合理的創建標題,有助于目錄的生成
直接輸入1次#,并按下space后,將生成1級標題。
輸入2次#,并按下space后,將生成2級標題。
以此類推,我們支持6級標題。有助于使用TOC語法后生成一個完美的目錄。
如何改變文本的樣式
強調文本 強調文本
加粗文本 加粗文本
標記文本
刪除文本
引用文本
H2O is是液體。
210 運算結果是 1024.
插入鏈接與圖片
鏈接: link.
圖片:
帶尺寸的圖片:
居中的圖片:
居中并且帶尺寸的圖片:
當然,我們為了讓用戶更加便捷,我們增加了圖片拖拽功能。
如何插入一段漂亮的代碼片
去博客設置頁面,選擇一款你喜歡的代碼片高亮樣式,下面展示同樣高亮的 代碼片.
// An highlighted block
var foo = 'bar';
1
2
生成一個適合你的列表
項目
項目
項目
項目1
項目2
項目3
計劃任務
完成任務
創建一個表格
一個簡單的表格是這么創建的:
項目 Value
電腦 $1600
手機 $12
導管 $1
設定內容居中、居左、居右
使用:---------:居中
使用:----------居左
使用----------:居右
第一列 第二列 第三列
第一列文本居中 第二列文本居右 第三列文本居左
SmartyPants
SmartyPants將ASCII標點字符轉換為“智能”印刷標點HTML實體。例如:
TYPE ASCII HTML
Single backticks 'Isn't this fun?' ‘Isn’t this fun?’
Quotes "Isn't this fun?" “Isn’t this fun?”
Dashes -- is en-dash, --- is em-dash – is en-dash, — is em-dash
創建一個自定義列表
Markdown
Text-to-HTML conversion tool
Authors
John
Luke
如何創建一個注腳
一個具有注腳的文本。2
注釋也是必不可少的
Markdown將文本轉換為 HTML。
KaTeX數學公式
您可以使用渲染LaTeX數學表達式 KaTeX:
Gamma公式展示 Γ(n)=(n?1)!?n∈N \Gamma(n) = (n-1)!\quad\foralln\in\mathbb NΓ(n)=(n?1)!?n∈N 是通過歐拉積分
Unexpected text node: ' 'Unexpected text node: ' '
Γ(z)=∫
0
∞
t
z?1
e
?t
dt.
你可以找到更多關于的信息 LaTeX 數學表達式here.
新的甘特圖功能,豐富你的文章
Mon 06
Mon 13
Mon 20
已完成
進行中
計劃一
計劃二
現有任務
Adding GANTT diagram functionality to mermaid
關于 甘特圖 語法,參考 這兒,
UML 圖表
可以使用UML圖表進行渲染。 Mermaid. 例如下面產生的一個序列圖::
張三
李四
王五
你好!李四, 最近怎么樣?
你最近怎么樣,王五?
我很好,謝謝!
我很好,謝謝!
李四想了很長時間,文字太長了不適合放在一行.
打量著王五...
很好... 王五, 你怎么樣?
張三
李四
王五
這將產生一個流程圖。:
鏈接
長方形
圓
圓角長方形
菱形
關于 Mermaid 語法,參考 這兒,
FLowchart流程圖
我們依舊會支持flowchart的流程圖:
開始
我的操作
確認?
結束
yes
no
關于 Flowchart流程圖 語法,參考 這兒.
導出與導入
導出
如果你想嘗試使用此編輯器, 你可以在此篇文章任意編輯。當你完成了一篇文章的寫作, 在上方工具欄找到 文章導出 ,生成一個.md文件或者.html文件進行本地保存。
導入
如果你想加載一篇你寫過的.md文件或者.html文件,在上方工具欄可以選擇導入功能進行對應擴展名的文件導入,
繼續你的創作。
mermaid語法說明 ??
注腳的解釋 ??
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務。
如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里
Echarts數據化可視圖表
開發工具與關鍵技術:Visual Studio 2015 使用Echarts圖表
作者:郭海明
撰寫時間:2019年 6月 4日
1
2
3
在創建一個網頁的時候,有一些頁面會有許多數據,瀏覽起來枯燥而乏味,而且數據之間的對比也不夠明顯。那么有什么方法可以讓這些數據的對比明顯起來,使數據看起來也沒有那么枯燥呢!答案當然是有的,我們只需要引用Echarts數據可視化圖表就可以了。使用Echarts數據化圖表不僅可以讓數據之間對比明顯,還可以使數據更加生動起來,增強用戶瀏覽頁面數據的體驗感。
Echarts提供了常規的折線圖,柱狀圖,餅狀圖,散點圖。還有用于統計的盒型圖,用于地理數據可視化的地圖,熱力圖,線圖,用于關系數據可視化的關系圖,多維數據可視化的平行坐標。還有用戶BI的漏斗圖,儀表盤,并且支持圖與圖之間的混搭。
Echarts圖表使用起來的方法頁很簡單,首先將Echarts插件引用到視圖里面,視圖里面添加顯示Echarts圖表的類。給這個類顯示圖表的空間,并給類ID,用于后面寫好圖表之后將圖表放到這個類里面。
然后在
將學生信息數據表格需要用到的數據表,進行多表的連接查詢,連接完成之后,
獲取到需要用到的數據,封裝到自定義的AchievementInfor的實體類里面。
寫出接收不同階段成績的方法。用于接收每個不同階段的成績.
寫完之后,返回到視圖里面去寫調用Echarts的圖表,這里我們顯示的是折線圖,所以首先在
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務。
如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里
本文介紹了兩種在 JavaScript 讀取文件的方法
文件讀取在當今的編程語言中應該算是一項比較 trivial 的工作了,語言的標準庫一般都會幫助我們做好文件抽象與讀寫緩存,我們僅需要熟悉和運用相關的 API 即可.
但是 JavaScript 由于安全性的原因,一直以來都沒有提供相關的文件讀取接口,但有時我們確實需要讀取本地文件內容,下面是兩種可能的讀取方法.
1. 使用 HTML5 中的 FileReader
HTML5 引入的 FileReader 可以幫助我們讀取本地文件,但是有一個限制,就是我們不能直接使用文件路徑的方式來訪問文件,而是首先需要用戶選擇文件(通過文件選擇或者拖動文件至網頁等方式)
代碼還是比較簡單的,首先你需要在 html 文件中添加文件選擇表單:
<input type="file" id="file-input" />
<div id="file-content" />
1
2
接著就可以在 JavaScript 中進行(用戶選擇的)文件讀取了:
function readSingleFile(e) {
// file from "file-input"
var file = e.target.files[0];
if (!file) {
return;
}
// create FileReader
var reader = new FileReader();
// load callback
reader.onload = function(e) {
var contents = e.target.result;
// process file contents here
// ...
};
// do read
reader.readAsText(file);
}
// add file input change listener
var fileInput = document.getElementById("file-input");
fileInput.addEventListener("change", readSingleFile, false);
2. 使用 XMLHttpRequest
XMLHttpRequest 一般用于實現 Ajax,通過他我們也可以實現本地文件的讀取(但是有同源等限制),示例代碼如下:
var contents = "";
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.status == 200 && xmlhttp.readyState == 4) {
contents = xmlhttp.responseText;
// process file contents here
// ...
}
};
// send read request
xmlhttp.open("GET","abc.txt",true);
xmlhttp.send();
更多資料
http://researchhubs.com/post/computing/javascript/open-a-local-file-with-javascript.html
https://www.html5rocks.com/en/tutorials/file/dndfiles/
https://www.liaoxuefeng.com/wiki/1022910821149312/1023022332902400
如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里
最近折騰自己的網站,在自適應方面發現有了很多新的方法,感嘆前端的技術真是日新月異,從以前只能這樣,到現在除了這樣,還可以那樣,甚至再那樣......技術永無止境啊。
回到主題,自適應響應式布局這個話題古老而新穎,從最早的不同分辨率的屏幕,到現在遍布各個生活角落的移動設備,響應式布局已經成了幾乎所有互聯網公司必備的條件。在我的映像中,bootstrap一直是響應式的頭號選擇,的確,其中的各種xl,xs,柵格布局讓響應式變得很容易。
話說,這Vue做響應式,其實一點都不復雜:一個生命周期鉤子,一個條指令,一套js判斷語句解決,說到這,高手們應該早已經明白如何操作了, 這篇文章就給廣大剛入門的同學們拓寬一下吧(不熟悉Vue的同學,還是先惡補一下Vue基礎吧)。
一個生命周期鉤子——mounted:掛載時操作;一條指令——v-show(本例中采用,非絕對):根據條件顯示;一套js判斷語句:if/else或者switch/case。具體操作起來很簡單:(代碼直接展示)
<!--這是一段導航html-->
<nav id="nav-part" class="easyUtil-backImgPostion easyUtil-flexContainerRow">
<ul class="easyUtil-flexContainerRow">
<li class="nav-list" :class="nav.className" v-for="(nav,i) in navs">
<a :href="nav.href">{{nav.name}}</a>
</li>
</ul>
<div id="serach-part" v-show="show"><input type="search" id="search" :placeholder="placeholder" class="easyUtil-input"><button id="searchBtn" class="easyUtil-btn">{{btn}}</button></div>
</nav>
var head = new Vue({
el : "#head",
data : {
//此處省略一千字
show : true
},
mounted : function(){
//可用于設置自適應屏幕,根據獲得的可視寬度(兼容性)判斷是否顯示
let w = document.documentElement.offsetWidth || document.body.offsetWidth;
if(w < 1000){
this.show = false;
}
})
我的目的是在移動設備中不顯示搜索欄(search-part)部分,那么利用v-show,和mounted配合,在掛載時檢測一下屏幕可視寬度,如果小于1000,則認為是手機,v-show設為false,不顯示即可。
看,很簡單吧,簡單到我覺得自己好像在忽悠。其實到這里,原理已經說完,具體的應用大家可以自行發揮,而且也不一定就用v-show,我這里是為了顯示與否,如果大家想添加樣式什么的,還可以寫別的,甚至于計算屬性,watch都可以。只要記住在掛載的時候完成即可,不然頁面會有跳動,不利于體驗。
可能有人會問,用css的@media就可以完成了,為啥用js,我這里想說的是,我并沒有否認@media,這里只是寫出更多一種方式,同時結合一下現在很火的前端框架。多一種方法,就多一種解決思路,不至于再回到以前"只能這樣"的道路上。具體到實際應用中,當然是最適合的方法為主。前端水深,前端的路子也越來越多,越來也豐富,敞開思維,就會看見不同的天空。
ps一句,js確實需要刷新頁面重新加載才會顯示,也就是說如果用戶將頁面從大屏移動到小屏幕,就可能出現布局不響應問題,但是在實際使用中,這種情況幾乎不會出現,因為用戶不能可能將電腦打開的網頁,直接移動到手機上,操作永遠都是重新打開,所以js,css在顯示效果上是沒有區別的(當然如果js太過復雜,性能會有影響)。另外,文中方法的兼容性問題,只要支持Vue的瀏覽器,都沒問題。
就說到這吧,歡迎大神指正,不勝感激!
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務。
如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里
1、用px2rem配合lib-flexible,讓網頁適配。
lib-flexible
作用:讓網頁根據設備dpr和寬度,利用viewport和html根元素的font-size配合rem來適配不同尺寸的移動端設備
安裝:
npm install lib-flexible
1
引入:入口文件main.js中:
import "lib-flexible/flexible.js"
1
2、手寫一個js小工具,省略rem的計算,加快開發速度。
在src目錄下增加一個utils目錄,在里面新建一個js文件,寫入以下內容:
// 基準大小
const baseSize = 32
// 設置 rem 函數
function setRem () {
// 當前頁面寬度相對于 750 寬的縮放比例,可根據自己需要修改。
const scale = document.documentElement.clientWidth / 750
// 設置頁面根節點字體大小
document.documentElement.style.fontSize = (baseSize * Math.min(scale, 2)) + 'px'
}
// 初始化
setRem()
// 改變窗口大小時重新設置 rem
window.onresize = function () {
setRem()
}
在main.js中引入改js文件:
import "./utils/rem"
1
然后就可以直接用px寫頁面啦,而不用去計算rem的值,是不是很舒服呢。
3、使用VW。了解下vw 與 vh單位,以viewport為基準,1vw 與 1vh分別為window.innerWidth 與 window.innerHeight的百分之一
安裝:
npm i postcss-px-to-viewport -save -dev
1
在package.json中配置如下:
"postcss": {
"plugins": {
"autoprefixer": {},
"postcss-pxtorem": {
"rootValue": 32,
"propList": ["*"]
}
},
"plugins": {
"autoprefixer": {},
"postcss-px-to-viewport": {
"viewportWidth": 750,
"minPixelValue": 1
}
}
},
4、利用bootstrap實現響應式圖片
在 Bootstrap 版本 3 中,通過為圖片添加 .img-responsive 類可以讓圖片支持響應式布局。其實質是為圖片設置了 max-width: 100%;、 height: auto; 和 display: block; 屬性,從而讓圖片在其父元素中更好的縮放。
對于圖片的大小限制一定要在圖片的父級元素進行限制。
5、利用bootstrap的柵格系統,下面列一下柵格系統的參數:
超小屏手機 (<768px) 小屏幕平板(>=768px) 中等屏桌面(>=992px) 大屏桌面(>=1200px)
類前綴 .col-xs .col-sm .col-md .col-lg
列數 12 12 12 12
.container最大寬度 None(自動) 750px 970px 1170px
舉個移動設備和桌面的例子:
<!-- Stack the columns on mobile by making one full-width and the other half-width -->
<div class="row">
<div class="col-xs-12 col-md-8">.col-xs-12 .col-md-8</div>
<div class="col-xs-6 col-md-4">.col-xs-6 .col-md-4</div>
</div>
<!-- Columns start at 50% wide on mobile and bump up to 33.3% wide on desktop -->
<div class="row">
<div class="col-xs-6 col-md-4">.col-xs-6 .col-md-4</div>
<div class="col-xs-6 col-md-4">.col-xs-6 .col-md-4</div>
<div class="col-xs-6 col-md-4">.col-xs-6 .col-md-4</div>
</div>
<!-- Columns are always 50% wide, on mobile and desktop -->
<div class="row">
<div class="col-xs-6">.col-xs-6</div>
<div class="col-xs-6">.col-xs-6</div>
</div>
還有更多對響應式的支持,就不一一列舉了。
如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里
Bootstrap:
1. 概念: 一個前端開發的框架,Bootstrap,來自 Twitter,是目前很受歡迎的前端框架。Bootstrap 是基于 HTML、CSS、JavaScript 的,它簡潔靈活,使得 Web 開發更加快捷。
* 框架:一個半成品軟件,開發人員可以在框架基礎上,在進行開發,簡化編碼。
* 好處:
1. 定義了很多的css樣式和js插件。我們開發人員直接可以使用這些樣式和插件得到豐富的頁面效果。
2. 響應式布局。
* 同一套頁面可以兼容不同分辨率的設備。
2. 快速入門
1. 下載Bootstrap
2. 在項目中將這三個文件夾復制
3. 創建html頁面,引入必要的資源文件
3.演示案例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3個meta標簽*必須*放在最前面,任何其他內容都*必須*跟隨其后! -->
<title>Bootstrap HelloWorld</title>
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依賴 jQuery,所以必須放在前邊) -->
<script src="js/jquery-3.3.1.min.js"></script>
<!-- 加載 Bootstrap 的所有 JavaScript 插件。你也可以根據需要只加載單個插件。 -->
<script src="js/bootstrap.min.js"></script>
</head>
<body>
<h1>你好,世界!</h1>
</body>
</html>
響應式布局
同一套頁面可以兼容不同分辨率的設備。
* 實現:依賴于柵格系統:將一行平均分成12個格子,可以指定元素占幾個格子
* 步驟:
1. 定義容器。相當于之前的table、
* 容器分類:
1. container:兩邊留白
2. container-fluid:每一種設備都是100%寬度
2. 定義行。相當于之前的tr 樣式:row
3. 定義元素。指定該元素在不同的設備上,所占的格子數目。樣式:col-設備代號-格子數目
* 設備代號:
1. xs:超小屏幕 手機 (<768px):col-xs-12
2. sm:小屏幕 平板 (≥768px)
3. md:中等屏幕 桌面顯示器 (≥992px)
4. lg:大屏幕 大桌面顯示器 (≥1200px)
* 注意:
1. 一行中如果格子數目超過12,則超出部分自動換行。
2. 柵格類屬性可以向上兼容。柵格類適用于與屏幕寬度大于或等于分界點大小的設備。
3. 如果真實設備寬度小于了設置柵格類屬性的設備代碼的最小值,會一個元素沾滿一整行。
CSS樣式和JS插件
1. 全局CSS樣式:
* 按鈕:class="btn btn-default"
* 圖片:
* class="img-responsive":圖片在任意尺寸都占100%
* 圖片形狀
* <img src="..." alt="..." class="img-rounded">:方形
* <img src="..." alt="..." class="img-circle"> : 圓形
* <img src="..." alt="..." class="img-thumbnail"> :相框
* 表格
* table
* table-bordered
* table-hover
* 表單
* 給表單項添加:class="form-control"
2. 組件:
* 導航條
* 分頁條
3. 插件:
* 輪播圖
演示案例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- 上述3個meta標簽*必須*放在最前面,任何其他內容都*必須*跟隨其后! -->
<title>Bootstrap HelloWorld</title>
<!-- Bootstrap -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- jQuery (Bootstrap 的所有 JavaScript 插件都依賴 jQuery,所以必須放在前邊) -->
<script src="js/jquery-3.3.1.min.js"></script>
<!-- 加載 Bootstrap 的所有 JavaScript 插件。你也可以根據需要只加載單個插件。 -->
<script src="js/bootstrap.min.js"></script>
<style>
.paddtop{
padding-top: 10px;
}
.search-btn{
float: left;
border:1px solid #ffc900;
width: 90px;
height: 35px;
background-color:#ffc900 ;
text-align: center;
line-height: 35px;
margin-top: 15px;
}
.search-input{
float: left;
border:2px solid #ffc900;
width: 400px;
height: 35px;
padding-left: 5px;
margin-top: 15px;
}
.jx{
border-bottom: 2px solid #ffc900;
padding: 5px;
}
.company{
height: 40px;
background-color: #ffc900;
text-align: center;
line-height:40px ;
font-size: 8px;
}
</style>
</head>
<body>
<!-- 1.頁眉部分-->
<header class="container-fluid">
<div class="row">
<img src="img/top_banner.jpg" class="img-responsive">
</div>
<div class="row paddtop">
<div class="col-md-3">
<img src="img/logo.jpg" class="img-responsive">
</div>
<div class="col-md-5">
<input class="search-input" placeholder="請輸入線路名稱">
<a class="search-btn" href="#">搜索</a>
</div>
<div class="col-md-4">
<img src="img/hotel_tel.png" class="img-responsive">
</div>
</div>
<!--導航欄-->
<div class="row">
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<!-- 定義漢堡按鈕 -->
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">首頁</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
<li><a href="#">Link</a></li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
</div>
<!--輪播圖-->
<div class="row">
<div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>
<li data-target="#carousel-example-generic" data-slide-to="1"></li>
<li data-target="#carousel-example-generic" data-slide-to="2"></li>
</ol>
<!-- Wrapper for slides -->
<div class="carousel-inner" role="listbox">
<div class="item active">
<img src="img/banner_1.jpg" alt="...">
</div>
<div class="item">
<img src="img/banner_2.jpg" alt="...">
</div>
<div class="item">
<img src="img/banner_3.jpg" alt="...">
</div>
</div>
<!-- Controls -->
<a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
</header>
<!-- 2.主體部分-->
<div class="container">
<div class="row jx">
<img src="img/icon_5.jpg">
<span>黑馬精選</span>
</div>
<div class="row paddtop">
<div class="col-md-3">
<div class="thumbnail">
<img src="img/jiangxuan_3.jpg" alt="">
<p>上海直飛三亞5天4晚自由行(春節預售+親子/蜜月/休閑游首選+豪華酒店任選+接送機)</p>
<font color="red">¥ 699</font>
</div>
</div>
<div class="col-md-3">
<div class="thumbnail">
<img src="img/jiangxuan_3.jpg" alt="">
<p>上海直飛三亞5天4晚自由行(春節預售+親子/蜜月/休閑游首選+豪華酒店任選+接送機)</p>
<font color="red">¥ 699</font>
</div>
</div>
<div class="col-md-3">
<div class="thumbnail">
<img src="img/jiangxuan_3.jpg" alt="">
<p>上海直飛三亞5天4晚自由行(春節預售+親子/蜜月/休閑游首選+豪華酒店任選+接送機)</p>
<font color="red">¥ 699</font>
</div>
</div>
<div class="col-md-3">
<div class="thumbnail">
<img src="img/jiangxuan_3.jpg" alt="">
<p>上海直飛三亞5天4晚自由行(春節預售+親子/蜜月/休閑游首選+豪華酒店任選+接送機)</p>
<font color="red">¥ 699</font>
</div>
</div>
</div>
<div class="row jx">
<img src="img/icon_6.jpg">
<span>國內游</span>
</div>
<div class="row paddtop">
<div class="col-md-4">
<img src="img/guonei_1.jpg">
</div>
<div class="col-md-8">
<div class="row">
<div class="col-md-4">
<div class="thumbnail">
<img src="img/jiangxuan_3.jpg" alt="">
<p>上海直飛三亞5天4晚自由行(春節預售+親子/蜜月/休閑游首選+豪華酒店任選+接送機)</p>
<font color="red">¥ 699</font>
</div>
</div>
<div class="col-md-4">
<div class="thumbnail">
<img src="img/jiangxuan_3.jpg" alt="">
<p>上海直飛三亞5天4晚自由行(春節預售+親子/蜜月/休閑游首選+豪華酒店任選+接送機)</p>
<font color="red">¥ 699</font>
</div>
</div>
<div class="col-md-4">
<div class="thumbnail">
<img src="img/jiangxuan_3.jpg" alt="">
<p>上海直飛三亞5天4晚自由行(春節預售+親子/蜜月/休閑游首選+豪華酒店任選+接送機)</p>
<font color="red">¥ 699</font>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="thumbnail">
<img src="img/jiangxuan_3.jpg" alt="">
<p>上海直飛三亞5天4晚自由行(春節預售+親子/蜜月/休閑游首選+豪華酒店任選+接送機)</p>
<font color="red">¥ 699</font>
</div>
</div>
<div class="col-md-4">
<div class="thumbnail">
<img src="img/jiangxuan_3.jpg" alt="">
<p>上海直飛三亞5天4晚自由行(春節預售+親子/蜜月/休閑游首選+豪華酒店任選+接送機)</p>
<font color="red">¥ 699</font>
</div>
</div>
<div class="col-md-4">
<div class="thumbnail">
<img src="img/jiangxuan_3.jpg" alt="">
<p>上海直飛三亞5天4晚自由行(春節預售+親子/蜜月/休閑游首選+豪華酒店任選+接送機)</p>
<font color="red">¥ 699</font>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 3.頁腳部分-->
<footer class="container-fluid">
<div class="row">
<img src="img/footer_service.png" class="img-responsive">
</div>
<div class="row company">
CSDN博客楊校老師 版權所有Copyright 2017-2019, All Rights Reserved 魯ICP備19007759號-1
</div>
</footer>
</body>
</html>
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務。
藍藍設計的小編 http://www.syprn.cn