vue中遇到的坑
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
vue中遇到的坑
如何解决在vue中替换图⽚、⼀个使⽤base64,⽽我们使⽤zepto之后,src找不到资源,因为已经打包了,难道强⾏写base64。
1. 引⼊⽂件时语法很重要!
import "FooterMenu" from '@components/Menu';
import FooterMenu from'@components/Menu';
即在页⾯组件中引⼊⼀个FooterMenu组件, 我们引⼊时应该引⼊的⼀个变量作为标签,⽽不能再FooterMenu上添加引号!!在这⾥浪费了很多时间。
2. 在⼀个单页⾯组件中不需要style,但必须要script。
即在.vue⽂件中,我们可以没有style,但是必须要有script来利⽤ exports default 来导出模块,否则就会出错。
补充:
<transition name="fade">
<div class="pay-model" v-show="ifpay">
<div class="pay-style">
<div v-if="payArr[payArr.length - 3] == 1">
<input type="radio" name="settleChoose"checked = "checked" data-value='4' id="wechat" value="微信⽀付" v-model="style">
<label for="wechat" >微信⽀付</label>
</div>
<div v-if="payArr[payArr.length - 2] == 1">
<input type="radio" name="settleChoose" id="alipay" data-value='2' value="⽀付宝⽀付" v-model='style'>
<label for="alipay" >⽀付宝⽀付</label>
</div>
<div v-if="payArr[payArr.length - 1] == 1">
<input type="radio" name="settleChoose" id="tohome" data-value='1' value="货到付款" v-model='style'>
<label for="tohome">货到付款</label>
</div>
</div>
</div>
</transition>
在这⾥,如果style的值为初始值 "",即为空,那么我们及时使⽤这⾥的checked = "checked"也⽆法⾃动选中,解决⽅法:如果我们希望在打开模态框之后的微信⽀付是默认的,那么我们就可以将 style 的初始值设置为 “微信⽀付”,这样就没有什么问题了。
补充:
<div v-if="payArr[payArr.length - 2] == 1">
<label class="pay-lable" >
<input type="radio" v-bind:checked = 'curPayMethod == 2' name="choosePay" value="2">
⽀付宝⽀付</label>
</div>
<div v-if="payArr[payArr.length - 3] == 1">
<label class="pay-lable" >
<input type="radio" v-bind:checked = 'curPayMethod == 4' name="choosePay" value="4">
微信⽀付</label>
</div>
<div v-if="payArr[payArr.length - 1] == 1">
<label class="pay-lable">
<input type="radio" v-bind:checked = 'curPayMethod == 1' name="choosePay" value="1">
修改为货到付款</label>
</div>
label的for对应于input的id,如果说不能正常使⽤,其实我们也可以直接将input写进label⾥去,这样会更加⽅便,不再需要使⽤ for 和 id 了。
3. 当我们在路由中配置了不同的router-link对应于不同的组件的时候,会发现npm run dev之后什么都没有,⽐如我的路由如下:
export default new Router({
routes: [
{
path: '/Mall',
component: Mall
},
{
path: '/personal-center',
component: personalCenter
},
{
path: '/order',
component: AlipayHint
},
{
path: '/commodity',
component: Commodity
}
]
});
运⾏之后,是空⽩页,这是因为路由中并没有配置⼀进来是“/”的路由,所以什么都没有显⽰,这时就需要重定向了。
如下所⽰:
routes: [
{
path: '/Mall',
component: Mall
},
{
path: '/personal-center',
component: personalCenter
},
{
path: '/order',
component: AlipayHint
},
path: '/commodity',
component: Commodity
},
{
path: "/",
redirect: "/commodity"
}
]
即我们需要重定向的时path中的值,⽽不是component中的值。
4. 在v-for下的列表中,如何向⽅法传递参数?
(1)我们可以在⼀个list中绑定 v-for="item,index in items",这样,我们就可以获取到相应的item和index(从0开始),另外,如果我们希望向list中的某个v-on:click = "handler" 传递参数,可以直接传递,⽐如: v-on:click="handler(index)",这样就可以向methods下的handler传递参数了。
(2)我们还可以传递$event直接给hanlder,然后通过e.currentTarget获取到这个元素。
5. 如何使⽤vuex、使⽤store中的数据、替换store中的数据?
vuex⼤家都不陌⽣,⽐如我在⼀个store的state中存储了items为⼀个空数组,然后在组件中循环数组中的每⼀个元素并展⽰出来,然后再通过axios获取到数据之后更新store,这样数组中就有元素了。
最开始我使⽤的思路如下所⽰:
const state = {
totalPrice: 0,
items: [],
//.... 其他的state
}
然后通过axois获取items,获取到之后更新:
.then(function (response) {
if (response.data.code == 130) {
items = response.data.data;
console.log(items);
mit('update', items);
}
其中的update已经在mutation中定义了,因为我们知道vue中的state只能通过commit这⼀种⽅式来替换⽽不能通过其他⽅式,如下:
mutations: {
update (state, items) {
state.items = items;
}
}
最后,我们需要把items挂载到组件下:
data: function () {
return {
name: "CommodityKinds",
items: this.$store.state.items
}
},
说明:因为我已经将store注册到根组件下了,所以我们可以在组件中使⽤ this.$store.state来访问到state对象。
但是,这样是有问题的 --- 我们会发现,进⼊有items数据的页⾯后,数据并没有被渲染出来,⽽是等到我们切换页⾯,再切换回来的时候才能渲染出来。
⽽问题就出现在了最后⼀步!
我们应该将store中的数据放在computed下⽽不是放在data下
具体解决⽅法如下:
import {mapState} from'vuex'
然后:
computed: mapState({
items: state => state.items
})
这样,当store中的数据改变时,就会直接改变了,更多例⼦可以看vuex官⽅⽂档,讲的很好。
总结:⼀般⽽⾔,我们需要将store下的state放在computed中,将组件⾃⾝的state,不需要像vuex这样动态的、传递的放在 data 下即可。
6. 在vue中,我们可以使⽤v-on:click.once对click处理函数只绑定⼀次,这样就类似于jquery中的one绑定了。
7. 在jquery中,如果我们希望第⼀个元素最开始添加⼀个active类名,我们可以使⽤class绑定,其中是⼀个对象,对象中的属性是类的名称,值是布尔值,如果为true,则显⽰,否则不显⽰。
<template>
<div class="commodity-kind">
<div class="kind" v-bind:class="{active: index == 0}" v-on:click="getContent(item.id, $event)" v-for="item,index in items">
<span>{{}}</span>
</div>
</div>
</template>
这样,⼀进去就是这样的状态了。
8. 当需要axios请求时,如果我们在不同的组件中都需要请求,并且都有相同的请求头,特别是最近的项⽬我需要使⽤vue-cli的express代理Tomcat服务器进⾏测试开发时,就要
添加/api才能正常访问,但是在每⼀个请求前添加这个是⾮常⿇烦的,并且在 npm run build 时,⼜要把这些/api去掉,这是相当⿇烦的,所以我们可以单独建⽴⼀个js⽂件,我
命名为 request.js ⽂件,内容如下:
import axios from'axios'
axios.defaults.baseURL = "/api";
mon['BBG-Key'] = "ab9ef20253-49d4-b229-3cc2383480a6";
export default axios
其中,/api是在开发过程需要代理服务器所必须的,所以这⾥设置为baseURL,那么在实际请求中,就会⾃动添加/api,并且在实际⽣产中,我们只要注释掉它就可以了。
⽽BBG-Key是为了安全使⽤的,所以为了避免每次在请求时都添加⼀个请求头,我们在这⾥直接设置为 common(公共)的请求头。
这样,在实际的每⼀个请求中就不需要都添
加这个请求头了。
最后导出这个 axios,在其他的模块中引⽤。
import axios from'../assets/js/request'
axios.get('/bbg/shop/get_classify', {
params: {
sid: 13729792
}
})
.then(function (response) {
if (response.data.code == 130) {
items = response.data.data;
//............
这样,就会较之前省去很多的⼯作量。
good!
9. vue中在css下写的,即⼀般使⽤的时作为背景图的,在assets下的图⽚经过打包之后使⽤的时base64的编码⽅式,所以,如果在js中操作css,使⽤路径的⽅式是⾏不通的,
我的⽅式是使⽤base64,但是有更好的⽅法吗?如下所⽰:
handleDefault (id,e) {
$(".default").html("设为默认").css({
'color': 'black',
'background': 'url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAC+SURBVFhH7Y5BCgIxDEXHs7h 'background-size': '0.4rem'
});
$(e.currentTarget).html("默认地址").css({
'color': '#51B1B0',
'background': 'url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAnCAYAAAB9qAq4AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAG3SURBVFhH7Zc9S8NgFIXrFw 'background-size': '0.4rem'
});
10. class绑定的是⼀个对象,⼀般情况下,这个对象直接定义在html中是⽐较好处理的,如下:
<!-- 这⾥使⽤class绑定来决定默认 -->
<span class="no-default" v-bind:class="{default: item.id == defaultAddress.id}" v-on:click="handleDefault(item.id, $event)" >
{{ (item.id == defaultAddress.id) ? "默认地址" : "设为默认" }}
</span>
注意: class中的class名称不能⽤引号括起来。
11. 在menu中,每当点击⼀个选项时,替换其背景图⽚,如何做到实时的变化。
最开始,我的实现思路是:先通过import的⽅式引⼊,然后在 v-for 中引⽤data下的每⼀个项⽬的src,然后当点击选项的时候,⽤switch函数来根据点击的index来进⾏替换图
⽚,但是这样的替换存在⼀个问题:每当点击之后,第⼀次并没变化,⽽是再点击⼀次,才会发⽣改变。
原因:在vue中,data下的值和DOM中不是实时更新的,所以⼀般实时更新就要使⽤store。
即在store中import 图⽚资源,然后在改变的时候通过mutations进⾏改变。
这样的变
化就是实时的了。
问题:虽然使⽤ mutations 可以实时改变,但问题是,我们完全是没有必要的,因为这个改变只需要在⼀个组件中,使⽤store未免太⼩题⼤做了。
注意:这⾥使⽤的是vue的data,并且需要改变的时引⼊的⽂件(需要打包的),对于下⾯这样只需要修改颜⾊的不需要使⽤这样的⽅式,只需要使⽤ zepto 来改变css即可,这
样⼀定是实时的。
12. 使⽤actions时,需要commit Mutations,但是actions 不⽀持多参数传递,也就是说第⼀个参数是Mutation,第⼆个参数是我们需要传递的值,如果传⼊多个,那么第三个及以后将⾃动忽略,为了解决这个问题,我们可以将多个值封装到⼀个对象,然后传递这个对象就可以了,这就类似于Payload啊啊啊。
if (response.data.code == 626) {
for (let i = 0; i < response.data.data.length; i++) {
console.log(response.data.data[i], index);
var obj = {
index: index,
item: response.data.data[i]
};
commit(UPDATE_ALL_CONTENT, obj);
}
index++;
resolve();
}
OK!这就是payload。
哈哈哈哈理解就好。
13. 在vue中,我们传⼊的事件⼀定是$event,但是获取时, e.currentTarget 和 e.target 获取的不⼀样的,区别在于前者是当前的元素,即冒泡的最后⼀个绑定事件的元素,⽽后者是最原始的元素。
关键:后者可以实现事件代理。
14. 有时候啊,⼀个很⼩的错误都会导致全局的失败!⽐如,不知道为什么就报下⾯这种错误!
然后内容就显⽰不出来,但是通过network可以获知数据都请求到了,所以遇到这种问题我的解决⽅法还是寻找于此有关的代码,然后逐个注释代码,如果注释之后不再出错,就说明问题出在了这⾥,通过寻找,问题在这:
<template>
<div class="item"}>
即之前添加属性时, } 没有去掉。
虽然有问题了,但是解决问题的⽅法和思路正确就好。
15. 为什么document.body.scrollTop = 0 不⽣效,⽽ document.querySelector("body").scrollTop = 0; 是可以的呢?
16. 下⾯的这个错误⽽很明显!就是在创建钩⼦函数created中出现了未定义的变量:
即 Error in created hook!
17. localStorage⽆法输出
为什么只有localStorage可以输出,⽽其他的不能呢?就是访问不到属性!。