如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里
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界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務。
如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里
有這樣一種常見的需求:有一個搜索框,需要根據用戶的輸入進行實時的查詢。也就是說用戶每輸入一個字符就要發送一次請求。
想到的做法是監聽輸入框的keyup時間然后在回調里發送異步請求。
這樣做的不足也很明顯:
其實我們并不需要用戶每次輸入時都發送請求,這樣會給服務器造成不必要的壓力。
因為發送的是異步請求,有可能查詢的結果和最后輸入的內容并不匹配。
如何解決以上兩種問題呢? 有兩種解決方案
首先我們規定當用戶停止輸入1秒(具體時間根據自己需求而定)后再根據輸入框的值發送請求。
其次我們利用定時器來解決以上問題。
第一種方案:直接看代碼吧
vat timer
$('.input').on('keyup', function(e) {
clearTimeout(timer)
timer = setTimeout(function() {
// do something
}, 1000)
})
首先定義一個定時器timer
監聽輸入框的keyup事件,在回調函數里先清除timer,這一步總能保證在用戶停止輸入1秒后執行最后一個timer。如果用戶輸入的間隔小于1秒就不會執行timer
這么寫似乎不太抽象,而且定義了一個全局變量timer,不友好!稍加改動一下:
function debounce(func,delay){
var timer
return function(){
clearTimeout(timer)
var event = arguments[0] // 獲取原生event參數
timer = setTimeout(function(){
func(event)
},delay)
}
}
function handle(event){
// do something
}
$('.input').on('keyup', debounce(handle, 1000))
這樣是不是復用性更高,我們只需要在handle函數中寫我們的處理邏輯就可以了。而且沒有了全局變量,避免了全局污染的可能??!
*第二種方案: *
var lastTime
$('.input').on('keyup', function(e) {
lastTime = e.timeStamp
setTimeout(function() {
console.log('timeout')
if (lastTime == e.timeStamp) {
// do something
}
}, 1000)
})
首先定義一個時間戳來保存最后一次輸入的時間
然后1秒后在定時器里判斷保存的時間戳和觸發事件的時間戳e.timeStamp是否相同,只要1秒內又輸入了內容,e.timeStamp就回變化。
但是這種寫法有個弊端,用戶鍵入幾次就會執行幾次setTimeout,也就是說當用戶連續鍵入多個字符后,會有多個任務被推入待執行隊列,然后每隔1秒執行,只是在執行的時候判斷要不要發送異步請求,這種方式不會發送多余的異步請求,但是會執行多余的任務,這無疑浪費了性能。
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務。
如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里
DOM樹
在訪問頁面時,需要與頁面中的元素進行交互式的操作。在操作中,元素的訪問是最頻繁、最常用的,主要包括對元素屬性、內容、值CSS的操作。
一、操作元素的屬性
attr() prop() 獲取或設置元素的屬性值
兩者區別:簡單來說,對于HTML元素本身就帶有的固有屬性,在處理時,使用prop方法。對于HTML元素我們自己自定義的DOM屬性,在處理時,使用attr方法。
針對屬性對象不同
prop( )是針對Dom元素屬性,attr( )針對HTML元素屬性,和attribute與property區別一樣。
用于設置的屬性值類型不同
attr()函數操作的是文檔節點的屬性,因此設置的屬性值只能是字符串類型,如果不是字符串類型,也會調用其toString()方法,將其轉為字符串類型。
prop()函數操作的是JS對象的屬性,因此設置的屬性值可以為包括數組和對象在內的任意類型。
應用版本不同
attr()是jQuery 1.0版本就有的函數,prop()是jQuery 1.6版本新增的函數。毫無疑問,在1.6之前,你只能使用attr()函數;1.6及以后版本,你可以根據實際需要選擇對應的函數。
其他不同
對于表單元素的checked、selected、disabled等屬性,Attr()方法拿不到值,請使用prop()函數來設置或獲取checked、selected、disabled等屬性。對于其它能夠用prop()實現的操作,也盡量使用prop()函數。如下圖代碼:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script src="js/jquery-1.9.1.min.js"></script>
</head>
<body>
<input type="button" id="btn1" value="按鈕">
<input type="button" id="btn2" value="按鈕">
<script>
//操作元素的屬性
//attr() prop()獲取或設置元素的屬性值
$("#btn1").attr("value","按鈕1");//將#btn1的value值改為按鈕1
$("#btn1").prop("value","按鈕2");//將#btn1的value值改為按鈕2
console.log( $("input[type='button']").prop("value"));//獲取#btn1的value值,輸出為按鈕2
console.log($("#btn2").attr("value"));//獲取#btn1的value值,輸出為按鈕
//設置多個屬性值
$("input[type='button']").prop({
width:"200px",
value:"hello"
});//同時設置寬度為100px,value值為hello
//根據輸出結果,width值設置失敗,value值設置成功
console.log($("input[type='button']").prop("width"));//0
console.log($("input[type='button']").attr("width"));//0
$("input[type='button']").attr({
width:"200px",
value:"HELLO"
})//同時設置寬度為200px,value值為HELLO
//根據輸出結果可以看到,width和value均設置成功
console.log($("input[type='button']").prop("width"));//0
console.log($("input[type='button']").attr("width"));//200px
// var btn=$("input[type='button']");
// btn.attr("data-src","pink");
// console.log(btn.attr("data-src"));//pink
// console.log(btn.prop("data-src"));//undefined
var btn=$("input[type='button']");
btn.prop("data-src","pink");
console.log(btn.attr("data-src"));//undefined
console.log(btn.prop("data-src"));//pink
</script>
二、刪除元素的屬性
removeAttr( name ) ,其中name為元素屬性的名稱
removeProp( name ) ,其中name為元素屬性的名稱
三、元素內容的操作
在JQuery中,操作元素內容的方法包括html( )和text( )。前者與JavaScript中的innerHTML屬性類似,即獲取或設置元素的HTML內容;后者類似于JavaScript中的innerText屬性,即獲取或設置元素的文本內容。區別如下:
語法格式 參數說明 功能描述
html() 無參數 用于獲取元素的HTML內容
html(val) val參數為元素的HTML內容 用于設置元素的HTML內容
text() 無參數 用于獲取元素 的文本內容
text(val) val參數為元素的文本內容 用于設置元素的文本內容
<script>
//js中的寫法 innerHTML innerText
var sd=document.getElementById("block");
sd.innerText="小貓吃魚";
console.log(sd.innerHTML);//小貓吃魚
console.log(sd.innerText);//小貓吃魚
// //jquery html() text() 和js一致 獲取或設置元素的html值或文本值
console.log($("#block").html());//小貓吃魚
console.log($("#block").text());//小貓吃魚
$("#block").text("小貓抓老鼠");//修改innerText內容
console.log($("#block").html());//小貓抓老鼠
console.log($("#block").text());//小貓抓老鼠
$("#block").html("小貓吃肉肉");//修改innerHTML內容
console.log($("#block").html());//小貓吃肉肉
console.log($("#block").text());//小貓吃肉肉
</script>
四、操作表單元素的值
val() 獲取或設置表單元素的value值
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script src="js/jquery-1.9.1.min.js"></script>
</head>
<body>
<input type="text" id="txt" value="請輸入...">
<script>
console.log( $("#txt").val());// 獲取#txt的value值 輸出為:請輸入...
$("#txt").val("12345");//修改#txt的value值為12345
console.log( $("#txt").val());//12345
</script>
</body>
</html>
五、元素樣式的操作
1.直接設置元素樣式值
在JQuery中,通過css()方法為某個指定的元素設置樣式值,語法格式如下:
css(name,value) ,其中name為樣式名稱,value為樣式的值
css()可以設置樣式也可以獲取樣式
2.增加CSS類別
通過addClass()方法增加元素類別的名稱,語法格式如下:
addClass(class) ,其中參數class為類名稱,可以同時增加多個,用空格隔開即可,如addClass(class0 class1 class2 ...)
3.刪除CSS類別
與addClass()方法相對應,removeClass()方法用于刪除類別,語法格式與addClass()相同,如果不設定參數,則刪除元素中的所有類名稱
4.類別切換
通過toggleClass()方法切換不同的元素類別,語法格式如下:
toggleClass(class) ,其中參數class為類別名稱,其功能是當元素中含有名稱為class的CSS類別時,刪除該類別,若沒有,則增加該類別
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script src="js/jquery-1.9.1.min.js"></script>
</head>
<body>
<button id="btn" class="btndata">按鈕</button>
<script>
$("#btn").addClass("btn1");//追加一個類名稱
$("#btn").addClass("btn2 btn3");//追加多個類名稱
$("#btn").removeClass("btn2 btn1");//移除類名稱
$("#btn").removeClass();//移除所有類名稱
$("#btn").toggleClass("btn1");//類的切換 toggleClass() 如果有類名稱則替換 如果沒有就添加
</script>
</body>
</html>
六、jquery操作子父節點
children() 找父元素里面的子節點
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script src="js/jquery-1.9.1.min.js"></script>
</head>
<body>
<ul>
<li class="lilist">1</li>
<li class="lidata">2</li>
<span>6</span>
<li class="lilist">3</li>
<span>5</span>
<li class="lilist">4</li>
<span>7</span>
</ul>
<script>
console.log($("ul").children());//輸出ul 下的所有子節點
console.log($("ul").children()[0]);//輸出ul下索引為0的子節點
console.log($("ul>li").first());//輸出ul里面第一個li
console.log($("ul>li").last());//輸出ul里面最后一個li
console.log($("ul>li").eq(2));//eq() 根據索引找元素
console.log($("ul>li").first().siblings(".lilist"));//找同胞元素 輸出和first()相同類名稱的元素
console.log($("ul>li").eq(1).prev());//找當前元素的前一個元素
console.log($("ul>li").eq(2).prevAll("span"));//當前元素前面的所有指定元素
console.log($("ul>li").eq(2).prevAll());//當前元素前面的所有元素
console.log($("ul>li").eq(1).next());//找當前元素的下一個元素
console.log($("ul>li").eq(1).nextAll("li"));//當前元素后面的所有指定元素
console.log($("ul>li").eq(1).nextAll());//當前元素后面的所有元素
console.log($("ul>li").eq(0).is(".qq"));//is() 判斷當前對象是誰 輸出true or false 當前元素與類名稱相符 輸出true
</script>
</body>
</html>
七、JQuery中的尺寸問題
下面以高度為例進行說明
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script src="js/jquery-1.9.1.min.js"></script>
<style>
.ss{
width: 200px;
height: 200px;
margin: 10px 10px;
padding: 20px 20px;
}
</style>
</head>
<body>
<div class="ss"></div>
<script>
console.log($(".ss").height());//200 可視區域 不包括內外邊距
console.log($(".ss").innerHeight());//240 包括內邊距的距離
console.log($(".ss").outerHeight());//240 包括內邊距的距離
</script>
</body>
</html>
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務。
如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里
1、大家都知道vue是一種單頁應用,單頁應用就是僅在頁面初始化的時候加載相應的html/css/js一單頁面加載完成,不會因為用戶的操作而進行頁面的重新加載或者跳轉,用javascript動態的變化html的內容
優點: 良好的交互體驗,用戶不需要刷新頁面,頁面顯示流暢, 良好的前后端工作分離模式,減輕服務器壓力,
缺點: 不利于SEO,初次加載耗時比較多
2、hash模式
vue-router默認的是hash模式—使用URL的hash來模擬一個完整的URL,于是當URL改變的時候,頁面不會重新加載,也就是單頁應用了,當#后面的hash發生變化,不會導致瀏覽器向服務器發出請求,瀏覽器不發出請求就不會刷新頁面,并且會觸發hasChange這個事件,通過監聽hash值的變化來實現更新頁面部分內容的操作
對于hash模式會創建hashHistory對象,在訪問不同的路由的時候,會發生兩件事:
HashHistory.push()將新的路由添加到瀏覽器訪問的歷史的棧頂,和HasHistory.replace()替換到當前棧頂的路由
3、history模式
主要使用HTML5的pushState()和replaceState()這兩個api來實現的,pushState()可以改變url地址且不會發送請求,replaceState()可以讀取歷史記錄棧,還可以對瀏覽器記錄進行修改
window.history.pushState(stateObject, title, URL)
window.history.replaceState(stateObject, title, URL)
包括back,forward , go 三個方法
history.go(-2);//后退兩次
history.go(2);//前進兩次
history.back(); //后退
hsitory.forward(); //前進
區別:
前面的hashchange,你只能改變#后面的url片段。而pushState設置的新URL可以是與當前URL同源的任意URL。
history模式則會將URL修改得就和正常請求后端的URL一樣,如后端沒有配置對應/user/id的路由處理,則會返回404錯誤
參考于: https://www.cnblogs.com/ceceliahappycoding/p/10552620.html
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務。如果您想訂閱本博客內容,每天自動發到
前言
在此之前,已經實現了vue+ElementUI的跨域查詢并渲染查詢結果的功能,現在想要在每一行中添加修改和刪除的按鈕。于是乎就需要獲取當前行的數據,于是就有了下面兩種方式的獲取。
1 獲取當前行的數據
1.1 我的笨辦法
這里是我記錄自己的學習過程,這個方法也能實現,但是麻煩,如果您只是為了尋找最終方案,請直接查看1.2章節。
首先我查看了官方文檔,打算使用對話框來渲染修改頁面和刪除警告頁面。這個實現起來很簡單,就是對按鈕綁定一個click事件,然后控制對話框的顯示和隱藏:
<el-table @row-click="handleEdit" :data="dengmiQueryForm.list" stripe border width="100%" height="350">
<el-table-column prop="mimian" label="謎面" width="300" fixed="left">
</el-table-column>
<el-table-column prop="dengmiSeq" label="序號">
</el-table-column>
<el-table-column prop="mimu" label="謎目">
</el-table-column>
<el-table-column prop="mige" label="謎格">
</el-table-column>
<el-table-column prop="midi" label="謎底">
</el-table-column>
<el-table-column prop="zuozhe" label="作者">
</el-table-column>
<el-table-column prop="mizhu" label="注">
</el-table-column>
<el-table-column prop="shangxi" label="賞析">
</el-table-column>
<el-table-column prop="leixing" label="類型">
</el-table-column>
<el-table-column label="操作" fixed="right" width="200px">
<el-col :span="10">
<el-tooltip effect="dark" content="編輯當前行" placement="top">
<el-button size="mini" @click="dengmiQueryForm.dialogVisible = true">編輯</el-button>
</el-tooltip>
</el-col>
</el-table-column>
</el-table>
<div style="margin-top: 5px;"></div><!--這個只是為了在頁面上顯示間隔-->
<el-dialog title="編輯燈謎" :visible.sync="dengmiQueryForm.dialogVisible">
<el-form :model="modifyForm">
<el-form-item label="謎面" :label-width="modifyForm.formLabelWidth">
<el-input v-model="modifyForm.mimian" auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="謎目" :label-width="modifyForm.formLabelWidth">
<el-input v-model="modifyForm.mimu" auto-complete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dengmiQueryForm.dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="dengmiQueryForm.dialogVisible = false">確 定</el-button>
</div>
</el-dialog>
<script>
export default {
name: "dengmiQuery",
comments: {
DengmiModify
},
data() {
return {
modifyForm:{
formLabelWidth:'120px',
mimian:'',
mimu:''
},
dengmiQueryForm: {
dialogDeleteVisible:false,
dialogVisible: false,
list: []
}
};
},
methods: {
submitForm(formName) {
console.log(formName.mimu);
this.$http.get('http://localhost:909/dengmi/showDengmi2').then(function (success) {
console.log("This request is succeed! Here is the response:");
this.dengmiQueryForm.list = success.body.result;
this.dengmiQueryForm.requestResult = true;
}, function (error) {
console.log("This request is failed! Here is the response:");
console.log(error);
this.dengmiQueryForm.requestResult = false;
})
},
handleEdit(row) {
this.dengmiQueryForm.deleteShow = row.mimian + "(" + row.mimu + ")" + row.midi + "/" + row.zuozhe;
this.modifyForm.mimian=row.mimian;
this.modifyForm.mimu=row.mimu;
}
}
}
</script>
如上代碼,是在el-table標簽上綁定了行單擊事件*@row-click=“handleEdit”*,該方法的參數row即為當前行的數據。
在handleEdit方法中,通過對data中的參數賦值,然后新增窗口中通過使用data中的參數來獲取當前行的數據,從而實現將當前行的數據傳遞到新的對話框中。
這個方法雖然也能實現需求,但是比較麻煩:當有別的操作的時候,比如我再添加一個刪除操作,就需要在點擊刪除按鈕的時候,獲取當前行的數據,然后進行刪除操作;而因為新增和刪除使用的是不同的對話框,其取值也是要通過handleEdit方法來獲取,因此,當按鈕較多,或者當前行的字段值較多的時候,就需要在handleEdit中對許多許多的變量進行賦值,而且是對所有按鈕的所有參數。這個工作量想想還是挺恐怖的。
1.2 使用slot-scope獲取數據
slot-scope是屬于VUE的東東,叫做插槽;至于插槽是個什么東東,來戳這里。
在操作列,對操作按鈕先用帶有slot-scope屬性的dom進行包裝,即可獲取當前行的數據,具體的代碼,除了操作列不同外,還需要刪除el-table標簽中綁定的*@row-click*方法,剩下的都一樣:
<el-table-column label="操作嘗試2">
<template slot-scope="scope">
<el-button type="text" @click="checkDetail(scope.row)">查看詳情</el-button>
</template>
</el-table-column>
<script>
export default {
name: "dengmiQuery",
data() {
return {
modifyForm:{
formLabelWidth:'120px',
mimian:'',
mimu:''
},
dengmiQueryForm: {
dialogVisible: false,
list: [],
}
};
},
methods: {
checkDetail(val){
console.log(val)
}
}
}
</script>
通過<template slot-scope=“scope”>來定義當前行的數據對象,然后通過scope.row來獲取當前行的數據。
全部代碼
<template>
<div>
<el-form :model="dengmiQueryForm" ref="dengmiQueryForm" label-width="100px" class="demo-ruleForm" size="mini">
<el-row>
<el-col span="8">
<el-form-item label="謎面">
<el-input v-model="dengmiQueryForm.mimian"></el-input>
</el-form-item>
</el-col>
<el-col span="8">
<el-form-item label="謎目">
<el-input v-model="dengmiQueryForm.mimu"></el-input>
</el-form-item>
</el-col>
<el-col span="8">
<el-form-item label="謎格">
<el-input v-model="dengmiQueryForm.mige"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col span="8">
<el-form-item label="謎底">
<el-input v-model="dengmiQueryForm.midi"></el-input>
</el-form-item>
</el-col>
<el-col span="8">
<el-form-item label="作者">
<el-input v-model="dengmiQueryForm.zuozhe"></el-input>
</el-form-item>
</el-col>
<el-col span="8">
<el-form-item label="謎底字數">
<el-input v-model="dengmiQueryForm.midiLength"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col>
<el-button type="primary" @click="submitForm" icon="el-icon-search">查詢</el-button>
<el-button type="warning" @click="resetForm" icon="el-icon-search" plain>重置</el-button>
</el-col>
</el-row>
</el-form>
<el-header></el-header>
<div v-if="dengmiQueryForm.requestResult">
<el-table :data="dengmiQueryForm.list.slice((dengmiQueryForm.currentPage-1)*dengmiQueryForm.pagesize,dengmiQueryForm.currentPage*dengmiQueryForm.pagesize)"
stripe border width="100%" height="350">
<el-table-column type="index" fixed="left"></el-table-column>
<el-table-column prop="mimian" label="謎面" width="300" fixed="left">
</el-table-column>
<el-table-column prop="dengmiSeq" label="序號">
</el-table-column>
<el-table-column prop="mimu" label="謎目">
</el-table-column>
<el-table-column prop="mige" label="謎格">
</el-table-column>
<el-table-column prop="midi" label="謎底">
</el-table-column>
<el-table-column prop="zuozhe" label="作者">
</el-table-column>
<el-table-column prop="mizhu" label="注">
</el-table-column>
<el-table-column prop="shangxi" label="賞析">
</el-table-column>
<el-table-column prop="leixing" label="類型">
</el-table-column>
<el-table-column label="操作" fixed="right" width="200px">
<el-row>
<el-col :span="10">
<el-tooltip effect="dark" content="編輯當前行" placement="top">
<el-button size="mini" @click="dengmiQueryForm.dialogVisible = true">編輯</el-button>
</el-tooltip>
</el-col>
<el-col :span="10">
<el-tooltip effect="light" content="刪除當前行" placement="top">
<el-button size="mini" @click="dengmiQueryForm.dialogDeleteVisible = true" type="danger" plain>刪除</el-button>
</el-tooltip>
</el-col>
</el-row>
</el-table-column>
<el-table-column label="操作嘗試2">
<template slot-scope="scope">
<el-button type="text" @click="checkDetail(scope.row)">查看詳情</el-button>
</template>
</el-table-column>
</el-table>
<div style="margin-top: 5px;"></div>
<el-pagination
prev-text="上一頁"
next-text="下一頁"
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="dengmiQueryForm.currentPageA"
:page-sizes="[5,10,50,100]"
:page-size="5"
layout="total, sizes, prev, pager, next, jumper"
:total="dengmiQueryForm.list.length">
</el-pagination>
</div>
<div v-else>
請求失??!
</div>
<el-dialog title="編輯燈謎" :visible.sync="dengmiQueryForm.dialogVisible">
<el-form :model="modifyForm">
<el-form-item label="謎面" :label-width="modifyForm.formLabelWidth">
<el-input v-model="modifyForm.mimian" auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="謎目" :label-width="modifyForm.formLabelWidth">
<el-input v-model="modifyForm.mimu" auto-complete="off"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dengmiQueryForm.dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="dengmiQueryForm.dialogVisible = false">確 定</el-button>
</div>
</el-dialog>
<el-dialog title="刪除燈謎" :visible.sync="dengmiQueryForm.dialogDeleteVisible">
<h1><span style="color: red"><strong>確定刪除該行數據?刪除后不可恢復!</strong></span></h1>
<el-form>
<el-form-item label="當前行數據">
<el-col :span="18">
<el-input v-model="dengmiQueryForm.deleteShow" readonly></el-input>
</el-col>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dengmiQueryForm.dialogDeleteVisible = false">取 消</el-button>
<el-button type="primary" @click="dengmiQueryForm.dialogDeleteVisible = false">確 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
name: "dengmiQuery",
data() {
return {
modifyForm:{
formLabelWidth:'120px',
mimian:'',
mimu:''
},
dengmiQueryForm: {
deleteShow:'',
dialogDeleteVisible:false,
dialogVisible: false,
currentRow: null,
visibleA: false,
currentPage: 1, //初始頁
pagesize: 5, // 每頁的數據
currentPageA: 1,
mimian: '',
mimu: '',
mige: '',
midi: '',
zuozhe: '',
midiLength: '',
list: [],
requestResult: true,
thisRowData:{}
}
};
},
methods: {
submitForm(formName) {
console.log(formName.mimu);
this.$http.get('http://localhost:909/dengmi/showDengmi2').then(function (success) {
console.log("This request is succeed! Here is the response:");
this.dengmiQueryForm.list = success.body.result;
this.dengmiQueryForm.requestResult = true;
}, function (error) {
console.log("This request is failed! Here is the response:");
console.log(error);
this.dengmiQueryForm.requestResult = false;
})
},
resetForm(formName) {
this.$refs[formName].resetFields();
},
handleSizeChange(size) {
this.dengmiQueryForm.pagesize = size;
console.log(this.dengmiQueryForm.pagesize) //每頁下拉顯示數據
},
handleCurrentChange(currentPage) {
this.dengmiQueryForm.currentPage = currentPage;
console.log(this.dengmiQueryForm.currentPage) //點擊第幾頁
},
handleEdit(row) {
this.dengmiQueryForm.deleteShow = row.mimian + "(" + row.mimu + ")" + row.midi + "/" + row.zuozhe;
// this.dengmiQueryForm.currentRow = row;
console.log(this.dengmiQueryForm.deleteShow);
this.modifyForm.mimian=row.mimian;
this.modifyForm.mimu=row.mimu;
// console.log("event=" + event);
// console.log(colunm)
},
handleClose(done) {
this.$confirm('確認關閉?')
.then(_ => {
done();
})
.catch(_ => {});
},
checkDetail(val){
console.log(val)
}
}
}
</script>
<style scoped>
</style>
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務。
如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里
現在我有如下需求,子組件 <user /> 中此時有一條用戶的信息(userInfo);我要在父組件通過插槽展示這個用戶的姓名(userInfo.name);
注意:這里的父組件并沒有這個用戶的信息,子組件中有,如果直接在父組件{{userInfo.name}} 獲取這條信息是獲取不到的;因為,只有 <user /> 組件可以訪問到 userInfo,而我們提供的內容是在父組件渲染的;
模板在哪寫,就是用哪里的變量,跟插槽用在哪無關
模板是在父組件中寫好,被編譯過后,傳到子組件的插槽中的
為了讓父組件的插槽內容可以讀取到子組件的數據,我們可以將userInfo 作為一個 <slot> 元素的特性綁定上去;
// 子組件
const card = {
data() {
return {
userInfo: {name: '宮鑫'}
}
},
template: `
<div class='card'>
<!-- 在插槽上綁定子組件的數據 -->
<slot :userInfo="userInfo"/>
</div>
`
};
綁定在 元素上的特性被稱為插槽 prop。現在在父級作用域中,我們可以給v-slot帶一個值來定義我們提供的插槽 prop 的名字:
// 父組件
template: `
<div>
<card>
<template v-slot:default="userInfo">
用戶姓名: {{userInfo}}
</template>
</card>
</div>
`
// 輸出:
// 用戶姓名: { "userInfo": { "name": "宮鑫" } }
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務。
如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里
今天遇到的就是z-index不起作用的問題。一個后臺小哥不知道抽什么瘋,寫元素覆蓋偏不讓用absolute,搞的我之后廢了9牛二虎之力寫了一下,問題描述是這樣的,
一對兄弟節點,insert和parent,parent有兩個子節點subtop和subbottom,展現的結果是想讓subtop在insert上面,subbottom在insert下面,
代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style type="text/css">
.insert{
position: relative;
z-index:100;
background: green;
width:300px;
height:300px;
top:100px;
}
.parent{
/*position:relative;
z-index: 1000;*/
width:200px;
height:200px;
/*left:0;
top:-50px;*/
border:1px solid #eee;
}
.subbottom{
position:relative;
z-index: 50;
width:200px;
height:200px;
background: red;
top:-100px;
left:0;
}
.subtop{
position: relative;
z-index:1100;
width:100px;
height:100px;
left:0;
top:0;
background: blue;
}
</style>
</head>
<body>
<div class="insert"></div>
<div class="parent">
<div class="subtop"></div>
<div class="subbottom"></div>
</div>
</body>
</html>
其實原理也很簡單,就是利用了z-index的覆蓋問題,在寫的過程中我發現無論怎么改變,insert的z-index總是無效的,于是百度了一下z-index無效的情況,一共有三種:
1、父標簽 position屬性為relative;
2、問題標簽無position屬性(不包括static);
3、問題標簽含有浮動(float)屬性。
這樣也很好理解為什么parent設置了position和z-index之后insert的z-index就會失效的問題了,他的解決辦法有是三個:
1、position:relative改為position:absolute;
2、浮動元素添加position屬性(如relative,absolute等);
3、去除浮動。
所以,去掉parent的position和z-index,達到了我想要的效果,如下圖所示:
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、網站建設 、平面設計服務。如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里
這個問題是解決基于 vue 和 electron 的開發中使用 vuex 的 dispatch 無效的問題,即解決了 Please, don't use direct commit's, use dispatch instead of this. 問題。
先允許我梳理一下目錄結構,以便閱讀的時候不會一頭霧水,你到底說的這個文件是哪個……
其中 /src/main 是存放主配置文件的,/src/render 下面有 store、router、components 等。
components 下面就是很多 .vue 文件,router 下面就是一些路由配置的 js 文件和一些攔截器的 js。
關鍵是 store,store 下面有一個 index.js 的主配置文件 index.js,和一個 modules 文件夾。
index.js 里面寫的是(記住這句話,后面會用到):
import Vue from 'vue'
import Vuex from 'vuex'
import { createPersistedState, createSharedMutations } from 'vuex-electron'
import modules from './modules'
Vue.use(Vuex)
export default new Vuex.Store({
modules,
plugins: [
createPersistedState(),
createSharedMutations()
],
strict: process.env.NODE_ENV !== 'production'
})
而 modules/ 下面存放各個實體,例如上圖中的 Auth.js 和 Counter.js,并通過 index.js 全部引入。
/**
* The file enables `@/store/index.js` to import all vuex modules
* in a one-shot manner. There should not be any reason to edit this file.
*/
const files = require.context('.', false, /\.js$/)
const modules = {}
files.keys().forEach(key => {
if (key === './index.js') return
modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default
})
export default modules
然后來看一個 vuex 的官方樣例:
const state = {
main: 0
}
const mutations = {
DECREMENT_MAIN_COUNTER (state) {
state.main--
},
INCREMENT_MAIN_COUNTER (state) {
state.main++
}
}
const actions = {
someAsyncTask ({ commit }) {
// do something async
commit('INCREMENT_MAIN_COUNTER')
}
}
export default {
state,
mutations,
actions
}
之后很顯然的,我想要在 Vue 的組件調用 INCREMENT_MAIN_COUNTER 對計數器加 1。
this.$store.commit('INCREMENT_MAIN_COUNTER');
// this.$store.commit('INCREMENT_MAIN_COUNTER', payload);
1
2
如果是一般的 vue,就 OK 了,但是,我遇到了報錯,說,Please, don't use direct commit's, use dispatch instead of this.
那好吧,沒事,不就是不然用 Commit,非要用 Dispatch 嘛,那我就寫一個 Action,里面直接調用 Mutation,就像這個樣子:
const actions = {
JUST_INCREASE ({ commit }) {
commit('INCREMENT_MAIN_COUNTER')
}
}
1
2
3
4
5
然而奇怪的事情是,this.$store.dispatch('JUST_INCREASE') 并不能運行,沒反應,計數器還是 0,不能賦值,就像是這個函數沒有被執行一樣。沒有報錯,沒有任何異常,查也查不出什么問題。
網上的資料似乎也挺少。
折騰了很久,后來發現是 vuex-electron 里面一個插件的鍋。
解決方法有兩個。
方法一:
在 store/index.js 里面,就是上文特別強調了的那個文件,去掉 createSharedMutations 插件。
import Vue from 'vue'
import Vuex from 'vuex'
import { createPersistedState, createSharedMutations } from 'vuex-electron'
import modules from './modules'
Vue.use(Vuex)
export default new Vuex.Store({
modules,
plugins: [
createPersistedState(),
createSharedMutations() // 注釋掉這一行
],
strict: process.env.NODE_ENV !== 'production'
})
這是因為 vuex-electron 引入了一個用于多進程間共享 Vuex Store 的狀態的插件。如果沒有多進程交互的需求,完全可以不引入這個插件。
注釋掉以后重啟項目,用 this.$store.commit('XXX') 就可以使用了。
然而,如果需要多進程來處理怎么辦?
方法二:
https://github.com/vue-electron/vuex-electron#installation
看第 3 條:
In case if you enabled createSharedMutations() plugin you need to create an instance of store in the main process. To do it just add this line into your main process (for example src/main.js):
import './path/to/your/store'
1
這種時候就不能用第一種方法來解決問題了。
好在文檔也說了,加上一行導入。
找到 /src/main/index.js,在前面加上一句:
import '../renderer/store'
1
之后一切正常,可以使用 Dispatch 來進行操作了。
最后還有一個比較奇怪的問題:
在直接調用 state 的時候,這樣寫 this.$store.state.loginStatus 是不行的,會 undefined,必須寫成 this.$store.state.Auth.loginStatus,就像是 this.$store.state.Counter.main 一樣,似乎可以解釋為,不同的模塊不指定名字的話就找不到。
但是,在寫 Dispatch 的時候又不需要指定名字了,直接 dispatch('changeLoginStatus') 就行了,不然難道不應該是也按照 dispatch('Auth/changeLoginStatus') 這樣子來寫嘛……
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、網站建設 、平面設計服務。
如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里
需求是攔截前端的網絡請求和相應。
廢話不多說,直接上干貨。
我用的是vue-cli3所以這個config文件是我自己創建的。
先介紹env.js
//根據不同的環境更改不同的baseUrl
let baseUrl = '';
//開發環境下
if (process.env.NODE_ENV == 'development') {
baseUrl = '';
} else if (process.env.NODE_ENV == 'production') {
baseUrl = '生產地址';
}
export {
baseUrl,//導出baseUrl
}
在這里我首先設置了開發環境和生產環境的地址,并向外拋出。
在看一下axios.js
import {
baseUrl, //引入baseUrl
} from "../config/env";
import axios from 'axios';
import qs from 'qs';
//引入vuex的js文件
import vuex from '../src/store/index';
// 創建 axios 實例
let service = axios.create({
baseUrl: baseUrl,//請求前綴
timeout: 20000, // 請求超時時間
crossDomain: true,//設置cross跨域
withCredentials: true//設置cross跨域 并設置訪問權限 允許跨域攜帶cookie信息
})
// 設置 post 默認 Content-Type
service.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
// 添加請求攔截器
service.interceptors.request.use(
(config) => {
// console.log()
//下面的代碼是如何在攔截器中調用vuex管理狀態。
//我這里主要是做了一個蒙層的遮蓋
// vuex.$store.commit('OPEN_LOADING');
//判斷請求方式是否為POST,進行轉換格式
config.method === 'post'
? config.data = qs.stringify({...config.data})
: config.params = {...config.params};
// 請求發送前進行處理
return config
},
(error) => {
// 請求錯誤處理
return Promise.reject(error)
}
)
// 添加響應攔截器
service.interceptors.response.use(
(response) => {
let { data } = response;
return data
},
(error) => {
let info = {},
{ status, statusText, data } = error.response
if (!error.response) {
info = {
code: 5000,
msg: 'Network Error'
}
} else {
// 此處整理錯誤信息格式
info = {
code: status,
data: data,
msg: statusText
}
}
}
)
/**
* 向外拋出service
*/
export default service
最后將這個axios.js文件引入main.js中,并將引入的axios掛載到Vue實例上就ok了。
完美!如有不對的地方還請各位大佬指點,萬分感謝。
踩過的坑:
怎么在axios攔截器中使用vuex,首先我們要引入vuex的js文件,然后就可以用了,就這么簡單。
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務。
藍藍設計的小編 http://www.syprn.cn