[TOC]
>[success] # 響應式布局
本章主要對 **頁面布局** 來進行一些學習,包括 **3** 個內容:
1. **vue-cli3.0** 中使用 **iview**
2. **布局組件** 的使用
3. **柵格組件** 實現 **響應式布局**
>[success] ## vue-cli3.0 中使用 iview
接下來講解如何在 **vue-cli3.0** 中如何引入 **iview** ,以及如何 **配置** 它的 **iview-loader** ,如何 **全局引入** 、 **按需引入 iview** 。之前很多開發者都使用過 **iview** ,那么在 **vue-cli3.0** 中對 **iview** 的 **配置有一些改變** ,主要是在 **iview-loader** 這的 **配置有改變** ,因為在 **vue-cli3.0** 生成的項目中,是 **沒有 webpack 配置文件** 的 ,所以需要在 **vue.config.js** 里面去配置 **iview-loader** 。
1. **首先用 npm 安裝 iview**
如果是 **iview 3.1.0** 版本,我們可以使用 **vue ui** 進行安裝,步驟如下:
1. 執行指令
~~~
vue ui
~~~
2. 打開界面后選擇要安裝 **iview** 的項目

3. 點擊 **插件 > 添加插件**

4. 搜索插件進行安裝

5. 出現下面界面就進行安裝了

6. 安裝成功后會讓勾選3個選項, 如下圖:
選項1:**你想如何導入 ViewUI(iView)?** 默認是 **全局導入**
選項2:**你想覆蓋 ViewUI(iView) 的 Less 變量嗎?** 默認 **否**
選項3:**選擇要加載的語言環境** 默認 **zh-CN**

此時直接勾選下方 **完成安裝按鈕** 即可。
7. 也可以用**npm 指令安裝方式**
~~~
npm install iview
~~~
2. **全局引入iview**
**全局引入介紹** : **一次性引入全部 iview 組件** 。
在項目入口文件 **src\main.js** 中需要配置如下:
**src\main.js**
~~~
import Vue from 'vue'
import iview from 'iview' // 引入iview
import 'iview/dist/styles/iview.css' // 引入iview樣式
Vue.use(iview)?//?iview作為插件,需要用Vue.use方法來引入
~~~
3. **按需引入**
**按需引入介紹**: **iview** 中有很多 **組件** ,項目中有些 **組件** 可能用不到,如果使用 **全局引入** 的方式,就會 **增大了編譯后的文件體積** ,所以可以使用 **按需引入** , 用哪個 **組件** ,就在 **全局里把它引入**,然后 **打包后的文件體積就會小很多** ,如果項目基本上用到所有組件,還是用**全局引入**。
1. 首先你需要 **安裝一個 babel 插件**
~~~
npm install babel-plugin-import --save-dev
~~~
2. 在 **vue-cli3.0** 生成的項目中,**babel** 的配置文件 **babel.config.js**,**默認配置** 是這樣的:
~~~
module.exports = {
presets: [
'@vue/app'
]
}
~~~
需要把剛剛安裝的插件添加進去,添加后的內容如下:
~~~
module.exports = {
presets: [
'@vue/app'
],
'plugins': [['import', {
'libraryName': 'iview', // 倉庫名字
'libraryDirectory': 'src/components' // 倉庫的文件夾
}]]
}
~~~
3. 接下來在 **main.js** 里,可以這樣 **按需引入** :
~~~
import 'iview/dist/styles/iview.css' // iview的樣式文件還是要引入的
import { Button, Table } from 'iview' // 用ES6的解構賦值,來按需引入使用的組件
Vue.component('Button', Button) // 注冊組件,Vue.component('組件名字', 引進來的組件)
~~~
4. **需要注意**
問題:在 **非template/render模式** 下,包括 **JSX** 寫法中,**組件名** 要用 **分隔形式**,如 **DataPicker** 要寫為 **data-picker** ,而對于 **iview** 中名稱和 **原生HTML標簽** 相同的 **組件**,需要加 **i-前綴** ,如 **Button** 要寫成 **i-button**。
解決辦法: **我們可以通過配置 iview-loader 來解決 Switch 在任何模式下都必須寫為 i-switch ,Cirele要寫為 i-cirele的問題。**
4. **vue-cli3.0中配置iview-loader**
1. 首先需要 **安裝 iview-loader**
~~~
npm install iview-loader --save-dev
~~~
2. 在 **vue.config.js** 中添加 **iview-loader**
~~~
const path = require('path') // 引入nodejs的path模塊
const resolve = dir => path.join(__dirname, dir) // resolve方法用來加載路徑
const BASE_URL = process.env.NODE_ENV === 'production' ? '/iview-admin/' : '/' // 判斷當前為開發環境還是打包環境, '/'意思是代表指定在域名的根目錄下,如果要指定到iview-admin下就這樣寫'/iview-admin/', production為生產壞境,development為開發環境
module.exports = {
lintOnSave: false, // 取消每次保存時都進行一次' ESLint '檢測
publicPath: BASE_URL, // 項目的基本路徑,vuecli2.0時打包經常靜態文件找不到,就是需要配置這個屬性為'./'
chainWebpack: config => { // 配置Webpack
config.resolve.alias
.set('@', resolve('src')) // 引入文件時候“ @ ”符號就代表src
.set('_c', resolve('src/components')) // 引入組件文件夾中的文件就可以用“ _c ”代替src/components
config.module // 添加iview-loader
.rule('vue')
.use('iview')
.loader('iview-loader')
.options({ prefix: false })
},
productionSourceMap: false, // 打包時不生成.map文件,會減少打包體積,同時加快打包速度
devServer: { // 跨域有2種解決方案: 1. 在后端的header中配置, 2. 使用devServer來配置代理解決跨域
proxy: 'http://localhost:3000/' // 這里寫需要代理的URL,這里會告訴開發服務器,將任何未知請求匹配不到靜態文件的請求,都代理到這個URL來滿足跨域
}
}
~~~
在 **chainWebpack** 中 **鏈式調用** 方法來添加 **iview-loader** ,這樣使用組件時候就可以不寫 **i-前綴** 了。
5. **注意**
如果使用的是 **全局引入** ,不要配置這個 **babel插件** ,如果配置了 **babel插件** ,會在 **main.js** ,**報一個錯誤:import iview from 'iview' 它會報 iview 為 undefined**
>[success] ## 布局組件的使用
使用 **iview** 中的 **layout組件** 來進行一個 **頁面的總體布局** ,里面包括幾個**組件**:**Header** 、 **Sider** 、 **Content** 、 **Footer** ,以及 **最外層** 的 **Layout** ,這 **5個組件** 。
>[success] ## 柵格組件實現響應式布局
使用 **iview** 的 **柵格組件(row、col)** ,來實現 **響應式布局** ,能夠 **根據網頁寬度實現不同的布局** 。
**實現效果圖**:

**GIF動圖**:
支持 **展開收起側邊欄** ,以及 **嵌套路由** 跳轉頁面

1. **創建一個 layout.vue 文件**
**src/views/layout.vue**
~~~
<template>
<div class="layout-wrapper">
<Layout class="layout-outer">
<!-- 側邊欄 -->
<Sider collapsible hide-trigger breakpoint="sm" v-model="collapsed"></Sider>
<!-- 布局容器 -->
<Layout>
<!-- 頂部布局 -->
<Header class="header-wrapper">
<Icon :class="triggerClasses" @click.native="handleCollapsed" type="md-menu" :size="32" />
</Header>
<!-- 內容部分 -->
<Content class="content-con">
<Card shadow class="page-card">
<!-- 做【嵌套路由】,用于展示子路由 -->
<router-view />
</Card>
</Content>
</Layout>
</Layout>
</div>
</template>
<script>
export default {
data(){
return{
collapsed: false // 控制收縮變量
}
},
computed: {
triggerClasses(){
return [
'trigger-icon',
this.collapsed ? 'rotate' : ''
]
}
},
methods: {
// 展開 / 收起
handleCollapsed(){
this.collapsed = !this.collapsed
}
}
}
</script>
<style lang="scss">
.layout-wrapper,.layout-outer{
height: 100%;
.header-wrapper{
background: #fff;
box-shadow: 0 1px 1px 1px rgba($color: #000000, $alpha: .1);
padding: 0 23px;
.trigger-icon{
cursor: pointer;
&.rotate{
transform: rotateZ(-90deg);
transition: transform .3s ease;
}
}
}
.content-con{
padding: 10px;
.page-card{
min-height: calc(100vh - 84px);
}
}
}
</style>
~~~
**嵌套路由** 頁面,**Home.vue**
**src/views/Home.vue**
~~~
<template>
<div class="home">
<Row>
<i-col></i-col>
</Row>
<Row :gutter="10">
<i-col span="12"></i-col>
<i-col span="12"></i-col>
</Row>
<Row :gutter="10" class="blue">
<i-col :md="6" :sm="12"></i-col>
<i-col :md="6" :sm="12"></i-col>
<i-col :md="6" :sm="12"></i-col>
<i-col :md="6" :sm="12"></i-col>
</Row>
</div>
</template>
<style lang="scss">
.home{
.ivu-col{
height: 50px;
background: pink;
margin-top: 10px;
background-clip: content-box;
}
.blue{
.ivu-col{
background: blue;
background-clip: content-box;
}
}
}
</style>
~~~
2. **在路由中配置,把 layout 作為首頁展示**
**src/router/router.js**
~~~
import Home from '@/views/Home'
import Layout from '@/views/layout'
export default [
{ // 把 Layout 作為首頁展示
path: '/',
name: 'home',
component: Layout,
children: [ // 創建嵌套路由
{
path: 'home',
component: Home
}
]
},
{
path: '/login',
name: 'login',
component: () => import('@/views/login.vue'),
},
{
path: '*', // * 符號,代表匹配任何的路徑
component: () => import('@/views/error_404.vue')
}
]
~~~
3. **調整頁面高度**
現在的 **頁面高度** 是 **0** ,如果想調整 **高度** ,需要調整 **app.vue** 頁面的 **高度**
**src/App.vue**
~~~
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style lang="scss">
html,body,#app{
height: 100%;
}
body{
margin: 0;
}
</style>
~~~
- vue 26課
- Vue-cli3.0項目搭建
- Vue-ui 創建cli3.0項目
- Vue-ui 界面詳解
- 項目目錄詳解
- public文件夾
- favicon.ico
- index.html
- src文件夾
- api文件夾
- assets文件夾
- components文件夾
- config文件夾
- directive文件夾
- lib文件夾
- mock文件夾
- mock簡明文檔
- router文件夾
- store文件夾
- views文件夾
- App.vue
- main.js
- .browserslistrc
- .editorconfig
- .eslintrc.js
- .gitignore
- babel.config.js
- package-lock.json
- package.json
- postcss.config.js
- README.en.md
- README.md
- vue.config.js
- Vue Router
- 路由詳解(一)----基礎篇
- 路由詳解(二)----進階篇
- Vuex
- Bus
- Vuex-基礎-state&getter
- Vuex-基礎-mutation&action/module
- Vuex-進階
- Ajax請求
- 解決跨域問題
- 封裝axios
- Mock.js模擬Ajax響應
- 組件封裝
- 從數字漸變組件談第三方JS庫使用
- 從SplitPane組件談Vue中如何【操作】DOM
- 渲染函數和JSX快速掌握
- 遞歸組件的使用
- 登陸/登出以及JWT認證
- 響應式布局
- 可收縮多級菜單的實現
- vue雜項
- vue遞歸組件
- vue-cli3.0多環境打包配置
- Vue+Canvas實現圖片剪切
- vue3系統入門與項目實戰
- Vue語法初探
- 初學編寫 HelloWorld 和 Counter
- 編寫字符串反轉和內容隱藏功能
- 編寫TodoList功能了解循環與雙向綁定
- 組件概念初探,對 TodoList 進行組件代碼拆分
- Vue基礎語法
- Vue 中應用和組件的基礎概念
- 理解 Vue 中的生命周期函數
- 常用模版語法講解
- 數據,方法,計算屬性和偵聽器
- 樣式綁定語法
- 條件渲染
- 列表循環渲染
- 事件綁定
- 表單中雙向綁定指令的使用
- 探索組件的理念
- 組件的定義及復用性,局部組件和全局組件
- 組件間傳值及傳值校驗
- 單向數據流的理解
- Non-Props 屬性是什么
- 父子組件間如何通過事件進行通信
- 組件間雙向綁定高級內容
- 使用匿名插槽和具名插槽解決組件內容傳遞問題
- 作用域插槽
- 動態組件和異步組件
- 基礎語法知識點查缺補漏
- Vue 中的動畫
- 使用 Vue 實現基礎的 CSS 過渡與動畫效果
- 使用 transition 標簽實現單元素組件的過渡和動畫效果
- 組件和元素切換動畫的實現
- 列表動畫
- 狀態動畫
- Vue 中的高級語法
- Mixin 混入的基礎語法
- 開發實現 Vue 中的自定義指令
- Teleport 傳送門功能
- 更加底層的 render 函數
- 插件的定義和使用
- 數據校驗插件開發實例
- Composition API
- Setup 函數的使用
- ref,reactive 響應式引用的用法和原理
- toRef 以及 context 參數
- 使用 Composition API 開發TodoList
- computed方法生成計算屬性
- watch 和 watchEffect 的使用和差異性
- 生命周期函數的新寫法
- Provide,Inject,模版 Ref 的用法
- Vue 項目開發配套工具講解
- VueCLI 的使用和單文件組件
- 使用單文件組件編寫 TodoList
- Vue-Router 路由的理解和使用
- VueX 的語法詳解
- CompositionAPI 中如何使用 VueX
- 使用 axios 發送ajax 請求
- Vue3.0(正式版) + TS
- 你好 Typescript: 進入類型的世界
- 什么是 Typescript
- 為什么要學習 Typescript
- 安裝 Typescript
- 原始數據類型和 Any 類型
- 數組和元組
- Interface- 接口初探
- 函數
- 類型推論 聯合類型和 類型斷言
- class - 類 初次見面
- 類和接口 - 完美搭檔
- 枚舉(Enum)
- 泛型(Generics) 第一部分
- 泛型(Generics) 第二部分 - 約束泛型
- 泛型第三部分 - 泛型在類和接口中的使用
- 類型別名,字面量 和 交叉類型
- 聲明文件
- 內置類型
- 總結