配置路径@(一般情况下搭建vue-cli,项目已经配置好了@路径。若自己需要改动可按照一下方法)
vue-cli 2.x 版本创建项目时,我们可以在 build 文件夹下找到 webpack.base.conf.js 文件,在里面修改 resolve.alias 即可 resolve: { extensions: ['.js', '.vue', '.json'], alias: { 'vue$': 'vue/dist/vue.esm.js', '@': resolve('src'), } }, vue-cli 3.0 创建项目时,目录结构精简化,找不到 build 和 config 文件夹,那么该如何修改路径别名呢? 由于vue-cli 3.0 版本所有的配置项都放在了 vue.config.js 文件中,所以在里面进行配置就好了,代码如下: const path = require('path'); function resolve (dir) { return path.join(__dirname, dir) } // 项目的主要配置文件 module.exports = { // webpack 配置进行更细粒度的修改 https://cli.vuejs.org/zh/config/#chainwebpack chainWebpack: (config)=>{ //修改文件引入自定义路径 config.resolve.alias .set('@', resolve('src')) .set('style', resolve('src/assets/style')) } } 配置好想用的路径别名后,重新启动项目,再引入文件时,使用别名即可 import Demo from '@/demo/demoweb'
使用iconfont
1、在assets文件夹下新建iconfont文件夹 2、从iconfont下载字体图标包,下载下来之后,将文件中的这6个文件放入iconfont中(见下图) 3、在main.js中引入:import './assets/iconfont/iconfont.css' (若有报错,安装css-loader包)
如何实现横向滚动(兼容safari,微信,浏览器)
实现横向滚动需要以下几点: 1、设置width:2000px这种大的宽度 2、父级盒子要overflow-y:hidden;overflow-x:auto来防止页面宽度溢出,以及实现左右滚动效果 3、::-webkit-scrollbar { display: none;}隐藏横向滚动条(此方法在ios和微信端无效),所以第四步实现兼容 4、滚动条所存在的盒子为g,g之外再设置一个父盒子s并给定高度和overflow:hidden。通过s来遮盖g的滚动条即可实现隐藏滚动条。 示例: <template> <div class="university"> <div class="container"> <div class="scrollHidden"> <!--此盒子设置:height,overflow:hidden--> <div class="body"> <!--此盒子设置:滚动条overflow-y:hidden,overflow-x:auto,滚动条display:none,padding-bottom--> <ul class="body_content"> <!--此盒子设置 :2000px宽度--> <li v-for="(item,index) in universityList" :key="index" class="every_content"> <!--此盒子设置: 浮动--> <div class="content_img"><img :src="item.pimage" /></div> <div class="content_name">{{item.pname}}</div> </li> </ul> </div> </div> </div> </div> </template> <script></script> <style scoped lang="less"> .university{ .container{ .scrollHidden{ height:152px; //7、设置固定高度(以子盒子为准) overflow:hidden; //8、超出部分影隐藏 .body{ overflow-y: hidden; //2、父级盒子:竖向超出部分隐藏 overflow-x: auto; //3、父级盒子:控制横向可滚动,配合overflow-y:hidden共同控制内容不溢出当前屏幕 &::-webkit-scrollbar { //4、父级盒子:隐藏滚动条(不兼容ios和微信端) display: none; } padding-bottom: 100px; //5、通过padding-bottom将滚动条挤到盒子外 .body_content{ list-style: none; width:2000px; //1、子级盒子:设置一个大的宽度,如2000,3000等 .every_content{ height:150px; margin-right: 25px; margin-bottom: 10px; float: left; //6、展示内容的盒子,设置浮动 text-align: center; } } } } } } </style>
实现一个固定区域内竖向滚动
竖向滚动如果不隐藏滚动条,会简单很多,以下两个样式就够了。若要隐藏滚动条,参考上面横向滚动配置 <div class="srollContent"> <ul> <li>......</li> <li>......</li> </ul> </div> <style scoped lang="less"> .scrollContent{ height:300px; //固定父盒子高度 overflow:auto; //超出部分会以滚动条形式展示 } </style>
安利一个不错的叙述vue移动端经验的博客
https://www.cnblogs.com/wdlhao/p/9393539.html
v-if简单使用
<li class="every_content" v-for="(item,index) in heros" :key="index"> <i v-if="item.type==0">我是亚索</i> <i v-else-if="item.type==1">我是剑姬</i> <i v-else-if="item.type==2">我是卡萨</i> <i v-else-if="item.type==3">我是狮子狗</i> </li>
左侧图片右侧文字布局:图片宽度固定的,现在要实现当屏幕宽度改变时,右侧文字描述部分宽度自适应。
1、使用flex布局可以解决左右布局宽度自适应问题 2、但是flex布局时,若有文字溢出时展示省略号的需求,则需要配合overflow:hidden才可以 示例: <div class="body"> <ul class="bodyContent"> <li class="everyContent" v-for="(item,index) in hotProductInfo" :key="index"> <div class="contentImg"><img :src="item.pictures"/></div> <!--左侧图片--> <div class="contentDetails"> <!--右侧文字描述--> <div class="intro">{{item.intro}}</div> </div> </li> </ul> </div> <style scoped lang="less"> .body{ .bodyContent{ .everyContent{ display: flex; //1、flex布局 .contentImg{ margin-right: 10px; img{ width:140px; height:80px; } } .contentDetails{ flex:auto; //2、flex:1,auto都可以。右侧文字描述部分宽度自适应 overflow: hidden; //3、这里使用overflow:hidden,解决"文字溢出省略号展示功能"失效的问题 .intro{ font-size: 16px; color:#333333; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; text-overflow: ellipsis; } } } } } </style>
Vue中使用vant-ui
1、安装Vant-ui yarn add vant & npm install vant -D 2、安装按需引入的babel插件 yarn add babel-plugin-import & npm install babel-plugin-import -D 3、在.babelrc文件(此文件在根目录下)中添加配置 { "plugins": [ "transform-vue-jsx", "transform-runtime", ["import", { //将此代码添加进plugins里 "libraryName": "vant", "libraryDirectory": "es", "style": true }] ] } 4、在main.js中按需引入 import {Button,Tag} from 'vant'; //注意import {Button,Tag} from 'vant'要在Vue.use(Button).use(Tag)之前。即 使用之前先引入 Vue.use(Button).use(Tag); 5、按照vant官网api使用即可 <van-button type="primary">按钮</van-button>
配合vant-ui框架的List组件实现“上拉加载更多”功能 (懒加载)
1、引入List组件(上面有介绍,句不过多赘述了) 2、如何使用:看下方代码 <template> <div> <!--【***①组件***】van-list用于监听滚动事件及设置加载相关事宜--> <van-list v-model="loading" :finished="finished" finished-text="-- 没有更多了 --" @load="onLoad" :immediate-check=false //初始化页面时不检查滚动位置 > <!--这里写html代码--> <ul class="universityInfo" > <li class="everyInfo" v-for="(item,index) in universityList" :key="index"> <div class="infoName"><span>{{item.pname}}</span></div> </li> </ul> </van-list> </div> </template> <script> import * as axios from 'axios' import common from '../../kits/common.js' export default { name:"pUniversityList", data(){ //【***②参数***】 return{ universityList:[], //请求到的数据 loading: false, //加载状态 finished: false, //是否全部加载完毕 page:1, //接口的请求页码 pagesize:15, //每次请求数据数量,在设置:immediate-check=false后,pagesize最好设置大一点 } }, created(){ this.getUniversityList(); }, methods:{ getUniversityList(){ axios.get(`${common.coper}/allCooperation?page=${this.page}&pagesize=${this.pagesize}`) //【***③请求***】动态设置请求的页码和数据数量 .then(res=>{ if(res.data.code==200){ this.loading = false //请求接口成功时设置加载状态为false,【敲黑板,这里踩坑了,this.loading=false应该写在这里见下方解释】 if(res.data.data.list){ //因为不确定当没有数据时,后端接口返回给你的data.list是[],还是null,严谨一点,这里最好做一个判断。 this.universityList=this.universityList.concat(res.data.data.list); //将请求的数据合并到之前的数据上 //this.universityList=res.data.data.list.reverse().concat(this.universityList); //使数据倒叙排序 if(res.data.data.list.length<this.pagesize){ //当请求到的数据量小于请求的数据量时,说明数据已全部请求完毕 this.finished = true; //数据全部加载完毕 } }else{ this.finished = true; } } }).catch(err=>{}) } //懒加载函数【***④函数***】 onLoad() { let times=setTimeout(()=>{ this.page+=1 //每请求一次,页面数+1 this.getUniversityList() /*this.loading=false*/ //之前的this.loading=false是写在这里的,导致了一个bug就是每次上拉页面onload函数会执行两次或多次。原因在于这里是异步执行,故this.loading=false不会立即执行,因此loading是true状态,函数onload也一直在执行中。此时就会出现多次调用接口的情况。所以要把this.loading=false设置在接口函数(见上方)中。保证在接口调用成功后,this.loading=false,即加载完成。 clearTimeout(times) //执行完定时器后清除定时器 },500) } }, } </script>
上拉加载项目使用模板
【①】html模板 <van-list v-model="loading" :finished="finished" finished-text="-- 没有更多了 --" @load="onLoad" :immediate-check=false > 。。。。。。 </van-list> 【②】data参数设置 data(){ //【***②参数***】 return{ universityList:[], loading: false, finished: false, page:1, pagesize:15, } }, 【③】请求接口动态设置page,pagesize等 getUniversityList(){ axios.get(`${common.coper}/allCooperation?page=${this.page}&pagesize=${this.pagesize}`) .then(res=>{ if(res.data.code==200){ this.loading = false if(res.data.data.list){ this.universityList=this.universityList.concat(res.data.data.list); if(res.data.data.list.length<this.pagesize){ this.finished = true; } }else{ this.finished = true; } } }).catch(err=>{}) }, 【④】onload加载函数 onLoad() { let times=setTimeout(()=>{ this.page+=1 this.getUniversityList() clearTimeout(times) },500) }
路由传值,取值(一个参数)
1、路由部分配置:如router.js页面,在需要取值的页面的路由上添加/:testid { path:'/pUniversity/pUniversityInfo/:testid', //添加/:testid component:pUniversityInfo }, 2、传值,在需要传值的页面(如列表页) <li class="everyInfo" v-for="(item,index) in universityList" :key="index"> <router-link :to="'/pUniversity/pUniversityInfo/'+item.testid" > //这里通过这种方式传入id值,注意to需要v-bind绑定,另外注意 / 符号别少了 <div class="infoImg"><img :src="item.pimage" /></div> <div class="infoName"><span>{{item.pname}}</span></div> </router-link> </li> 3、取值,在需要取值的页面(如详情页) data(){ return{ id:this.$route.params.testid //注意这里是$route而不是$router } },
路由传值取值(多个参数,params方式)
1、路由页面 { path:'/video/videoScreen', component:VideoScreen, name:'VideoScreen', //params传多个参数必须要给路由命名,再通过命名方式跳转。 }, 2、传值页面 methods:{ postData(){ this.$router.push({name:'VideoScreen',params:{cid:this.demoCid,sid:this.demoSid,eid:this.demoEid}}) //params传多个值,只能通过name命名方式跳转,不可通过path路径方式 }, } 3、取值页面 data(){ return{ getData:this.$route.params //取值 } } 丶丶丶【敲黑板】params通过路由name传值的方式有个缺点,就是在取值页面刷新后,传过来的值便被清空了。丶丶丶 4、上述问题解决办法: 在路由页面做如下改动 { path:'/video/videoScreen/:cid/:sid/:eid', //这里在路由后面配置一下需要传的参数即可,这样参数就跟着路由被带过来,不会被清空了 component:VideoScreen, name:'VideoScreen', },
路由传值取值(多个参数,query方式)
1、路由页面 { path:'/video/videoScreen', component:VideoScreen, }, 2、传值页面 methods:{ postData(){ this.$router.push({path:'/video/videoScreen',query:{cid:this.demoCid,sid:this.demoSid,eid:this.demoEid}}) //query传多个值,只能通过path路径方式跳转,不可通过name命名方式 }, } 3、取值页面 data(){ return{ getData:this.$route.query//取值 } }
Vue中使用三目运算符
【1、直接使用】 <template> <div>{{transIndex==1?"第一个":"第二个"}}</div> </template> <script> export default{ data(){ return{ transIndex:1, } } } </script> 【2、在class中使用,用来动态绑定样式】 <template> <div> <button id="1" class="start" :class="selectid==1?'active':''" @click="select($event)">开始</button> //注意这里active是属性,要加引号,不然会报错 <button id="2" class="stop" :class="selectid==2?'active':''" @click="select($event)">结束</button> //在class里使用三木运算符时class需要v-bind绑定 </div> </template> <script> export default{ data(){ return{ selectid:1, } }, methods:{ select(e){ this.selectid=e.currentTarget.id //获取当前元素的id值 } } } </script>
vue通过js设置当前页面最小高度等于屏幕高度
在mounted钩子函数中设置 mounted(){ document.getElementById('demo').style.minHeight = window.innerHeight + 'px'; },
vant-ui动态设值
<template> <div> <van-popup v-model="menuShow" position="left" :duration="state" class="sideBarPop"> //这是vantui里的弹出层组件,duration不可直接设值(需要绑定才行),需要通过:duration="state"这种方式动态赋值,或者直接:duration="0.5" <div>DEMO</div> </van-popup> </div> </template> <script> export default{ data(){ state:0.5, } } </script>
Vue中dom元素完全渲染完毕后再获取一些数据--例子:文本超过三行后显示展开收起功能。(知识点较多)
1、完全渲染完毕后获取数据:watch对象配合Vue.nextTick方法 2、判断文本是否超过三行:获取文本高度,获取行高,行数=文本高/行高 【dom,css部分代码】 <template> <div class="contentIntro"> <div class="intro" id="intro"><span>{{goodsList.info}}</span></div> //文本域 <div v-show="isOpenShow"> //是否显示展开收起模块 <span class="moreIntro" @click="openIntro" v-show="!isOpen">展开</span> <span class="moreIntro" @click="closeIntro" v-show="isOpen">收起</span> </div> </div> </template> <style scoped lang="less"> .intro{ color:#6f6f6f; font-size: 15px; line-height: 22px; //一定要设置line-height,以便js部分获取line-height数据 //下面设置超出部分用省略号表示 display: -webkit-box; //将此display改变即可使省略失效 -webkit-line-clamp: 4; //设定行数 -webkit-box-orient: vertical; overflow: hidden; text-overflow: ellipsis; } .moreIntro{ float:right; font-size: 15px; color:#ff7700; } </style> 【script部分代码】 <script> import common from '../../common.js' import * as axios from 'axios data(){ isOpenShow:false, //是否显示展开收起按钮 personInfo:[], //个人信息 personIntro:null, //个人信息-描述 }, watch:{ //watch配合nextTick实现dom渲染完毕后监听dom元素 personIntro:function(){ this.$nextTick(()=>{ //vue的nextTick方法,可以配合watch实现在对更新过后的dom的监听。这里是要监听【渲染完毕后】的文本高度和行高,所以使用这种方法 const elem=document.getElementById('intro') const H=elem.offsetHeight //获取整个文本域的高度 /* const h=elem.style.lineHeight */ //获取文本的行高。这种方法只能获取行内样式里的样式,无法获取外联样式设置的样式,有局限性,这里不适用。但使用方式简单,有时可以用用。在移动端,内联样式是固定的,不会被编译器转化成rem等,没法自动适配屏幕,所以这里我们要获取外联样式,这样才能达到适配的目的,此方法只能获取内联样式是不行的。 const h=window.getComputedStyle(elem,null).getPropertyValue("line-height") //获取文本的行高。window.getComputedStyle()方法可以获取元素的样式属性,包括外联和内联样式,局限性很小。 const lineNum=parseFloat(H/parseFloat(h)).toFixed(2) //因为h的结果是带px单位的,所以这里要 parseFloat(h).toFixed(2) 转换为数字形式并保留两位小数。 lineNum=H/h的意思是行数=文本高度/行高 console.log(H) console.log(h) console.log(lineNum) if(lineNum>3){ //行高大于3时,展开按钮出现,若移动端不出现展开按钮,可以将3设置小一点试试,如2.6,2.7 this.isOpenShow=true } }) } }, methods:{ getPersonInfo(){ axios.get(`${common.personindex}/getCooperation?pid=${this.pid}`).then(res=>{ if(res.data.code==200){ this.personInfo=res.data.data this.personIntro=res.data.data.pdetails //给personIntrof赋值以配合watch方法实现监听 } }) }, openIntro(){ this.isOpen=true //收起按钮出现 document.getElementById("intro").style.display="block" //设置display,使得文本省略失效,从而展示所有文本 }, closeIntro(){ this.isOpen=false //展开按钮出现 document.getElementById("intro").style.display="-webkit-box" //重新设置display,以...省略形式展示 } } </script>
给v-html中的标签添加css样式
解决方案1:在updated生命周期函数中,js动态配置样式,代码如下 updated() { $('.msgHtmlBox').find('p').css('color', 'blue'); }, 解决方案2:去掉style标签中的scoped属性 scoped属性导致css仅对当前组件生效(用css3的属性选择器+生成的随机属性实现的),而html绑定渲染出的内容可以理解为是子组件的内容,子组件不会被加上对应的属性,所以不会应用css. 解决方案3:写样式的时候添加 >>> 符号(注:若使用了less,则不能使用此方法) <style scoped> .msgHtmlBox >>> p{ color: blue; } </style>
input获取焦点失去焦点(注意浏览器兼容问题)
原则上失去焦点是@blur,获取焦点是@focus 但是苹果safari浏览器不能很好的兼容@focus,所以移动端的话@focus最好用@click代替 js使input框获取焦点document.getElementById("inputName").focus() js使input框失去焦点document.getElementById("inputName").blur()
vant-ui里toast的使用
sendComment(){ this.$toast({ message:'评论发表成功', duration:2000, }) this.commentValue='' this.inputSelect=false },
input输入框在呼出键盘后错位
https://www.cnblogs.com/ljx20180807/p/9837748.html
图片间隔处理方法(如5张图片,屏幕一行放下2张,中间间隔10px,两边无间隔)
使用nth-child(odd),nth-child(2n)方式添加margin-right:10px样式 注意看下方图片,一个是中间有间隔,两边无间隔。一个是所有图片右侧均有间隔
实现短信验证码倒计时
<span v-show="show" @click="getCode">获取验证码</span> <span v-show="!show" class="count">{{count}} s</span> data(){ return { show: true, count: '', timer: null, } }, methods:{ getCode(){ const TIME_COUNT = 60; if (!this.timer) { this.count = TIME_COUNT; this.show = false; this.timer = setInterval(() => { if (this.count > 0 && this.count <= TIME_COUNT) { this.count--; } else { this.show = true; clearInterval(this.timer); this.timer = null; } }, 1000) } } }
vue正则匹配(踩坑,不要用全局g)
inputuname() { const pattern = /^[\w\u4e00-\u9fa5]{3,8}$/ //注意这里不要用g全局匹配,否则若其他地方有不符合该正则的,则表达式会一直返回false。 if (this.username.length==0) { this.errname = false }else if(pattern.test(this.username)==false){ this.errname = true }else if(pattern.test(this.username)==true){ this.errname = false } },
input输入框光标高度问题
IE:不管该行有没有文字,光标高度与font-size大小一致 FF:该行没有文字时,光标大小与input的 height 大小一致;该行有文字时,光标大小与font-size大小一致 chrome:有2种情况,①设置了line-height 该行没有文字时,光标大小与input的 line-height 大小一致; 该行有文字时,光标大小从input顶部到文字底部 ②没有设置line-height 光标大小与font-size一样 所以,input在使用的时候,最好不要设line-height, 可以设定一个较小的height, 然后用 padding 来撑开,这样基本上可以解决所有浏览器的问题 input{ height: 10px; padding: 10px 0px; font-size: 12px; }
使用vant的upload组件上传头像,图片(上传图片使用form表单形式,而非json)
<template> <div class="image"> <span>头像:</span> <van-uploader class="imgDiv" :after-read="afterRead"> <div class="uploaderStyle" v-if="!imgUrl"> <span>+</span> <span>上传头像</span> </div> <div class="imageShow" v-if="imgUrl"> <img :src="imgUrl"/> </div> </van-uploader> </div> </template> <script> afterRead(file){ /* console.log(file.file) */ let param = new FormData(); //创建formData对象 param.append('file', file.file); //组件获取到的图片file有时需要经过处理后上传,这里需要上传file里面的file数据,所以file.file,见下图 let config = { headers: { 'Content-Type': 'multipart/form-data' //设置请求头格式 } }; axios.post(`${common.api}/upload`, param, config).then(res => { //上传至 图片处理接口 拿到后台处理过后的图片url if(res.data.code==200){ this.imgUrl=res.data.msg //这就是后台处理过后的url axios.post(`${api.userApi}/demoimg?faceimg=${this.imgUrl}`).then(res=>{ //将处理过后的图片url上传至其他接口 if(res.data.code==200){ this.$toast("图片上传成功") } }) } }) } </script>
上传图片小结
这里上传的方式是在vant组件的after-read文件读取的钩子函数里拿到图片file,然后将file.file上传到后台的图片处理接口,再拿到处理接口返回的url,这时图片就转化成了url形式,再将这个url上传给其他需要的接口即可。 即after-read读取文件-->file传处理接口-->拿到处理后url-->使用url传其他接口 而需要说明的是并不是每个ui框架的上传组件都是这种处理模式,有的框架的文件读取是单独出来的api(如vant的after-read)。 而有的文件读取是内嵌在组件内部的,比如antDesign的文件读取就在beforeUpload之中,element,mint,cube等每一个都有自己的模式。 如果框架没有单独的文件读取api,可以参考 https://www.cnblogs.com/huihuihero/p/11060531.html 里的图片上传方式
vue根据不同数据动态设置背景
<div class="demo" :style="{background:'url('+require('../../assets/image/pic_'+(index+1)+'.png')+') no-repeat center'}"></div> 注意:图片必须要以pic_1.png pic_2.png pic_3.png pic_4.png这种数字型命名
来源:https://www.cnblogs.com/huihuihero/p/11493710.html