第一个vue项目总结
最近幸运的参与了公司m站重构项目,项目使用了nuxt、vant
nuxt是基于vue的服务端渲染框架,服务端渲染有助于SEO。具体可以参考这篇博客。
vant是有赞的一个ui框架,封装了一些ui组件,改改样式还是挺好用的。
遇到的问题
1、v-lazy批量加载本地图片
v-lazy是vant封装vue的lazyload指令。当图片地址是本地图片时,懒加载无效。
搜了一圈,原因是涉及到webpack(nuxt自带)打包问题,所以要提前把图片引入
IMG: require("../static/about/pic.png")
因为本地图片很多,在页面这样批量引入不好看,于是把每个图片的地址写在一个JSON对象里,然后在页面通过引入JSON对象,在img标签中绑定对应的地址。
// common.js
export const lazyImgJSON = {
"tea": {
"high": {
a: require("../static/about/teacherPics/high/a.png"),
b: require("../static/about/teacherPics/high/b.png"),
c: require("../static/about/teacherPics/high/c.png"),
d: require("../static/about/teacherPics/high/d.png"),
g:require("../static/about/teacherPics/high/g.png")
}
}
// page.vue
<template>
<img class="new" v-lazy="tea.high.a">
</template>
<script>
import { lazyImgJSON } from '~/util/common'
<script>
这样就可以批量引入啦~
2、vue中对象和数组处理问题
这个坑是因为自己没认真看文档,vue文档中写到了数组更新检测 以及 对象更改检测注意事项
(1)数组
vue里数组的push()、pop()、shift()、unshift()、splice()、sort()、reverse()方法,会触发视图更新!
直接给数组的index位置赋值修改或者直接修改长度不会立即触发视图更新!
解决方法:用set方法或者splice方法,像下面这样
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
(2)对象
Vue 不能检测对象属性的添加或删除,即不会立即触发视图更新。
解决方法:用set方法或者Object.assign
// set
Vue.set(vm.userProfile, 'age', 27)
// Object.assign
vm.userProfile = Object.assign({}, vm.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})
3、vue-touch引入遇到2个问题
(1)报错can't read property 'priority' of undefied
这个是因为vue和vue-touch版本问题,参见[vue-touch](https://github.com/vuejs/vue-touch/tree/next)的说明,2.0以后的vue使用下面的命令安装
npm install vue-touch@next
(2)报错hammerjs中window is not defined
这个最终在nuxt文档里找到了说明,戳这里
This is due to the server-side rendering. If you need to specify that you want to import a resource only on the client-side, you need to use the process.browser variable.
这是因为ssr。如果你需要引入一个只支持客户端的资源,你需要用process.browser变量。
//像这样
<script>
import ....
if (process.browser) {
Vue.use(require('vue-touch'), {name: 'v-touch'})
}
export default {
}
<script>
4、2地方加上最好加上res.status===0的判断
(1)第一处:请求的返回值,加上判断res.status === 0
(2)第二处:页面中将所用到的数据包一层判断 v-if ="res.status === 0 "
否则页面渲染的数据有可能会报undefined
每进入一个页面,控制台打印:
nuxt:render Rendering url /study/todoLive +34s
nuxt:render Data fetching /study/todoLive: 1ms +0ms
这个我也没搞懂原因,但是我猜想和控制台打印的这两行东西有关。
5、vue.prototype使用
很方便!
有时候需要处理一些列表数据,比如 分 转成 元, 时间戳的处理。
之前的处理数据方法是拿到数据(一般是列表),都循环处理这些。
现在的解决办法是在vue.prototype里添加处理方法,直接在页面渲染的地方调用处理方法。
栗子:
<div class="beginning-mod">
<div class="beginning">
<span class="time">{{citem.course.introduction}}</span>
<template v-if="citem.course.lecture_desc">
<em>|</em><span class="hour">{{citem.course.lecture_desc}}</span>
</template>
</div>
<div class="price">¥{{ fenToYuan(citem.order.price)}}</div>
</div>
<div class="teachers-price">
<div class="u-ellipsis teacher-list">
<span v-if="citem.course.teacher_name" class="teacher_name">主讲老师:{{citem.course.teacher_name}}</span>
<span v-if="citem.course.counselor_name" class="teacher_name">辅导老师:{{citem.course.counselor_name}}</span>
</div>
<div v-if="citem.order.orig_price !== citem.order.price" class="price">¥{{ fenToYuan(citem.order.orig_price)}}</div>
</div>
6、子组件method里取不到props
这个是因为props是动态的,父组件把接口返回的数据传给子组件。这时候用watch就可以解决啦~
props: {
calendar:Array
},
watch: {
calendar:function(val){
this.taskList = val
this.compareList()
}
}
watch监视props的变化,然后将变化的值赋给另一个全局变量。
7、列表数据处理
戳这里
8、vue日历插件
这个还没写