vue&vue-cli 3.0项目中遇到的有趣问题(五)
- 1、自定义字体在ios系统上不生效的问题
- 2、阻止网页的自动翻译问题
- 3、常用方法总结
- 4、template解决v-for,v-if共用问题
- 5、mixin混入的使用
- 6、设置网页标题
- 7、history模式下的问题
- 8、css和scss自定义全局变量
- 9、自定义全局指令
- 10、自定义全局插件
- 11、自定义全局组件
- 12、全局禁用alert
1、自定义字体在ios系统上不生效的问题
背景:博主最近在开发的时候,在项目里引入了设计提供的第三方字体,在电脑和安卓手机上是正常的,但是在苹果手机上却不能生效,最后发现是 ios尚不支持该字体,不同的系统所支持的字体格式也有所不同:
经过查找,我找到一个fontmin插件,进行字体转化生成格式字体,fontmin插件使用如下:
《压缩工具是“ fontmin ”》 最后在项目中的全局字体文件里,赋值粘贴刚生成的css内容即可,注意路径的改变:
@font-face {
font-family: "PingFangSC";
src: url("PingFang-Medium.eot"); /* IE9 */
src: url("PingFang-Medium.eot?#iefix") format("embedded-opentype"), /* IE6-IE8 */
url("PingFang-Medium.woff") format("woff"), /* chrome, firefox */
url("PingFang-Medium.ttf") format("truetype"), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url("PingFang-Medium.svg#PingFangSC") format("svg"); /* iOS 4.1- */
font-style: normal;
font-weight: normal;
}
2、阻止网页的自动翻译问题
博主最近发现之前上线的项目,在不同用户的谷歌浏览器上面展示的内容存在差异,最后检查发现是浏览器的自动翻译导致的,但是不同用户可能存在不同的翻译设置,那只能全部一起禁用,即页面打开的时候无法自动翻译,经过查找我找到了以下的解决措施:
将项目模板html中的lang改成“zh-CN”
即:<html lang="zh-CN">
再在head里添加以下内容:<meta name="google" content="notranslate">
,即谷歌禁止翻译
全部代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="google" content="notranslate">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
3、常用方法总结
4、template解决v-for,v-if共用问题
template的作用是模板占位符,可帮助我们包裹元素,但在循环过程当中,template不会被渲染到页面上。
平时我们在开发过程中会遇到一种情况,遍历体会有if判断条件来进行展示这时候我们可能会想到在v-for使用v-if如:
<div class="my-list" v-for="(item,index) in list" :key="index" v-if="index%2===0">{{item}}</div>
但是由于v-for优先级比v-if高会造成不必要的资源浪费。
那怎么办呢:
1、解决方法1——外围再套一层div
<div class="my-list-content" v-for="(item,index) in list" :key="index">
<div class="my-list" v-if="index%2===0">{{item}}</div>
</div>
但是这会多出来,一层没有什么事作用的div demo。
2、解决方法2——template
<template v-for="(item,index) in list">
<div :key="index" class="my-list" v-if="index%2===0">{{item}}</div>
</template>
template可以很好地解决v-for,v-if共用的问题,以及解决多出无用元素的问题。但是需要注意的是,template本事不可以设置:key属性,只能复杂它的子级上,所以如果有多个子级那么每个子级都需要赋值key。
<template v-for="(item,index) in list">
<div :key="index+'list'" class="my-list">{{item}}</div>
<div :key="index+'list1'" class="my-list1">{{item}}</div>
<div :key="index+'list2'" class="my-list2">{{item}}</div>
</template>
5、mixin混入的使用
混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。混入对象可以包含任意组件选项,可以定义Data、methods、Components、LifeCycle Hooks(生命周期函数)、Directives(指令)、路由钩子函数等。
场景运用:
有两个非常相似的组件,他们的基本功能是一样的,但他们之间又存在着足够的差异性。他们可能会公用一部分业务逻辑,但是他们的页面结构又不相同。这个时候就可以使用mixin来让代码复用。(类似于JS库,暴露出来的方法达到函数复用的效果。又区别于JS库,它继承了vue中script所有对象,包括生命周期,data,methods)
编写一个混入文件:
Mixin.js
export default {
data () {
return {
// 商品展示
productShow: false,
// 视频加载
isVideoOk: false
};
},
mounted () {},
computed: {},
methods: {
// 视频播放
setPlay () {
const myVideo = this.$refs.myVideo;
if (myVideo) {
myVideo.play();
}
},
// 展示商品列表
handlePlpOpen () {
this.productShow = true;
},
// 关闭商品列表
handlePlpClose () {
this.productShow = false;
},
// 页面刷新
handleReload () {
this.$router.go(0);
},
// 全屏
setVideoFull () {
const myVideo = this.$refs.myVideo;
if (myVideo) {
myVideo.webkitRequestFullScreen();
}
}
}
};
混入文件引入:
1-局部混入
import Mixin from '../Mixin/Mixin.js' // 首先引入这个混入对象
export default {
mixins:[Mixin], // 然后注册你引入的这个混入对象
}
2-全局混入
在main.js中添加以下代码:
import Mixin from '../Mixin/Mixin.js'
Vue.mixin(Mixin);
混入规则:
1、data、computed等数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先;
2、created、mounted等同名钩子函数会合并成一个数组,都将被调用。但混入对象的钩子会在组件自身的钩子之前调用。
3、components、methods、directives等对象会被合并为同一对象。如果出现了相同键值对,则当前组件中的键具有优先级
注意:
慎用全局混入,如果使用了全局混入,那么将影响每一个新创建的Vue实例
6、设置网页标题
我们在开发网页的时候经常发现网页有对应的页面标题,这是怎么设置的呢。
如下:
1、在vue.config.js中添加以下内容:
module.exports = {
chainWebpack: config => {
config
.plugin('html')
.tap(args => {
args[0].title = '页面标题';
return args;
});
}
};
2、添加路由守卫:
router.beforeEach((to, from, next) => {
if (to.meta.title) {
document.title = '页面标题' + '-' + to.meta.title;
}
next();
});
7、history模式下的问题
1、history模式下静态资源以及多重路径(父子级路由)的访问问题:
实际问题是项目配置的访问路径的问题只需要在vue.config.js文件里添加以下代码
module.exports = {
publicPath: '/', // 访问路径
outputDir: 'dist', // 打包文件
assetsDir: 'static', // 静态资源包
};
2、history模式下build打包文件无法直接访问问题:
经过查阅,这种模式下本身就是无法直接访问,如果我想要访问,只能起服务访问,按照官方给出的方法需要使用express
connect-history-api-fallback
插件
1、先npm安装两者
2、在项目外围添加文件:
prod.server.js
// 引入express
const express = require('express');
// 引入中间件,解决history模式
const history = require('connect-history-api-fallback');
// 监听的端口
const port = 9998;
const app = express();
// 使用中间件
app.use(history());
// 设置静态文件路径
app.use(express.static('./dist'));
// 监听端口
module.exports = app.listen(port, function (err) {
if (err) {
console.error(err);
} else {
console.log(`项目启动成功,服务运行在\nhttp://localhost:${port}\n`);
}
});
3、在package.json中添加运行指令:
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"review": "node prod.server.js" // 新增
},
4、启动服务,访问打包文件:npm run review
8、css和scss自定义全局变量
背景:平时我们在开发页面的时候,对于一些全局都是用的属性,比如页面主题色,这个时候我们就可以设置一个css的全局变量,后期需要改颜色的时候,直接改这个全局颜色就可以了。
博主平时使用css样式和scss样式比较多,那就以这两个为例:
1、css全局变量
// css版
body {
--themeColor: #42b983;
--fontColor: #231815;
--themeBackColor: #42b983;
}
调用:
html {
font-size: 14px;
color: var(--themeColor);
}
2、scss全局变量
// scss版
$themeColor: #42b983;
$fontColor: #231815;
$themeBackColor: #42b983;
配置scss全局的支持
module.exports = {
css: {
loaderOptions: {
sass: {
prependData: `
@import "@/assets/styles/theme.scss";
`
}
}
}
};
调用:
html {
font-size: 14px;
color: $themeColor;
}
9、自定义全局指令
《在Vue项目中自定义全局指令》
10、自定义全局插件
《在Vue项目中自定义全局插件——全局Loading插件》
11、自定义全局组件
12、全局禁用alert
在项目模板html里添加以下js
<script type="text/javascript">
window.alert = (e) => {
return false;
}
</script>