IKEA 直接賣「家」了,來看看這既環保又有型的 Tiny Home 小屋拖車_包裝設計

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

上新台中搬家公司提供您一套專業有效率且人性化的辦公室搬遷、公司行號搬家及工廠遷廠的搬家服務

演而優則… 誒不是。總之,IKEA 居家產品賣著賣著,現在竟然也做起了「移動的家」露營拖車。重點是看起來還是非常地有瑞典風而且細節也是滿滿呢!繼續閱讀 IKEA 直接賣「家」了,來看看這既環保又有型的 Tiny Home 小屋拖車 報導內文。

▲圖片來源:IKEA

IKEA 直接賣「家」了,來看看這既環保又有型的 Tiny Home 小屋拖車

這個方正如貨櫃屋但又以很舒服外在色調環繞的 Tiny Home 小屋拖車。是 IKEA 與 Vox Creative 合作打造的微屋 / 小房子 / Tiny Home 計畫。希望透過這個可永續、可負擔、低浪費且有型,小小僅約 5 坪多(187 平方英尺)的空間,證明任何人都可以無拘無束地實現更永續的生活。

▲圖片來源:IKEA

先前我們也有介紹過類似概念的「家」– 是個美到讓人會想要反問,這房子怎麼會有駕駛座的校車改造計畫。這次 IKEA 的 Tiny Home Project,則是以露營拖車的形式實現的小屋計畫,並且也確認成真,將可用美金 4.75 萬也就是約 135 萬台幣擁有。

雖說對於 IKEA 而言,小屋應該主要還是可以展示他們的居家產品的用途為主(還有個網站可以做虛擬「看房」)。但這由 Escape Vista Boho XL 拖車屋為基礎所訂製而成的 Tiny Home,還具備有包括太陽能板、可堆肥廁所系統等功能細節,並可依需提供包括熱水的功能(這部分的能源則由車輛提供)。

▲圖片來源:IKEA

而根據 NBC 的報導,這個以電力運作的小屋是以零碳排與零污染為概念所建成,包括內在建材與家具也都有考量到永續環保或回收材質,但也同時十分注重如桌面採可折疊收納的功能性與美觀 — 這就是 IKEA 展現實力的地方吧。

雖說可能得要仰賴其他能源的狀態下,很顯然要正常在這個小屋生活,基本上很難達到真正的零污染。但至少整個建造的低浪費與環保方向還是很值得鼓勵,也讓人看到了環保不見得就得要犧牲美觀與設計的可能。

本篇圖片 / 引用來源

※產品缺大量曝光嗎?你需要的是一流包裝設計!

窩窩觸角包含自媒體、自有平台及其他國家營銷業務等,多角化經營並具有國際觀的永續理念。

延伸閱讀:

支援 AirPods Max 磁吸休眠的三方皮革收納盒來了,連充電器也能完整裝入

電動車時代來臨?《消費者報告》調查逾 7 成消費者考慮購入電動車

您也許會喜歡:

【推爆】終身$0月租 打電話只要1元/分

立達合法徵信社-讓您安心的選擇

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網動廣告出品的網頁設計,採用精簡與質感的CSS語法,提升企業的專業形象與簡約舒適的瀏覽體驗,讓瀏覽者第一眼就愛上她。

基於redis實現分佈式鎖_貨運

※評比南投搬家公司費用收費行情懶人包大公開

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

目錄

  • 原理剖析
  • 實現
    • 編寫註解
    • 攔截器攔截
    • 上述提及工具
      • RedisLock
      • StockKeyGenerator
    • 問題分析
      • 業務處理時間>上鎖過期時間

※智慧手機時代的來臨,RWD網頁設計為架站首選

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

系統的不斷擴大,分佈式鎖是最基本的保障。與單機的多線程不一樣的是,分佈式跨多個機器。線程的共享變量無法跨機器。

為了保證一個在高併發存場景下只能被同一個線程操作,java併發處理提供ReentrantLock或Synchronized進行互斥控制。但是這僅僅對單機環境有效。我們實現分佈式鎖大概通過三種方式。

  • redis實現分佈式鎖
  • 數據庫實現分佈式鎖
  • zk實現分佈式鎖
    今天我們介紹通過redis實現分佈式鎖。實際上這三種和java對比看屬於一類。都是屬於程序外部鎖。

原理剖析

  • 上述三種分佈式鎖都是通過各自為依據對各個請求進行上鎖,解鎖從而控制放行還是拒絕。redis鎖是基於其提供的setnx命令。
  • setnx當且僅當key不存在。若給定key已經存在,則setnx不做任何動作。setnx是一個原子性操作。
  • 和數據庫分佈式相比,因為redis內存輕量。所以redis分佈式鎖性能更好

實現

  • 原理很簡單。結合springboot項目我們實現一套通過註解形式對接口進行庫存上鎖案例進行理解

編寫註解

  • 我們編寫註解。方便我們在接口上添加註解提供攔截信息

/**
 * @author 張新華
 * @version V1.0
 * @Package com.ay.framework.order.redis.product
 * @date 2020年03月26日, 0026 10:29
 * @Copyright © 2020 安元科技有限公司
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface StockLock {

    /**
     * @author zxhtom
     * @Description 鎖key的前綴
     * @Date 15:25 2020年03月25日, 0025
     * @Param []
     * @return java.lang.String
     */
    String prefix() default "";
    /**
     * @author zxhtom
     * @Description key的分隔符
     * @Date 15:27 2020年03月25日, 0025
     * @Param []
     * @return java.lang.String
     */
    String delimiter() default ":";
}


/**
 * @author 張新華
 * @version V1.0
 * @Package com.ay.framework.order.redis.product
 * @date 2020年03月26日, 0026 11:09
 * @Copyright © 2020 安元科技有限公司
 */
@Target({ElementType.PARAMETER , ElementType.METHOD , ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface StockParam {
    /**
    * @author zxhtom
    * @Description 組成key
    * @Date 11:11 2020年03月26日, 0026
    * @Param []
    * @return java.lang.String[]
    */
    String[] names() default {""};
}

攔截器攔截

  • redis分佈式鎖實現的關鍵就是攔截器的編寫。上面的註解只是為了實現攔截的一個輔助。

@Around("execution(public * *(..)) && @annotation(com.ay.framework.order.redis.product.StockLock)")

  • 通過springboot的Around進行針對StockLock註解的攔截。通過攔截我們可以獲取到攔截的方法、參數、及需要的鎖的參數。
  • 我們獲取到需要鎖的名稱這裏叫做【a】之後通過redis的原子性操作對該key進行遞減操作。
  • 為了方便我們在削減庫存的時候可以對庫存進行更新操作。我們在遞減庫存前還需要藉助於另一把鎖。 這一把鎖我們叫做【a_key】
  • 換句話說我們接口想訪問就必須獲取【a】鎖,拿到【a】鎖需要減少庫存。減少庫存之前需要獲取【a_key】鎖。
  • 拿到鎖之後處理完邏輯之後我們需要釋放對應鎖。

RedisAtomicLong entityIdCounter = new RedisAtomicLong(lockKey, redisTemplate.getConnectionFactory());
    if (redisTemplate.hasKey(CoreConstants.UPDATEPRODUCTREDISLOCKKEY + lockKey)) {
        //表示lockKey的庫存信息有變動。此時無法進行交易
        throw new BusinessException("庫存變動。暫無法交易");
    }
    Long increment = entityIdCounter.decrementAndGet();
    if (increment >= 0) {
        try {
            Object proceed = pjp.proceed();
        } catch (Throwable throwable) {
            //所佔資源需要釋放回資源池
            while (!redisLock.tryGetLock(CoreConstants.UPDATEPRODUCTREDISLOCKKEY + lockKey, "")) {

            }
            //表示lockKey的庫存信息有變動。此時無法進行交易
            long l = entityIdCounter.incrementAndGet();
            if (l < 1) {
                redisTemplate.opsForValue().set(lockKey,1);
            }
            redisLock.unLock(CoreConstants.UPDATEPRODUCTREDISLOCKKEY + lockKey);
            throwable.printStackTrace();
        }
    } else {
        redisTemplate.opsForValue().set(lockKey,0);
        throw new BusinessException("庫存不足!無法操作");
    }

  • 因為我們上鎖就需要釋放鎖。但是程序在中途處理業務是發生異常導致沒有走到釋放鎖的步驟。這個時候就導致我們的分佈式鎖一直被鎖。俗稱【死鎖】。為了避免這種場景的發生。我們常常在上鎖的時候給一個有效期。有效期已過自動釋放鎖。這個特性恰好和redis的過期策略不摩爾和。

上述提及工具

RedisLock


public Boolean tryGetLock(String key , String value) {
    return tryGetLock(key, value, -1, TimeUnit.DAYS);
}
public Boolean tryGetLock(String key , String value, Integer expire) {
    return tryGetLock(key, value, expire, TimeUnit.SECONDS);
}
public Boolean tryGetLock(String key , String value, Integer expire , TimeUnit timeUnit) {
    ValueOperations operations = redisTemplate.opsForValue();
    if (operations.setIfAbsent(key, value)) {
        //說明 redis沒有該key , 換言之 加鎖成功  設置過期時間防止死鎖
        if (expire > 0) {
            redisTemplate.expire(key, expire, timeUnit);
        }
        return true;
    }
    return false;
}

public Boolean unLock(String key) {
    return redisTemplate.delete(key);
}

StockKeyGenerator


@Component()
@Primary
public class StockKeyGenerator implements CacheKeyGenerator {
    @Override
    public String getLockKey(ProceedingJoinPoint pjp) {
        //獲取方法簽名
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        //獲取方法cacheLock註解
        StockLock stockLock = method.getAnnotation(StockLock.class);
        //獲取方法參數
        Object[] args = pjp.getArgs();
        Parameter[] parameters = method.getParameters();
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < parameters.length; i++) {
            StockParam stockParam = parameters[i].getAnnotation(StockParam.class);
            Object arg = args[i];
            if (arg instanceof Map) {
                Map<String, Object> temArgMap = (Map<String, Object>) arg;
                String[] names = stockParam.names();
                for (String name : names) {
                    if (builder.length() > 0) {
                        builder.append(stockLock.delimiter());
                    }
                    builder.append(temArgMap.get(name));
                }
            }

        }
        return builder.toString();
    }
}

問題分析

  • 上面分析了一個死鎖的場景,理論上出了死鎖我們redis分佈鎖很好的解決了分佈式問題。但是還是會出現問題。下面列舉寫小編遇到的問題。

業務處理時間>上鎖過期時間

  • a線程獲取到鎖,開始進行業務處理需要8S,
  • 在8S內,鎖的有效期是5S,在鎖過期后也就是第6S , b線程進入開始獲取鎖這個時候b是可以獲取到新鎖的。這個時候就是有問題的。
  • 假設b線程業務處理只需要3S , 但是因為a線程釋放了鎖,所以在第8S的時候雖然b線程沒有釋放鎖,b的鎖也沒有過期但是這時候也沒有了鎖。從而導致C線程也可以進入

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

關於vue的多頁面標籤功能,對於嵌套router-view緩存的最終無奈解決方法_網頁設計公司

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

節能減碳愛地球是景泰電動車的理念,是創立景泰電動車行的初衷,滿意態度更是服務客戶的最高品質,我們的成長來自於你的推薦。

最近寫我自己的後台開發框架,要弄一個多頁面標籤功能,之前有試過vue-element-admin的多頁面,以為很完美,就按它的思路重新寫了一個,但發現還是有問題的。

vue-element-admin它用的是在keep-alive組件上使用include屬性,綁定$store.state.tagsView.cachedViews,當點擊菜單時,往$store.state.tagsView.cachedViews添加頁面的name值,在標籤卡上點擊關閉后就從$store.state.tagsView.cachedViews裏面把緩存的name值刪除掉,這樣聽似乎沒什麼問題。但它無法很好的支持無限級別的子菜單的緩存。

目前vue-element-admin官方預覽地址的菜單結構大多是一級菜單分類,下面是二級子菜單。如下圖所示,它只能緩存二級子菜單,三級子菜單它緩存不了。為什麼會出現這個情況呢。因為嵌套router-view的問題。

 

 

 

按vue-element-admin的路由結構,它的一級菜單,其實對應的是一個layout組件,layout裏面有個router-view(稱它為一級router-view)它有用keep-alive包裹着,用來放二級菜單對應的頁面,所以對於二級菜單來說,它都是用同一個router-view。如果我需要創建三級菜單的話,那就需要在二級菜單目錄里創建一個包含router-view(稱它為二級router-view)的index.vue文件,用來放三級菜單對應的頁面,那麼你就會發現這個三級菜單的頁面怎麼也緩存不了。

 

因為只有一級router-view被keep-alive包裹起着緩存作用,下面的router-view它不緩存。當然我們也可以在二級的router-view也包一個keep-alive,也用include屬性,但你會發現也用不了,因為還要匹配name值,就是說二級router-view的文件也得寫上name值,寫上name值后你發現還是用不了,因為include數組裡面沒有這個二級router-view的name值,所以你還得在tabsView里的addView裏面做手腳,把路由所匹配到的所有路由的name值都添加到cachedViews里,然後還要在關閉時再進行處理。天啊。我想想都頭痛,理論是應該是可以實現的,但會增加了很多前端代碼量。

 

請注意!下面的方法也是有Bug的,請重點看下面的BUT開始部分

還好keep-alive還有另一個屬性exclude,我馬上就有思路了,而且非常簡潔,默認全部頁面進行緩存,所有的router-view都包一層keep-alive,只有在點擊標籤卡上的關閉按鈕時,往$store.state.sys.excludeViews添加關閉頁面的name值,下次打開后再從excludeViews裏面把頁面的name值刪除掉就行了,非常地簡單易懂,不過最底層的頁面,仍然需要寫上跟路由定義時完全匹配的name值。這一步我仍然想不到有什麼辦法可以省略掉。

為方便代碼,我寫了一個組件aliveRouterView組件,併合局註冊,這個組件用來代替router-view組件,如下面代碼所示,$store.state.sys.config.PAGE_TABS這個值是是否開戶多頁面標籤功能參數

<template>
  <keep-alive :exclude="exclude">
    <router-view />
  </keep-alive>
</template>
<script>
export default {
  computed: {
    exclude() {
      if (this.$store.state.sys.config.PAGE_TABS) {
        return this.$store.state.sys.excludeViews;
      } else {
        return /.*/;
      }
    }
  }
};
</script>

 

多頁面標籤組件viewTabs.vue,如下面代碼所示

<template>
  <div class="__common-layout-tabView">
    <el-scrollbar>
      <div class="__tabs">
        <div
          class="__tab-item"
          :class="{ '__is-active':item.name==$route.name }"
          v-for="item in viewRouters"
          :key="item.path"
          @click="onClick(item)"
        >
          {{item.meta.title}}
          <span
            class="el-icon-close"
            @click.stop="onClose(item)"
            :style="viewRouters.length<=1?'width:0;':''"
          ></span>
        </div>
      </div>
    </el-scrollbar>
  </div>
</template>
<script>
export default {
  data() {
    return {
      viewRouters: []
    };
  },
  watch: {
    $route: {
      handler(v) {
        if (!this.viewRouters.some(item => item.name == v.name)) {
          this.viewRouters.push(v);
        }
      },
      immediate: true
    }
  },
  methods: {
    onClick(data) {
      if (this.$route.fullPath != data.fullPath) {
        this.$router.push(data.fullPath);
      }
    },
    onClose(data) {
      let index = this.viewRouters.indexOf(data);
      if (index >= 0) {
        this.viewRouters.splice(index, 1);
        if (data.name == this.$route.name) {
          this.$router.push(this.viewRouters[index < 1 ? 0 : index - 1].path);
        }
        this.$store.dispatch("excludeView", data.name);
      }
    }
  }
};
</script>
<style lang="scss">
.__common-layout-tabView {
  $c-tab-border-color: #dcdfe6;
  position: relative;
  &::before {
    content: "";
    border-bottom: 1px solid $c-tab-border-color;
    position: absolute;
    left: 0;
    right: 0;
    bottom: 2px;
    height: 100%;
  }
  .__tabs {
    display: flex;
    .__tab-item {
      white-space: nowrap;
      padding: 8px 6px 8px 18px;
      font-size: 12px;
      border: 1px solid $c-tab-border-color;
      border-left: none;
      border-bottom: 0px;
      line-height: 14px;
      cursor: pointer;
      transition: color 0.3s cubic-bezier(0.645, 0.045, 0.355, 1),
        padding 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
      &:first-child {
        border-left: 1px solid $c-tab-border-color;
        border-top-left-radius: 2px;
        margin-left: 10px;
      }
      &:last-child {
        border-top-right-radius: 2px;
        margin-right: 10px;
      }
      &:not(.__is-active):hover {
        color: #409eff;
        .el-icon-close {
          width: 12px;
          margin-right: 0px;
        }
      }
      &.__is-active {
        padding-right: 12px;
        border-bottom: 1px solid #fff;
        color: #409eff;
        .el-icon-close {
          width: 12px;
          margin-right: 0px;
          margin-left: 2px;
        }
      }
      .el-icon-close {
        width: 0px;
        height: 12px;
        overflow: hidden;
        border-radius: 50%;
        font-size: 12px;
        margin-right: 12px;
        transform-origin: 100% 50%;
        transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
        vertical-align: text-top;
        &:hover {
          background-color: #c0c4cc;
          color: #fff;
        }
      }
    }
  }
}
</style>

 

貼上我的sys的store文件,後面我發現,我把頁面name添加到excludeViews后,在下一幀中再從excludeViews中把name刪除后,這樣也能有效果。如下面excludeView所示。這樣就更加簡潔。我只需在關閉標籤卡時處理一下就行了。

const sys = {
    state: {
        permissionRouters: [],//權限路由表
        permissionMenus: [],//權限菜單列表
        config: null, //系統配置        
        excludeViews: [] //用於多頁面選項卡
    },
    getters: {

    },
    mutations: {
        SET_PERMISSION_ROUTERS(state, routers) {
            state.permissionRouters = routers;
        },
        SET_PERMISSION_MENUS(state, menus) {
            state.permissionMenus = menus;
        },
        SET_CONFIG(state, config) {
            state.config = config;
        },
        ADD_EXCLUDE_VIEW(state, viewName) {
            state.excludeViews.push(viewName);
        },
        DEL_EXCLUDE_VIEW(state, viewName) {
            let index = state.excludeViews.indexOf(viewName);
            if (index >= 0) {
                state.excludeViews.splice(index, 1);
            }
        }
    },
    actions: {
        //排除頁面
        excludeView({ state, commit, dispatch }, viewName) {
            if (!state.excludeViews.includes(viewName)) {
                commit("ADD_EXCLUDE_VIEW", viewName);
                Promise.resolve().then(() => {
                    commit("DEL_EXCLUDE_VIEW", viewName);
                })
            }
        }
    }
}
export default sys

 

效果如下圖所示,記得一點,就是得在你的頁面上填寫name值,需要跟定義路由時完全一致

 

BUT!!當我截完上面的動圖后,我就發現了問題了,而且是一個無法解決的問題,按我上面的方法,如果我點一下首頁,再點回原來的用戶管理,再關閉用戶管理,再打開用戶管理,你會發現緩存一直都在。

這是為什麼呢?究根詰底還是這個嵌套router-view的問題,不同的router-view的緩存是獨立的,首頁頁面是緩存在一級router-view下面,而用戶管理頁面是緩存在二級router-view下面,當我關閉用戶管理頁面后,只是往excludeViews添加了用戶管理頁面的name(sys.anme),所以只會刪除二級router-view下面name值為sys.user的頁面,二級router-view的name值為sys,它還緩存在一級router-view,所以導致用戶管理一直緩存着。

當然我也想過在關閉頁面時,把頁面父級的所有router-view的name值都添加到excludeViews裏面,這樣的話,也會出現問題,就是當我關閉用戶管理頁面后,同樣在name值為sys的二級router-view下面的頁面緩存都刪除掉了。

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

透過選單樣式的調整、圖片的縮放比例、文字的放大及段落的排版對應來給使用者最佳的瀏覽體驗,所以不用擔心有手機版網站兩個後台的問題,而視覺效果也是透過我們前端設計師優秀的空間比例設計,不會因為畫面變大變小而影響到整體視覺的美感。

當我測試了一晚上,我發現這真的是無解的,中間我也試過網上說的暴力刪除cache方法(方法介紹),也是因為這個嵌套router-view的問題導致失敗。

其實網上有人提出的解決方法是把框架改成只有一個一級router-view,一開始我覺得這是個下策,後面發現這也是唯一的方法了。

無奈,我確實不想扔棄這個多頁面標籤功能。那就改吧,其實改起來也不複雜,就是將菜單跟路由數組分為兩成數組,各自獨立。路由全部同級,均在layout布局組件的children裏面。

只使用一級router-view後面,這個多頁面標籤功能就非常好解決了,用include或exclude都可以,沒有什麼問題,但這兩種方法都得在頁面上寫name值,我是一個懶惰的程序員,總是寫這種跟業務無關係的name值顯得特別多餘。幸運的是,我之前在網上有找到一種暴力刪除緩存的方法,經過我的測試后,發現只有一個小問題(下面會提到),其它方面幾乎完美,而且跟include、exclude相比,還能完美支持同個頁面可以根據不同參數同時緩存的功能。(在vue-element-admin裏面也有說到include是沒法支持這種功能的,如下圖)

 

思想是這樣的,在store里創建一個openedPageRouters(已打開的頁面路由數組),我watch路由的變化,當打開一個新頁面時,往openedPageRouters裏面添加頁面路由,當我關閉頁面標籤時,到openedPageRouters裏面刪除對應的頁面路由,而上面提到的暴力刪除緩存,是在頁面的beforeRouterLeave事件中進行刪除中,所以我註冊一個全局mixin的beforeRouterLeave事件,檢測離開的頁面如果不存在於openedPageRouters數組裡面,那就進行緩存刪除。

思路很完美,當然裏面還有一個小問題,就是刪除不是當前激活的頁面,怎麼處理,因為beforeRouterLeave必須在要刪除頁面的生命周期才能觸發的,這個我用了點小手段,我先跳轉到要刪除的頁面,然後往openedPageRouters里刪除這個頁面路由,然後再跳回原來的頁面,這樣就能讓它觸發beforeRouterLeave了。哈哈,不過這個會導致一個小問題,就是地址欄的閃動一下,也就是上面提到的小問題。

下面是我的pageTabs.vue多頁面標籤組件的代碼

<template>
  <div class="__common-layout-pageTabs">
    <el-scrollbar>
      <div class="__tabs">
        <div
          class="__tab-item"
          v-for="item in $store.state.sys.openedPageRouters"
          :class="{ '__is-active': item.meta.canMultipleOpen?item.fullPath==$route.fullPath:item.path==$route.path }"
          :key="item.fullPath"
          @click="onClick(item)"
        >
          {{item.meta.title}}
          <span
            class="el-icon-close"
            @click.stop="onClose(item)"
            :style="$store.state.sys.openedPageRouters.length<=1?'width:0;':''"
          ></span>
        </div>
      </div>
    </el-scrollbar>
  </div>
</template>
<script>
export default {
  watch: {
    $route: {
      handler(v) {
        this.$store.dispatch("openPage", v);
      },
      immediate: true
    }
  },
  methods: {
    //點擊頁面標籤卡時
    onClick(data) {
      if (this.$route.fullPath != data.fullPath) {
        this.$router.push(data.fullPath);
      }
    },
    //關閉頁面標籤時
    onClose(route) {
      if (route.fullPath == this.$route.fullPath) {
        let index = this.$store.state.sys.openedPageRouters.indexOf(route);
        this.$store.dispatch("closePage", route);
        //刪除頁面后,跳轉到上一頁面
        this.$router.push(
          this.$store.state.sys.openedPageRouters[index < 1 ? 0 : index - 1]
            .path
        );
      } else {
        let lastPath = this.$route.fullPath;
        //先跳轉到要刪除的頁面,再刪除頁面路由,再跳轉回來原來的頁面
        this.$router.replace(route).then(() => {          
          this.$store.dispatch("closePage", route);
          this.$router.replace(lastPath);
        });
      }
    }
  }
};
</script>
<style lang="scss">
.__common-layout-pageTabs {
  $c-tab-border-color: #dcdfe6;
  position: relative;
  &::before {
    content: "";
    border-bottom: 1px solid $c-tab-border-color;
    position: absolute;
    left: 0;
    right: 0;
    bottom: 2px;
    height: 100%;
  }
  .__tabs {
    display: flex;
    .__tab-item {
      white-space: nowrap;
      padding: 8px 6px 8px 18px;
      font-size: 12px;
      border: 1px solid $c-tab-border-color;
      border-left: none;
      border-bottom: 0px;
      line-height: 14px;
      cursor: pointer;
      transition: color 0.3s cubic-bezier(0.645, 0.045, 0.355, 1),
        padding 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
      &:first-child {
        border-left: 1px solid $c-tab-border-color;
        border-top-left-radius: 2px;
        margin-left: 10px;
      }
      &:last-child {
        border-top-right-radius: 2px;
        margin-right: 10px;
      }
      &:not(.__is-active):hover {
        color: #409eff;
        .el-icon-close {
          width: 12px;
          margin-right: 0px;
        }
      }
      &.__is-active {
        padding-right: 12px;
        border-bottom: 1px solid #fff;
        color: #409eff;
        .el-icon-close {
          width: 12px;
          margin-right: 0px;
          margin-left: 2px;
        }
      }
      .el-icon-close {
        width: 0px;
        height: 12px;
        overflow: hidden;
        border-radius: 50%;
        font-size: 12px;
        margin-right: 12px;
        transform-origin: 100% 50%;
        transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
        vertical-align: text-top;
        &:hover {
          background-color: #c0c4cc;
          color: #fff;
        }
      }
    }
  }
}
</style>

 

以下是store代碼

const sys = {
    state: {
        menus: [],//
        permissionRouters: [],//權限路由表
        permissionMenus: [],//權限菜單列表
        config: null, //系統配置        
        openedPageRouters: [] //已打開原頁面路由
    },
    getters: {

    },
    mutations: {
        SET_PERMISSION_ROUTERS(state, routers) {
            state.permissionRouters = routers;
        },
        SET_PERMISSION_MENUS(state, menus) {
            state.permissionMenus = menus;
        },
        SET_MENUS(state, menus) {
            state.menus = menus;
        },
        SET_CONFIG(state, config) {
            state.config = config;
        },
        //添加頁面路由        
        ADD_PAGE_ROUTER(state, route) {
            state.openedPageRouters.push(route);
        },
        //刪除頁面路由
        DEL_PAGE_ROUTER(state, route) {
            let index = state.openedPageRouters.indexOf(route);
            if (index >= 0) {
                state.openedPageRouters.splice(index, 1);
            }
        },
        //替換頁面路由
        REPLACE_PAGE_ROUTER(state, route) {
            for (let key in state.openedPageRouters) {
                if (state.openedPageRouters[key].path == route.path) {
                    state.openedPageRouters.splice(key, 1, route)
                    break;
                }
            }
        }
    },
    actions: {
        //打開頁面
        openPage({ state, commit }, route) {
            let isExist = state.openedPageRouters.some(
                item => item.fullPath == route.fullPath
            );
            if (!isExist) {
                //判斷頁面是否支持不同參數多開頁面功能,如果不支持且已存在path值一樣的頁面路由,那就替換它
                if (route.meta.canMultipleOpen || !state.openedPageRouters.some(
                    item => item.path == route.path
                )) {
                    commit("ADD_PAGE_ROUTER", route);
                } else {
                    commit("REPLACE_PAGE_ROUTER", route);
                }
            }
        },
        //關閉頁面
        closePage({ state, commit }, route) {
            commit("DEL_PAGE_ROUTER", route);
        }        
    }
}
export default sys

 

以下是暴力刪除頁面緩存的代碼,我寫成了一個全局的mixin

import Vue from 'vue'
Vue.mixin({
  beforeRouteLeave(to, from, next) {
    //限制只有在我寫的那個父類里才可能會用這個緩存刪除功能
    if (!this.$parent || this.$parent.$el.className != "el-main __common-layout-main" || !this.$store.state.sys.config.PAGE_TABS) {
      next();
      return;
    }
    let isExist = this.$store.state.sys.openedPageRouters.some(item => item.fullPath == from.fullPath)
    if (!isExist) {
      let tag = this.$vnode.tag;
      let cache = this.$vnode.parent.componentInstance.cache;
      let keys = this.$vnode.parent.componentInstance.keys;
      let key;
      for (let k in cache) {
        if (cache[k].tag == tag) {
          key = k;
          break;
        }
      }
      if (key) {
        if (cache[key] != null) {
          delete cache[key];
          let index = keys.indexOf(key);
          if (index > -1) {
            keys.splice(index, 1);
          }
        }
      }
    }
    next();
  }
})

 

 然後router-view這樣使用,根據我的配置$store.state.sys.config.PAGE_TABS(是否啟用多頁面標籤)進行判斷 ,對了,我相信有不少人肯定會想到,路由不嵌套了,沒有matched數組了,怎麼弄麵包屑,可以看我下面代碼的處理,$store.state.sys.permissionMenus這個數組是我從後台傳過來的,是一個根據當前用戶的權限獲取到的所有有權限訪問的菜單數組,都是一級數組,沒有嵌套關係,我的菜單數組跟路由都是根據這個permissionMenus進行構建的。而我的麵包屑數組就是從這個數組遞歸出來的。

<template>
  <el-main class="__common-layout-main">
    <page-tabs class="c-mg-t-10p" v-if="$store.state.sys.config.PAGE_TABS" />
    <div class="c-pd-20p">
      <el-breadcrumb separator="/">
        <el-breadcrumb-item v-for="m in breadcrumbItems" :key="m.id">{{m.name}}</el-breadcrumb-item>
      </el-breadcrumb>
      <div class="c-h-15p"></div>
      <keep-alive v-if="$store.state.sys.config.PAGE_TABS">
        <router-view :key="$route.fullPath" />
      </keep-alive>
      <router-view v-else />
    </div>
  </el-main>
</template>
<script>
import pageTabs from "./pageTabs";
export default {
  components: { pageTabs },
  data() {
    return {
      viewNames: ["role"]
    };
  },
  computed: {
    breadcrumbItems() {
      let items = [];
      let buildItems = id => {
        let b = this.$store.state.sys.permissionMenus.find(
          item => item.id == id
        );
        if (b) {
          items.unshift(b);
          if (b.parentId) {
            buildItems(b.parentId);
          }
        }
      };
      buildItems(this.$route.meta.id);
      return items;
    }
  }
};
</script>
<style lang="scss">
$c-tab-border-color: #dcdfe6;
.__common-layout-main.el-main {
  padding: 0px;
  overflow: unset;
  .el-breadcrumb {
    font-size: 12px;
  }
}
</style>

 

演示一個最終效果,哎,弄了我整整两天時間,不過我改成不嵌套路由后,發現代碼量也少了很多,也是因禍得福啊。這更符合我的Less框架的理念了。哈哈哈!

對了,我之前有說到個小問題,大家可以仔細看一下,下圖的地址欄,當我關閉非當前激活的頁面標籤時,你會發現地址欄會閃現一下。好吧,下面這個動圖還不太明顯。

大家可以到我的LessAdmin框架預覽地址測試下,不要亂改菜單數據哦,會導致打不開的

http://test.caijt.com:9001

用戶:superadmin

密碼:admin

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

搬家費用:依消費者運送距離、搬運樓層、有無電梯、步行距離、特殊地形、超重物品等計價因素後,評估每車次單

何苦咬牙買豪華品牌?教你如何用20萬買出豪華檔次的車型!_貨運

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

0T的車型的畢竟6AT比1。5T的7速雙離合要成熟不少,開起來起碼平順性是很好的。實際上該車的操控、靜音等各方面都進步不少,底盤也是十分紮實,震動的動作不大,感覺新君越的整體駕乘體驗不比豪華車差。長安福特-金牛座指導價:23。

可能有些人覺得開台BBA出去會比較有面子,畢竟豪華車是身份的象徵,當然,那些是有錢之後考慮的事情了。那如果手裡的閑錢不到三十萬,要不要咬咬牙,擠多一點錢出來直接拿下一台BBA?認為這完全沒必要,按照這個預算,其實也有豪華感十足,但是購車和用車成本比BBA低很多的車子,這不,今天就給大家挑了幾輛這樣的車。(pS:這幾輛車就不介紹乘坐空間了,因為這是完全不用擔心的問題。)

一汽大眾-邁騰

指導價:18.99-31.69萬

今年七月上市的換代新邁騰(B8)可謂千呼萬喚始出來,事實上,一汽大眾這輛基於MQB平台的B級車也並沒有讓失望。

外觀上,新邁騰總體來說就是變得更寬更扁了,中網-大燈一體化的設計讓前臉看起來更加開揚,LED光源的大燈點亮後效果十分搶眼。貫穿兩個把手的腰線十分硬朗,告別了舊款略帶木訥的觀感。車尾線條幹凈利落,最有特色的要數那LED豎狀剎車燈,點亮后辨識度極高。

內飾的設計雖然低調,但商務氣息特別濃,中控台採用大面積的軟質搪塑材料,質感十分好,最喜歡的莫過於內飾中加入了實木飾板,提升了整個車廂的格調,帶來越級的體驗。儀錶盤為液晶的,功能強大,8英寸大屏搭載了MIB多媒體系統,操作簡單。內飾雖說不上奢華,但能夠給一種很接地氣的豪華感。

動力方面,新邁騰仍然有1.4T、1.8T和2.0T三個版本,搭載最新的第三代EA211和EA888發動機,最大馬力分別是150、179和220pS,變速箱為大眾比較成熟的7速雙離合。大眾的雙離合已經十分成熟,換擋動作快而穩,發動機的發力點靠後,起步平順,後勁十足,雖然不能給你激烈的駕駛感受,但配合紮實有韌性的底盤,認為這種平順穩重的行駛品質,是該級別的車應有的表現。

上汽通用別克-君越

指導價:22.58-33.98萬

君越的出現可以說是刷新了對B級車的看法,

※智慧手機時代的來臨,RWD網頁設計為架站首選

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

第一次見到B級車也能夠這麼長,這麼有豪華感,而20多30萬的價格,又讓該車十分的接地氣。

新君越的造型明顯變得更加年輕化的低矮扁平了,擺脫了舊款車型臃腫的“大叔車”造型,飛翼式的格柵辨識度很高,亮黑的底色配上鍍鉻兩條,質感很高檔。整體來說,認為這一代君越流暢、扁平的造型會讓他的受眾範圍更廣,兼顧了商務大氣和年輕時尚,很好。

簡潔明了的內飾採用懷抱式的設計,幹練之餘線條十分流暢。進入新君越的車廂時第一感覺就是豪華,大量的真皮搭配仿木紋飾板,十分顯高檔。多媒體系統也支持安吉星、Carplay和Carlife功能,十分豐富。

燃油版的新君越有兩種動力配置,按排量分分別是1.5T和2.0T,提供最大170pS和261pS的馬力,還是建議買2.0T的車型的畢竟6AT比1.5T的7速雙離合要成熟不少,開起來起碼平順性是很好的。實際上該車的操控、靜音等各方面都進步不少,底盤也是十分紮實,震動的動作不大,感覺新君越的整體駕乘體驗不比豪華車差。

長安福特-金牛座

指導價:23.38-34.88萬

要說金牛座,剛上市的時候還是比較沸沸揚揚的,當然也是有各種事件的影響,看中大型車銷量的話,金牛座其實並不差,前面除了BBA就是皇冠了,二十萬出頭能有這個級別的商務機座駕,夫復何求啊。

外觀上,認為金牛座的外觀是穩重當中又帶點粗獷氣息的,這也很符合美系車的風格。前臉最明顯的就是家族式的碩大中網,但隱約覺得與金牛座穩重的風格有點格格不入。覺得金牛座的外觀還是相當大氣的,畢竟車身尺寸擺在那。

再看內飾,皮質的面料、寬大的扶手箱、木紋飾板的加入、四副式的方向盤,營造出一種沉穩的商務氣息。細節上,看到金牛座的做工其實很不錯,接縫均勻、包裹嚴實,做工上絕對對得起它的定位。最出彩的是後排有豐富的功能,多媒體、空調控制等等一應俱全。

動力上,指導價不出30萬就能夠買到2.7T雙渦輪增壓V6引擎的配置,最大馬力329pS,搭配6AT變速箱,動力輸出平順而有力,油門雖然沉穩,但是V6引擎的低扭十分強,絲毫不用擔心起步拖沓。底盤的質感偏軟,但能保證一定的支撐性,整體的行駛質感還是十分優秀的。

一汽豐田-皇本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

※評比南投搬家公司費用收費行情懶人包大公開

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

自帶7座大空間+In-Joy智聯黑科技?傳祺GS8還讓對手活嗎?_網頁設計公司

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

透過選單樣式的調整、圖片的縮放比例、文字的放大及段落的排版對應來給使用者最佳的瀏覽體驗,所以不用擔心有手機版網站兩個後台的問題,而視覺效果也是透過我們前端設計師優秀的空間比例設計,不會因為畫面變大變小而影響到整體視覺的美感。

In-Joy系統主頁是“多任務卡片”式,首頁有三個最常用功能,可以同時查閱到幾項重要信息,並能快捷控制。In-Joy系統的另一個亮點,同時也是其設計理念——“一秒必達”,你可以更方便快捷的做很多事情,比如撥打電話、調整空調溫度、打開收音機、播放音樂、設置地圖導航等等。

前言

不少科幻電影會有這樣的鏡頭,主角通過手機輕鬆控制汽車,就像《007》中的詹世邦用手機遠程啟動了汽車逃過了反派的追殺;《復讎者聯盟》中鋼鐵俠擁有上天入地的隱形显示屏,快速掌握戰場信息及聯絡隊友。這些東西都讓我們垂涎三尺,非常地炫酷,但是有沒有想過這已經幾乎實現了呢?還是在一輛有着超大空間、霸氣的7座SUV上?沒錯,它就是10月26日將上市的“旗艦級豪華大7座SUV”傳祺GS8,我們今天討論的主角。

霸氣高顏值傳祺GS8將上市,請準備好聚光燈

鋼鐵俠托尼是一張性格乖張的人,有着一種吸引眾人目光的能力,而我們的主角——傳祺GS8兼具勇而不莽、貴而不俗,定位中大型7座SUV的它有着4810*1910*1770mm車身尺寸,在視覺上就給人一種寬奢的感覺。另外使用了傳祺光影雕塑2.0設計理念,整體線條硬朗霸氣,加上使用了科技感十足的LED大燈,給人感覺大氣穩重又不失霸氣感,瞬間拉高了中國品牌車型的顏值。

如此霸氣的車身尺寸加上2800mm的軸距,當然讓傳祺GS8有着優秀的空間表現,軸距比漢蘭達這個合資對手還多出10mm。除此以外,車內目光所及者皆體現豪華感,如黃花梨木紋與鑲嵌的金色飾條,搭配頂級麂皮質感的超纖維面料,考究的配色和做工,盡顯豪華品質;配備頂級品牌安橋車載音響系統、全景天窗、Easy Open電動掀背門等豪車級配置,直擊30萬級以上合資高端車。

In-Joy黑科技放大用戶價值,三屏互聯超高級享受

鋼鐵俠的戰衣有着一個超大的液晶屏幕,

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

搬家費用:依消費者運送距離、搬運樓層、有無電梯、步行距離、特殊地形、超重物品等計價因素後,評估每車次單

這輛傳祺GS8也有10英寸的哈曼頂級液晶屏幕以及7英寸的儀錶盤液晶显示屏。光是尺寸大是沒有用的,還必須是智能,傳祺GS8擁有“黑科技”In-Joy系統,運用Carlife和Carplay系統輕鬆實現中控大屏、儀錶屏與智能手機三屏互聯,車載屏幕就相當於變成了一台智能手機,導航信息、影音娛樂信息均可在7寸液晶儀錶上體現。

In-Joy系統主頁是“多任務卡片”式,首頁有三個最常用功能,可以同時查閱到幾項重要信息,並能快捷控制。In-Joy系統的另一個亮點,同時也是其設計理念——“一秒必達”,你可以更方便快捷的做很多事情,比如撥打電話、調整空調溫度、打開收音機、播放音樂、設置地圖導航等等。更值得炫耀的是,In-Joy系統配備了同級獨有的無線充電功能,為手機自由充電,暢享愉悅空間。

車內有着一個貼心管家,名字是智慧傳祺3.0系統

賈維斯可以遠程啟動實現遠程救主,而傳祺GS8也有着這樣智能的表現。據了解,智慧傳祺3.0系統能幫助我們實現手機控制車輛,甚至無視距離,遠程遙控啟動車輛、遠程開啟空調、座椅加熱、燈光、車窗、後備箱等功能,試想一下寒冷的冬天早早地遠程遙控開啟空調以及座椅加熱,一坐進車內就感受到溫暖而不是面對一輛冷冰冰的車是多麼愜意的事情。

它的智能還體現在駕駛方面,駕駛中大型SUV總讓人覺得難以駕駛,但傳祺GS8有着前碰預警系統、併線輔助系統、車道偏離系統以及ACC自適應巡航系統,幫助駕駛減少時盲區,而駕駛強度也會大幅度降低。

傳祺GS8預售價:16.98萬-25.98萬。

總的來說,傳祺GS8不僅僅在空間方面以及內飾豪華感等方面給到我們驚喜,還在互聯以及自動安全方面有着超越同價位對手的表現,是一輛有着諸多“黑科技”的中大型SUV,非常適合想要選擇中大型SUV、注重用戶體驗以及主動安全配置的用戶購買。10月26日,傳祺GS8將在杭州國際博覽中心震撼上市,不如掃描下面的二維碼,先來一大波美圖洗洗眼吧。

本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

節能減碳愛地球是景泰電動車的理念,是創立景泰電動車行的初衷,滿意態度更是服務客戶的最高品質,我們的成長來自於你的推薦。

居然不知道這些優惠巨大的進口車?教授都替你急了_包裝設計

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網動廣告出品的網頁設計,採用精簡與質感的CSS語法,提升企業的專業形象與簡約舒適的瀏覽體驗,讓瀏覽者第一眼就愛上她。

你可能會說,差不多的動力系統,我為什麼不買更加便宜的卡羅拉或者雷凌雙擎。然而事實上,雷克薩斯始終是雷克薩斯,在做工、用料方面,雷克薩斯還是比豐田領先,而且大雷還有免費保養政策呢。寶馬1系指導價:25。60-46。

在國內汽車市場還不是很發達的時候,國民的汽車都主要靠進口,然而時至今日,自主和合資品牌的車汽車都在逐漸壯大,看進口車的人也就逐漸少了。實際上進口車在机械品質和做工方面相對合資車的優勢並不大,但由於車企自身的計劃等各種原因,一些不錯的車子都只有進口沒有合資。今天提到的這幾款便是這樣的車型,重點是,它們的優惠還挺大。

沃爾沃V40

指導價:22.39-27.99萬

優惠幅度:2.5-3萬

如果讓叫獸總結一下V40的外觀設計,那叫獸只能說它真的是很“沃爾沃”。來自北歐的這個汽車品牌,雖已安全為本,但設計上有十分濃厚的自身特色。動感又不失高雅的車身線條,傾斜穿過車標的鍍鉻飾條,以及車尾的黑色后風擋邊框和“L”字形尾燈。都帶有濃濃的沃爾沃味道在裡頭。

V40的內飾依舊是熟悉的沃爾沃特色,面積不大的中控屏以及一大串類似於電話按鍵的中控按鍵,過複雜的按鍵實際上也不便於操作,然而沃爾沃依然在堅持。除此以外,V40也延續沃爾沃的傳統,有豐富的安全配置,通過中控屏可以一一進行查看和設置。

沃爾沃的座椅一直都是比較出色的,V40上的也一樣,十分厚實的填充、緊緻的包裹感、寬大的承托以及柔軟舒適的面料,座椅的舒適性極佳。空間方面,身高179cm的體驗者在後排能取得三指的腿部空間,至於頭頂就幾乎頂到車頂了,空間比較局促。

V40提供1.5T和2.0T兩種動力,分別提供最大152pS和190pS的馬力,均搭載6AT的手自一體變速箱。拿小排量的1.5T來說,動力系統響應靈敏,實際動力表現並不強勢,但也不至於表現出疲乏。懸挂的質感比較緊緻,但處理顛簸時還是不夠從容,少了幾分高級感。

總體來說,認為該車的行駛質感在緊湊型車來說還算很不錯的了,更何況V40延續了沃爾沃優秀的做工品質和豐富的安全性能。

雷克薩斯-CT

指導價:26.90-34.80萬

優惠幅度:5萬左右

從CT的外觀就可以看出它並不是要做一輛普通的兩廂小車,而是要做有個性的兩廂車。車頭依舊有熟悉的紡錘體格柵,前臉聚攏的線條會讓車頭更加有衝擊力,雖然這輛車並不是主打性能。

來到內飾,豪華感固然和同品牌的老大哥RX那些車系沒法比,但優質的用料、精緻的做工和層次分明的布局,還是讓CT充滿了雷克薩斯的味道。至於配置方面就十分厚道,常見的主動和被動安全配置還有無鑰匙啟動等等均為全系標配,就算買最低配的車型也不用擔心配置不夠用。

CT的織物座椅使用比較高檔的絨布面料,乘坐的質感比普通的織物要好上不少,配合運動化設計的座椅,提供很好的側向支撐。至於乘坐空間方面,身高174cm的體驗者在後排有4指的腿部和頭部空間,表現十分局促。

動力方面,CT全系搭載1.8L自吸發動機和豐田混動車特有的E-CVT變速箱,最大馬力僅有99pS,數據方面貌似並不出色。然而豐田的混動系統總能讓動力系統提供最優化的輸出,所以CT的動力表現並不會十分疲弱,滿足日常駕駛是卓卓有餘的。

你可能會說,差不多的動力系統,

※產品缺大量曝光嗎?你需要的是一流包裝設計!

窩窩觸角包含自媒體、自有平台及其他國家營銷業務等,多角化經營並具有國際觀的永續理念。

我為什麼不買更加便宜的卡羅拉或者雷凌雙擎?然而事實上,雷克薩斯始終是雷克薩斯,在做工、用料方面,雷克薩斯還是比豐田領先,而且大雷還有免費保養政策呢。

寶馬1系

指導價:25.60-46.90萬元

優惠幅度:7.5-8萬元

寶馬1系的車身造型十分緊湊和動感,前臉使用的絕對是寶馬的雙腎無疑的了,但新款1系的中網鍍鉻比舊款更加開揚、更具立體感了,而頭燈造型也變得更加有精神了。全LED光源的大燈,科技感十足啊。

1系的內飾依舊是典型的寶馬風格,環保式的中控台、懸浮式的6.5吋中控屏、以及整齊排列的物理按鍵。方向盤的面積不大,但十分粗壯,能增強駕駛者的駕駛慾望。而最新款的iDrive系統在15款車型已經搭載,支持藍牙音樂播放,說實話,這套iDrive真的不太好用。

座椅方面,現在全系車型都支持選裝真皮座椅了,不過即使是織物座椅,支撐性也是很好的,畢竟1系主打的駕駛樂趣嘛。至於後排空間,保持了一貫的狹窄,身高174cm的體驗者,只有一拳的腿部和四指的頭部空間。

動力方面,1系有四個不同版本的動力,從家用到性能都能夠滿足,全系標配8AT變速箱這點就比較優秀了。但即使是1.5T、136pS馬力的發動機也不容小覷,運動模式下依舊能給你不錯的推背感。至於底盤依舊的緊緻有韌性,十分靈敏,方向盤的虛位很小,雖然手感略沉,但轉向精準,買寶馬,買的就是這種駕駛樂趣啊。

靈活和精準,是給1系的關鍵詞,沒有超跑的狂飆、也沒有實用的空間,但當你在上下班通勤的路上感受了那份駕駛的樂趣以後,你就知道為什麼他們會選擇1系了。

奔馳A級

指導價:23.40-36.00萬元

優惠幅度:2萬左右

A級的造型就是在簡潔之中略帶動感,車身的線條還是偏向圓潤。前臉碩大的三叉星車標讓人一眼就看出了他的身份,而兩個大燈上自帶的日行燈也十分有科技感。而側面就能看到有上揚式的側麵線條,讓A級的外觀更加年輕化了。

內飾的豪華感雖然不強,但是在做工細緻,且加入了不少的運動話的元素來襯托它的定位。認為唯一的敗筆是懸浮式的中控屏,邊框的面積太大了,讓這个中控屏看起來一點都不高級。

皮革與織物混合的座椅面料,提供更好的防滑之餘又有不錯的質感。座椅已經不是傳統的奔馳座椅了,硬朗、包裹性強,所有的一切都是為了運動而準備。後排的空間是夠用的,身高175cm的人都能有一拳左右的腿部空間,只是後排又硬又短的座椅舒適性着實差。

動力方面,那A200來說,其動力系統其實和B200一樣,高功率的1.6T,152pS的馬力,但這對於身形更小,中心更低的A級來說會是更加刺激的動力輸出。底盤的調較已經放棄了奔馳的舒適,非常硬,而轉向則依舊輕盈,高速行駛的穩定性很好。

總結:買車,有時候買的更是一種生活,如果你真正載人的時間不是十分多的話,何不買一輛駕駛帶感,做工精緻的車來好好取悅自己呢?本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

上新台中搬家公司提供您一套專業有效率且人性化的辦公室搬遷、公司行號搬家及工廠遷廠的搬家服務

【極客思考】計算機網絡:Wireshark抓包分析TCP中的三次握手與四次揮手_包裝設計

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

上新台中搬家公司提供您一套專業有效率且人性化的辦公室搬遷、公司行號搬家及工廠遷廠的搬家服務

【摘要】本文重點分析計算機網絡中TCP協議中的握手和揮手的過程。

【前提說明】

前段時間突然看到了一篇關於TCP/IP模型的文章,心想這段時間在家裡也用wireshark抓了點包,那麼想着想着就覺得需要複習一下網絡知識,於是就有這篇博文的誕生。當然網上關於TCP相關的知識點也是芸芸,閑着無事也可以多google深入理解一下,本文重點在分析TCP協議中的握手和揮手的過程。

【抓包前準備】

既然要抓包,我的裝備是個人電腦,操作系統是Mac OS。抓包工具是wireshark,至於怎麼安裝和一些基本的操作,可以點擊參考這篇文章。

用本地電腦模擬server和client,都是localhost的地址,但是我選擇的是不同的端口進行標識。server的端口號:12345;client的端口號:50784。因為是用的本機做的實驗,所以wireshark監聽的不是網卡而是Loopback:lo0,如圖所示:

以下是我模擬client和server的代碼:

1)server端

-Python 代碼
01
#! /usr/bin/python
02
# -*- coding: utf-8 -*-
03
 
04
import socket
05
 
06
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
07
 
08
server_address = ('127.0.0.1', 12345)
09
print "Starting up on %s:%s" % server_address
10
sock.bind(server_address)
11
 
12
sock.listen(1)
13
 
14
while True:
15
    print "Waiting for a connection"
16
    connection, client_address = sock.accept()
17
 
18
    try:
19
        print "Connection from", client_address
20
 
21
        data = connection.recv(1024)
22
        print "Receive '%s'" % data
23
    finally:
24
        connection.close()

2)client端-Python 代碼

01
# /usr/bin/python
02
# -*- coding: utf-8 -*-
03
 
04
import socket
05
 
06
def check_tcp_status(ip, port):
07
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
08
 
09
    server_address = (ip, port)
10
    print 'Connecting to %s:%s.' % server_address
11
    sock.connect(server_address)
12
 
13
    message = "I'm TCP client"
14
    print 'Sending "%s".' % message
15
    sock.sendall(message)
16
 
17
    print 'Closing socket.'
18
    sock.close()
19
 
20
 
21
if __name__ == "__main__":
22
    print check_tcp_status("127.0.0.1", 12345)

代碼比較簡單,就是模擬了一次鏈接,可以多次執行client,client只要鏈接成功就會發送一句話“I’m TCP client”,server一直死循環監聽端口,並將接受到的信息打印到console中。

【結果分析】

看到上面的console輸出之後,我們看一下wireshark抓到的結果:

我用兩種顏色標了出來,可以看到黃色框中的序號為1、2、3的三次通信過程其實就是我們說的三次握手;握手建立之後的序號為4、5、6便為傳輸數據的過程;而序號7、8、9、10就是我們所說的四次揮手的過程。

我們再進一步細看下握手、揮手這倆過程。

三次握手

 

※產品缺大量曝光嗎?你需要的是一流包裝設計!

窩窩觸角包含自媒體、自有平台及其他國家營銷業務等,多角化經營並具有國際觀的永續理念。

我們來總結一下握手的規律:

  • 第一次握手:建立鏈接。客戶端發送鏈接的請求,發送SYN報文,將Seq設置為0。然後客戶端就進入了SYN_SEND狀態,等待服務器的確認。
  • 第二次握手:服務器收到客戶端的SYN報文段。需要對這個SYN報文段進行確認,發送ACK報文,並將Ack設置為1。同時,自己也要發送SYN請求信息,將Seq設置為0,。服務器將上述的所有信息一併發送給客戶端,此時服務器進入SYN_RECV狀態。
  • 第三次握手:客戶端收到服務器的ACK和SYN報文後,進行確認,然後將Ack設置為1,Seq設置為1,向服務器發送ACK報文段,這個報文段發送完畢之後,客戶端和服務器都進入了ESTABLISHED狀態。就此完成了TCP的三次握手。

四次揮手

 

接着總結下揮手的規律:

  • 第一次揮手:客戶端想服務器發送一個FIN報文段,將設置Seq為15和Ack為1。此時客戶端進入FIN_WAIT_1狀態。這表示客戶端沒有數據要發送服務器了,請求關閉連接。
  • 第二次揮手:服務器收到了客戶端發送的FIN報文段,向客戶端回一個ACK報文段,Ack設置為16,Seq設置為1;服務器進入了CLOSE_WAIT狀態,客戶端收到服務器返回的ACK報文之後隨即進入FIN_WAIT_2狀態。
  • 第三次揮手:服務器會觀察自己是否還有數據沒有發送給客戶端,如果有,先把數據發送給客戶端,再發送FIN報文;如果沒有,那麼服務器直接發送FIN報文給客戶端。請求關閉連接,同時服務器進入LAST_ACK狀態。
  • 第四次揮手:客戶端收到服務器發送的FIN報文,向服務器發送ACK報文,將Seq設置為16,Ack設置為2,然後客戶端進入TIME_WAIT狀態;服務器收到客戶端的ACK報文之後就關閉了連接;此時,客戶端等待2msl后依然沒有收到回復,則證明服務器已正常關閉,客戶端也可以關閉連接了。

注意個規律: 每次一方返回ACK報文的時候,設置Ack=對方傳來的Seq值+1。

【理解TCP/IP模型】

說完TCP協議之後,不能免俗的要聊一下TCP/IP協議模型,該模型是計算機網絡的經典的模型了。該模型由OSI模型演化而來,由原來的7層簡化為了5層,具體如下圖所示:

TCP/IP協議被稱為傳輸控制協議/互聯網協議,又稱網絡通訊協議(Transmission Control Protocol)。是由網絡層的IP協議和傳輸層的TCP協議組成,是一個很大的協議集合。

  • 物理層和數據鏈路層沒有定義任何特定協議,支持所有的標準和專用的協議。
  • 網絡層定義了網絡互聯也就是IP協議,主要包括IP、ARP、RARP、ICMP、IGMP。
  • 傳輸層定義了TCP和UDP(User Datagram Protocol),我們會後面重點介紹一下TCP協議。
  • 應用層定義了HTTP(超文本傳輸協議)、FTP(文件傳輸協議)、DNS(域名系統)等協議。

TCP/IP的網絡模型分層思想算是非常有借鑒性的系統分層思想。映射到我們的軟件系統上來看,其實我們的軟件系統更多的時候也需要考慮分層,層次之間通過接口來交互。在嚴格的分層系統里,內部的層只對相鄰的層次可見,這樣就可以將一個複雜問題分解成增量步驟序列。由於每一層最多隻影響兩層,也給維護帶來了很大的便利。

參考資料:

http://www.cnblogs.com/linyfeng/p/9496126.html

http://zhuanlan.zhihu.com/p/33797520

blog.csdn.net/zhzdeng/article/details/53490386

點擊關注,第一時間了解華為雲新鮮技術~

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網動廣告出品的網頁設計,採用精簡與質感的CSS語法,提升企業的專業形象與簡約舒適的瀏覽體驗,讓瀏覽者第一眼就愛上她。

一圖讀懂十九屆五中全會公報中的美麗中國_貨運

※評比南投搬家公司費用收費行情懶人包大公開

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

2020-11-01

2020-11-01
分享到:
[打印]
字號:[大] [中] [小]

※智慧手機時代的來臨,RWD網頁設計為架站首選

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

五部門聯合召開“美麗中國,我是行動者”主題實踐活動總結會_網頁設計公司

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

透過選單樣式的調整、圖片的縮放比例、文字的放大及段落的排版對應來給使用者最佳的瀏覽體驗,所以不用擔心有手機版網站兩個後台的問題,而視覺效果也是透過我們前端設計師優秀的空間比例設計,不會因為畫面變大變小而影響到整體視覺的美感。

2020-11-05 來源:生態環境部

2020-11-05
來源:生態環境部 分享到:
[打印]
字號:[大] [中] [小]

  11月5日,生態環境部、中央文明辦、教育部、共青團中央、全國婦聯等五部門聯合召開會議,總結“美麗中國,我是行動者”主題實踐活動成果,研究部署下一階段工作。生態環境部副部長庄國泰出席會議並講話。

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

節能減碳愛地球是景泰電動車的理念,是創立景泰電動車行的初衷,滿意態度更是服務客戶的最高品質,我們的成長來自於你的推薦。

  會議指出,生態環境領域宣傳和動員是黨的宣傳思想工作的重要組成部分。三年來,各部門各條戰線堅持以習近平新時代中國特色社會主義思想和習近平生態文明思想為指引,积極開展“美麗中國,我是行動者”主題實踐活動,生態文明建設主旋律持續高昂,生態環境保護正能量廣泛傳播,生態環境輿論主動局面更加強化,公眾參与環境保護渠道不斷拓展,全社會共建美麗中國熱情顯著提升,生態環境宣傳工作大格局初步形成,為打贏污染防治攻堅戰、建設美麗中國營造了良好社會氛圍。

  會議強調,黨的十九屆五中全會明確提出“十四五”和2035年生態文明建設和生態環境保護的目標任務,要圍繞大力宣傳習近平生態文明思想這一核心任務,持續深入開展“美麗中國,我是行動者”主題實踐活動,努力提升宣傳和動員工作能力和水平,着力推動構建生態環境治理全民行動體系。要深化重大理論研究宣傳,持續推進新聞宣傳,創新開展社會宣傳,不斷改進新媒體宣傳,穩步加強環境教育,推動形成人人關心、支持、參与生態環境保護的工作局面,為建設美麗中國夯實穩固社會基礎。

  中央文明辦、教育部、共青團中央、全國婦聯有關同志作了發言,江蘇、重慶、四川、內蒙古以及福建廈門、浙江湖州等6個地方代表進行經驗交流。

  會議以視頻形式召開,在生態環境部機關設主會場,在各省、市、縣生態環境部門及有關單位設3850個分會場,共14480人參加會議。

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

搬家費用:依消費者運送距離、搬運樓層、有無電梯、步行距離、特殊地形、超重物品等計價因素後,評估每車次單

孫金龍赴廣西調研省以下環保垂改工作_包裝設計

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網動廣告出品的網頁設計,採用精簡與質感的CSS語法,提升企業的專業形象與簡約舒適的瀏覽體驗,讓瀏覽者第一眼就愛上她。

2020-11-12 來源:生態環境部

2020-11-12
來源:生態環境部 分享到:
[打印]
字號:[大] [中] [小]   11月12日,生態環境部黨組書記孫金龍赴廣西南寧,調研省以下環保機構監測監察執法垂直管理改革工作(以下簡稱環保垂改)情況。他強調,要深入學習貫徹十九屆五中全會精神,按照中央巡視反饋意見整改工作要求,紮實推進環保垂改任務如期落實落地,進一步釋放改革紅利,助力“十四五”生態環境保護工作開好局、起好步。   孫金龍先後來到南寧市生態環境局、自治區生態環境廳主持召開座談會,分別聽取自治區、市、縣三級生態環境部門監測監察執法垂直管理改革落實情況的彙報。座談會上,大家總結了改革落實過程中的好做法好經驗,

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

上新台中搬家公司提供您一套專業有效率且人性化的辦公室搬遷、公司行號搬家及工廠遷廠的搬家服務

對一些具有共性、單靠基層又難以解決的突出問題,進行了深入探討交流,提出了下一步深入推進落實改革任務的意見建議。   孫金龍強調,習近平總書記早在黨的十八屆五中全會上就親自部署環保垂改任務,並就為什麼要改革和怎麼樣改革作了說明。黨中央、國務院印發《關於省以下環保機構監測監察執法垂直管理制度改革試點工作的指導意見》,要求“十三五”時期全面完成環保機構監測監察執法垂直管理制度改革任務。全國生態環境系統要切實增強“四個意識”、堅定“四個自信”、做到“兩個維護”,深刻認識到環保垂改是對地方生態環境管理體制整體重塑的一項重大改革舉措,進一步增強做好垂改工作的緊迫感、責任感和使命感。要有效銜接地方機構改革、綜合執法改革,有針對性地解決環保垂改落實過程中存在的問題,加快打造生態環境保護鐵軍,為精準治污、科學治污、依法治污提供堅強體制機制保障。   廣西壯族自治區政府副主席劉宏武出席座談會並陪同調研。中央編辦有關負責同志,生態環境部辦公廳、人事司主要負責同志參加調研和座談。   廣西壯族自治區生態環境廳主要負責同志及班子成員和有關負責同志;南寧市生態環境局主要負責同志及班子成員和有關負責同志;柳州市、賀州市、桂林市全州、來賓市忻城生態環境局主要負責同志參加座談會。

※產品缺大量曝光嗎?你需要的是一流包裝設計!

窩窩觸角包含自媒體、自有平台及其他國家營銷業務等,多角化經營並具有國際觀的永續理念。