[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** 的项目
![](https://img.kancloud.cn/a7/b2/a7b219d4b55d46c88a985df1dd23c4b6_1920x937.png)
3. 点击 **插件 > 添加插件**
![](https://img.kancloud.cn/57/64/576443503fbc8fb1647ec860e4e7ac92_1920x937.png)
4. 搜索插件进行安装
![](https://img.kancloud.cn/74/84/748479874c1fae9e3e415b9391cf4105_1920x937.png)
5. 出现下面界面就进行安装了
![](https://img.kancloud.cn/5c/60/5c60e739e3b49502a3fa1df1a9195bfb_1074x624.png)
6. 安装成功后会让勾选3个选项, 如下图:
选项1:**你想如何导入 ViewUI(iView)?** 默认是 **全局导入**
选项2:**你想覆盖 ViewUI(iView) 的 Less 变量吗?** 默认 **否**
选项3:**选择要加载的语言环境** 默认 **zh-CN**
![](https://img.kancloud.cn/6e/8b/6e8b6d0388508cbad6de51510b0dcf72_1920x937.png)
此时直接勾选下方 **完成安装按钮** 即可。
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)** ,来实现 **响应式布局** ,能够 **根据网页宽度实现不同的布局** 。
**实现效果图**:
![](https://img.kancloud.cn/52/8d/528d4cbc5249234f3ee1db091b903289_1920x937.png)
**GIF动图**:
支持 **展开收起侧边栏** ,以及 **嵌套路由** 跳转页面
![](https://img.kancloud.cn/4d/8b/4d8be99037f046173f6d5c92fe327bb0_1831x967.png)
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) 第二部分 - 约束泛型
- 泛型第三部分 - 泛型在类和接口中的使用
- 类型别名,字面量 和 交叉类型
- 声明文件
- 内置类型
- 总结