1.object is not defiend
(1)可能事件名和name名冲突
(2)vuex方法辅组函数名写错
2. cli3.0静态文件要放在public下面才能读取
3.请求参数如果是写在请求体里面的要通过下面这个请求
如果传入的参数是包裹在对象下键的话需要使用下面的方法进行传参
例如:
Object {payType: 0, batchNo: "18l5hja4qyx74", stopLosePrice: 17.155, stopWinPrice: 17.46} "first"
安装引入qs依赖
export const updateNewOrderStopPrice = (params) => {
const data = qs.stringify(params)
// console.log(data, 'databased')
return ajax.request({
url: '/order/newOrder/updateNewOrderStopPrice.do',
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data
})
}
4.设置字体之间间距
letter-spacing: 8px
5.改变页面数据返回得图片大小
for(let i in document.querySelectorAll('img')){
if(typeof document.querySelectorAll('img')[i] == 'object'){
document.querySelectorAll('img')[i].style.width = '94vw'
document.querySelectorAll('img')[i].style.paddingRight = '2.7vw'
}
}
6.如果加载数据打印出来是个空数组展开之后才有数据,证明取值得时候数据还没有渲染出来,此时需要加个定时器,等拿到数据之后才做下一步操作
7.更改循环渲染的数据中的图片大小
setTimeout(()=> {
let imgList = document.getElementsByClassName("firstContent")
// 类数组
let a = Array.from(imgList)
a.forEach((item) => {
console.log()
if(item.querySelector('a')){
item.querySelector('a').querySelector('img').setAttribute('style','width: 86.5vw;height: 20vw;')
}
})
},2000)
7.Class与Style动态绑定
1.对象语法
class
data: {
isActive: true,
hasError: false
}
style
data: {
activeColor: 'red',
fontSize: 30
}
2.数组语法
class
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
style
data: {
styleColor: {
color: 'red'
},
styleSize: {
fontSize: '23px'
}
}
8.使用vant中List懒加载,父子组件传参
list每次到达页面底部会触发一次onLoad事件加载数据,此时$emit一个事件告诉父组件加载下一页数据
{{item.remark}}
{{item.typeDetail>=0?'+':'-'}}{{item.money}}¥
{{item.typeDetail>=0?'+':'-'}}{{item.score}}分
{{item.createTime}}
export default {
props: ['BillItemData','type', 'isLoading','isfinished'],
data(){
return {
loading: false,
finished: false,
}
},
watch: {
isLoading: function() {
this.loading = false
},
},
methods: {
onLoad() {
console.log('onload')
this.$emit('toTheEnd',{
type: this.$props.type,
childLoading: this.loading
})
}
}
}
父组件中使用子组件并监听toTheEnd方法,只要子组件触发toTheEnd方法就执行handleAddMore方法加载数据
传cashAlldone给子组件,表示数据加载完成,不需要再加载
{{remain.margin}}
元(冻结保证金)
- 现金明细,全部加载完了 -
export default {
components: {
BillItem
},
data() {
return {
remain: {},
active: '0',
isLoading: '',
cashList: [],
cashPage: 0,
scorePage: 0,
pageSize: 10,
scoreList: [],
scoreAlldone: false,
cashAlldone: false
}
},
created () {
this.loadBalance(),
this.getDatas(
this.$http.getCashDetail,
{ type: 'money'},
this.pageSize,
this.cashPage,
'cashList'
),
this.getDatas(
this.$http.getCashDetail,
{ type: 'score'},
this.pageSize,
this.scoreList,
'scoreList'
)
},
methods: {
handleAddMore(childData) {
if(childData.type == 'money') {
this.cashPage += 1;
this.getDatas(
this.$http.getCashDetail,
childData,
this.pageSize,
this.cashPage,
'cashList'
)
}
if(childData.type == 'score') {
this.scorePage += 1;
this.getDatas(
this.$http.getCashDetail,
childData,
this.pageSize,
this.scorePage,
'scoreList'
)
}
},
// 封装的方法
getDatas(getDatasFn,childData, pageSizeType, pageType, whichList){
if(getDatasFn) {
getDatasFn({
type: childData.type,
offset: pageSizeType * pageType,
size: pageSizeType
}).then(resp => {
// 当数据加载到最后的时候再次加载data就为0,如果data为0表示加载完成,此时this.cashAlldone = true
if(resp.length == 0){
if(childData.type == 'money'){
this.cashAlldone = true
} else if(childData.type == 'score'){
this.scoreAlldone = true
}
}
if(this[whichList]) {
this[whichList] = this[whichList].concat(resp)
} else {
this[whichList] = resp
}
if(childData.childLoading != undefined) {
this.isLoading = new Date()
}
})
}
},
loadBalance() {
this.$http.getBalance().then(resp => {
if(resp) {
this.remain = resp
} else {
this.$router.push({
path: '/detailed'
})
}
})
}
}
}
9.节流,当一个请求持续不断刷新的时候,要确保上一次请求已经返回,才做下一次请求
data: {
return: {
isPending: false
}
},
mounted () {
this.timer = setInterval(() => {
if(this.isPending === false){
this.isPending = true
this.getRankQuotaVariety();
}
},1000)
},
beforeDestroy () {
clearInterval(this.timer);
},
methods: {
getRankQuotaVariety(){
Promise.all([
this.$http.getHomeData(),
this.$http.getTypeVariety()
]).then((values)=> {
this.isPending = false
……………………
}
}
10.Content Editable
html中任何元素都可以编辑,通过js事件处理,可以将网页转换为完整且快速的富文本编辑器
This text can be edited by the user
11.如果数据是动态渲染的不论是字符串还是变量一定要加v-bind或:绑定,不然渲染不出来
12.循环渲染数据特别是父组件传参给子组件渲染的时候一定要分清楚是不是多次渲染了同一个东西
13.把多维数组转换为一维数组values[1]下面包含三个数组
this.arrayTwo = [].concat.apply([], values[1])
14.两个数组通过对比某个字段是否相同,相同的话就糅合在一起
this.arrayOne.forEach(item => {
this.allDatas = this.isTypeAssign(this.arrayTwo, "varietyType", item)
})
isTypeAssign(arr, type, parentItem) {
arr.map((curr, index) => {
if (parentItem.varietyType == curr.varietyType) {
arr[index] = Object.assign({}, arr[index], parentItem);
}
})
return arr
},
15.报错方法“item”未在实例上定义,但在呈现期间引用。 通过初始化属性,确保此属性在数据选项或基于类的组件中是被动的。
可能是把标签元素嵌套层级写错了,比如里面的div中写的循环渲染,但是在div外面用v-if="item"判断了item是否有,此时嵌套层级出现问题,item不存在
16.实现组件复用时再次调用生命周期钩子函数
例如从/user/foo
到/user/bar
原来的组件实例会被复用,不过这也意味这组件的生命周期钩子不会再被调用
方法一:可以使用wathch
来监听$route的变化
方法二:可以在router-view上加一个唯一的key,来保证路由切换时都会重新渲染触发钩子函数
computed: {
key() {
return this.$route.name !== undefined ? this.$route.name ++ new Date() : this.$route ++ new Date()
}
key() {
return this.$route.fullPath
}
}
16.登录和权限验证原理
- **登录:当用户填完账号信息和密码后向服务器验证是否正确,验证通过后,服务器会返回一个token,拿到token之后,将token存储到cookie中,保证刷新页面后能记住用户登录状态,前端会根据token再去拉去userinfo的接口来获取用户信息(如用户权限,用户名等)*****
- 权限验证:通过token获取对应的role,动态根据用户的role算出对应的权限路由,通过router.addRoutes动态挂载路由
- 用户登录成功之后,会在全局钩子
router.beforeEach
中拦截路由,判断是否已获得token
在获得token
之后既可以去获取用户的基本信息
17.如何覆盖UI组件默认样式
例如element-ui样式,由于element-ui样式是在全局引入的,所以想在某个view里面覆盖它的样式就不能加scoped
,但是又想只是覆盖这个页面的element样式,就可以在他的父级加上一个class,用来命名空间来解决问题
.tag-wrap{ //你的命名空间
.el-tag { //element-ui 元素
margin-right: 0px;
}
}
18.函数名千万不能和别的名字写重,否则会发现意想不到的错误,而且很难找出错误点
19.vant组件库中input有封装好的方法,怎么一直获取输入框焦点,使用ref获取实例,在点击按钮弹出dialog框的时候,让input框获取焦点
// 按钮上绑定的方法,触发方法的时候input框获取焦点
handleGetValidateCode() {
// 获取验证码
if (this.isCartdownStart === false) {
const phoneReg = /^1[3456789]\d{9}$/;
if (phoneReg.test(this.inputPhone)) {
this.$http
.getValidateCode({
userPhone: this.inputPhone,
regImageCode: ""
})
.then(resp => {
// 600说明图片验证码错误
// 601需要输入验证码
if (resp.code == 601) {
this.validateCodeIsShow = true;
this.$http
.getValidateCodeImg({
userPhone: this.inputPhone
})
.then(resp => {
this.$refs.imgCodeInput.focus();
this.regImg = resp;
});
}
});
} else {
Toast("请输入正确的手机号");
}
}
}
20.ajax轮询
ajax轮询分为两种:
- 第一种:
设定一个定时器,无论有无结果返回,时间一到就会继续发送请求,这种轮询耗费资源,也不一定能得到想要的数据,这种轮询不推荐
- 第二种:
在第一次请求的时候,如果返回数据了那么就在成功的回调里再次发起这个请求,就像递归一样,调用本方法,如果时间太久失败了,同样的再次调用这个请求,长轮询也需要后台配合,没有数据改变的时候就不用返回,或者约定好逻辑。
21.timeout.close is not a function
使用clearInterval过程中,IDE自动加上以下语句:
import { clearInterval } from "timers";
导致错误,直接删除
22.自定义svg插入图片不能使用require引入,直接在代码中写
-
- 期货快讯
23.keep-alive include和exclude无效问题
使用include/exclude 属性需要给所有vue类的name赋值(注意不是给route的name赋值),否则 include/exclude不生效
export default {
name:'a', // include 或 exclude所使用的name
data () {
return{
}
}
}
24.手动滑动轮播图之后自动轮播失效
加上这句代码,注意swiper是swiper3.x
还是swiper4.x
//这是3的写法
swiperOption: {
pagination: '.swiper-pagination',
autoplay: 2000, // 可设置数值来指定播放速度
autoplayDisableOnInteraction: false, // 用户操作swiper之后,是否禁止autoplay
speed: 400, // 切换图片速度
loop: true // 循环播放
}
//这是4的写法
swiperOption: {
pagination: '.swiper-pagination',
autoplay: 2000, // 可设置数值来指定播放速度
autoplay: {
disableOnInteraction: false, // 用户操作swiper之后,是否禁止autoplay
},
speed: 400, // 切换图片速度
loop: true // 循环播放
}
25.vue-cli3.0 buil打包的js文件添加版本号
在vue.config.js中加入下面这段话
const Timestamp = new Date().getTime()
module.exports = {
configureWebpack: {
output: {
//文件名称 版本号 时间戳
filename: `[name].${process.env.VUE_APP_Version}.${Timestamp}.js`,
chunkFilename: `[name].${process.env.VUE_APP_Version}.${Timestamp}.js`
}
}
}
26.assets和static之间的区别
相同点
两个都是存放静态资源文件。项目中所需的资源文件图片,字体图标,样式文件等都可以放在这两个文件下
不同点
1、assets中存放的静态资源文件在项目打包时(npm run build
),会将assets中放置的静态资源文件进行打包上传,压缩体积,代码格式化。而压缩后的静态资源文件最终也会放置在static文件中跟着index.html一同上传至服务器
2、static中放置的静态资源文件就不会走打包压缩格式化流程,而是直接进入打包好的目录,直接上传至服务器。因为避免了压缩直接进行上唇,在打包时会提高一定的效率,但是static中的资源由于没有进行压缩等操作,所以文件的体积相对于assets中较大点。在服务器中会占据更大的空间
建议:
将项目中template需要的样式文件、js文件等都可以放置在assets中,走打包这一流程,减少体积。而项目中引入的第三方资源文件如iconfont.css文件等都可以放置在static中,因为这些三方文件已经做过处理,不需要再进行处理,直接上传。