一、全屏案例
全屏与正常视图的切换在系统中很常见,现在简单记录下在vue2项目中如何开发全屏与正常视图的切换。这里需要下载全屏插件 screenfull.js 插件。
1. 安装插件依赖。
npm install screenfull@5.1.0 --save
值得一提的是,如果不指定插件的版本,默认是安装最新版本的。但在vue2项目中,安装6.0版本的全屏插件会报错,所以在vue2项目中需要指定插件的版本为 5.1.0 。
2. 定义一个全屏公共组件,这里的路径为 src/components/Fullsceen/index.vue
import screenfull from 'screenfull'
3. 定义一个图标,并为其设置一个点击事件,因为svg是没有原生事件的,所以在父容器上设置点击事件。
<template>
<div @click="toggleClick">
<svg-icon v-if="this.isFullscreen" icon-class="half-screen"></svg-icon>
<svg-icon v-else icon-class="full-screen"></svg-icon>
</div>
</template>
如果当前状态是满屏,则显示一种图标。如果不是满屏,则显示另外一种图标
在阿里图标库中找到合适的图标,下载格式为svg,会得到一个压缩包,解压后复制svg文件重命名,将文件放在 src/icons/svg 目录下。当然也可以elementUI 的图标。然后定义文本标签,如 <i></i> <span></span> 等,复制图标样式类名即可。
由于引入图标后发现大小不合适,所以需要重写样式
<style scoped>
.svg-icon[data-v-c8a70580] {
display: inline-block;
width: 25px;
height: 25px;
margin: 10px 0;
color: #000 !important
}
</style>
4. 在钩子函数中,初始化是当前是否满屏。
data () {
return {
// 默认不全屏
isFullscreen: false,
}
},
mounted() {
screenfull.on("change", () => {
if (!screenfull.isFullscreen) {
this.isFullscreen = false;
} else {
this.isFullscreen = true;
}
})
},
5. 定义点击事件方法,方法名与 svg 标签父容器定义的方法名一致。
methods: {
toggleClick() {
if (!screenfull.isEnabled) {
this.$message({ message: '您的浏览器不支持全屏', type: "warning" })
return false;
}
this.isFullscreen = !this.isFullscreen;
// 调用 screenfull.toggle() 可以双向切换全屏与非全屏(map_container 需要全屏的元素)
screenfull.toggle(document.getElementById('map_container'));
},
}
6. 将上面的全屏组件在导航栏组件(src/layout/components/Navbar.vue)中引入、注册、使用组件 。即在全屏组件的父组件中引入使用。
7. 运行项目后效果如下:
正常情况
全屏情况
全屏组件代码
<template>
<div @click="toggleClick">
<svg-icon v-if="this.isFullscreen" icon-class="half-screen"></svg-icon>
<svg-icon v-else icon-class="full-screen"></svg-icon>
</div>
</template>
<script>
import screenfull from 'screenfull'
export default {
name: 'FullScreen',
data () {
return {
// 默认不全屏
isFullscreen: false,
}
},
mounted() {
screenfull.on("change", () => {
if (!screenfull.isFullscreen) {
this.isFullscreen = false;
} else {
this.isFullscreen = true;
}
})
},
methods: {
toggleClick() {
if (!screenfull.isEnabled) {
this.$message({ message: '您的浏览器不支持全屏', type: "warning" })
return false;
}
this.isFullscreen = !this.isFullscreen;
// 调用 screenfull.toggle() 可以双向切换全屏与非全屏(map_container 需要全屏的元素)
screenfull.toggle(document.getElementById('map_container'));
},
}
}
</script>
<style scoped>
.svg-icon[data-v-c8a70580] {
display: inline-block;
width: 25px;
height: 25px;
margin: 10px 0;
color: #000 !important
}
</style>
二、screenfull 插件API
- request(ele) 全屏
- exit() 退出全屏
- toggle() 切换全屏
- on(event, function) :event为 ‘change’ | ‘error’ 注册事件
- off(event, function) : 移除前面已经注册的事件
- element: 返回一个全屏的dom节点,如果没有就为 null
- isFullscreen : 是否是全屏状态
- isEnabled :判断是否支持全屏
三、SVG 图标的使用
1. 安装依赖
npm install svg-sprite-loader --save
2. .配置加载器和路径
不同版本的脚手架的项目结构会有差异,通常需要再vue.config.js文件下配置的,但是少数脚手架并没有这个文件,但是有build文件夹,因此需要再build文件夹下的webpack.base.conf.js进行配置,如非上诉两种情况,则需要再主目录下创建一个vue.config.js文件。
2. 1 在 vue.config.js文件下配置
'use strict'
function resolve(dir) {
return path.join(__dirname, dir)
}
module.exports = {
/* svg 相关配置 */
chainWebpack: config => {
config.module
.rule('svg')
.exclude.add(resolve('src/assets/icons')) //svg文件位置
.end()
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(resolve('src/assets/icons')) //svg文件位置
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()
}
}
2.2 在 webpack.base.conf.js文件下配置
在该文件下找到rules,在rules这个数组中添加对应的配置(如下)
module.exports = {
module: {
rules: [
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
exclude:[resolve('src/assets/icons/svg')], //在原有的图片加载的对象里添加这个
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.svg$/,
loader: 'svg-sprite-loader',
include: [resolve('src/assets/icons/svg')], // 这里是你放svg的文件夹
options: {
symbolId: 'icon-[name]'// 一定要加,要不然svg会无效
}
}
]
},
}
3. 封装 svg 组件
在src/components/svgIcon/ 目录下新建 index.vue 组件
<template>
<div
v-if="isExternal"
:style="styleExternalIcon"
class="svg-external-icon svg-icon"
v-on="$listeners"
/>
<svg
v-else
:class="svgClass"
aria-hidden="true"
v-on="$listeners"
>
<use :xlink:href="iconName" />
</svg>
</template>
<script>
import { isExternal } from "@/utils/validate";
export default {
name: "SvgIcon",
props: {
iconClass: {
type: String,
required: true
},
className: {
type: String,
default: ""
}
},
computed: {
isExternal() {
return isExternal(this.iconClass);
},
iconName() {
return `#icon-${this.iconClass}`;
},
svgClass() {
if (this.className) {
return "svg-icon " + this.className;
} else {
return "svg-icon";
}
},
styleExternalIcon() {
return {
mask: `url(${this.iconClass}) no-repeat 50% 50%`,
"-webkit-mask": `url(${this.iconClass}) no-repeat 50% 50%`
};
}
}
};
</script>
<style scoped>
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
.svg-external-icon {
background-color: currentColor;
mask-size: cover !important;
display: inline-block;
}
</style>
4.注册组件为全局
与存放svg图标的同级目录中新建一个index.js 文件(src/icons/index.js)。并将其导入到main.js。
import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon'// svg component
// register globally
Vue.component('svg-icon', SvgIcon)
const req = require.context('./svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys().map(requireContext)
requireAll(req)
5. 使用