Vue app开发踩过的那些坑(一)

最近接了一个活儿,甲方要求用Vue来进行开发,于是乎,从头开始读了一遍官方文档,便开始写代码了。之前接触过Angular JS,不过理解不深,但是对上手Vue来说,还是有帮助的。对于CSS,也老是记不住一些属性,在开发过程中,也算进行了复习。这篇文章主要纪录了在开发过程中遇到的坑以及对应的我的解决方案,参照网上的解决方案的大部分都贴了原文地址,如有问题,欢迎指正。

-----------------------------------------------------------------我是分割线--------------------------------------------------------------------------

1、开发环境的配置

Vue也需要安装node.js。在项目中使用到的一些插件(以vue-awesome为例)也要用

npm install vue-awesome -- save

加入到package.json的dependencies中,之后其他的项目成员在运行之前,直接 npm install 就好

2、如何使用插件vue-awesome

vue-awesome提供了各种icon,在页面中需要使用的时候,

1)需要把对应的icon文件以及需要使用的icon文件引入,

import Icon from 'vue-awesome/components/Icon.vue'
import 'vue-awesome/icons/arrow-left'

2)在components里加入Icon,示例代码如下:

components: {
  Icon
}

3)在对应的template中就可以直接使用了,此外,还可以用scale设置icon的大小,也可以css设置icon的颜色和一些其他的属性。

<Icon name="arrow-left" class="return-btn" scale="2"></Icon>

3、分割线的设置

需要使用分割线,用的hr,但是最后还是没找到如何给hr设置颜色(此处留个坑),后来遂改成设置div属性的border

4、z-index设置多层元素的堆叠顺序,拥有更高堆叠顺序的元素总是会处于堆叠顺序较低的元素的前面。

但是注意:z-index必须和position:absolute一起使用才有效

5、移动端页面适配

使用margin和padding等设置页面布局的时候,当以百分比,或者px为单位的时候,手机分辨率变了之后,可能会出现换行及其他一些乱码的情况。可以采用rem来设置,这样字的大小会根据根元素进行调整。可以参考这里

6、flex弹性布局

页面的布局方式,包括各种位置及相对排列,主要有以下一些属性

flex-direction
flex-wrap
flex-flow
justify-content
align-items
align-content
各个属性的取值对应来页面的不同布局,具体可以参照这里

7、axios实现网络交互

Vue和服务器端进行网络交互主要有以下一些实现方式,包括fetch, jquery ajax, axios, vue-resouce等。考虑到官方取消来对vue-resource,转而支持axios,所以采用axios进行网络交互,axios的教程参照这里

axios的使用主要注意以下几点:

1) 安装axios

npm install axios -- save

2) 值得注意的是,安装其他插件的时候,可以直接在main.js中引入并Vue.use(),但是axios不能use,只能在每个需要发送请求的组件中即使引入。

import axios from 'axios'

3) 考虑到使用的方便,可以单独抽出一个文件(例如http.js),对axios的请求进行初始化的配置,参照这里

import axios from 'axios'
export const HTTP = axios.create({
  baseURL: 'http://你的服务器地址'
  headers: {
     Authorization: `Bearer ${token}`
  }
})

之后在其他组件中使用的时候只需要引入HTTP即可,url也只需要写对应的接口地址。比如

HTTP.get('/answer')
4) 需要配置请求的header的时候,需要注意的是,在上面第3)步中设置header的方式,是只在项目第一次启动时进行设置,之后的header不会变化,导致,当用户登录的身份变化之后,token对应错误。

目前的解决方案是,采用axios.defaults.headers设置,暴露出一个函数,每次登录完给localStorage中的token赋值的时候,都检查一下token是否变化,如果变化的话,重新赋值。还是在http.js中,代码示例如下:

axios.defaults.headers.common['authorization'] = window.localStorage.getItem('authorization')
export function setAuthorizationToken (token) {
  if (token !== axios.defaults.headers.common['authorization']) {
    axios.defaults.headers.common['authorization'] = `${token}`
  }
}

5)http请求的then函数,response格式是.then(function (response) {}或者.then((response) => {}有什么区别(此处留个坑)

这个网址给出了一些建议。

8、Vue的生命周期

承接上面的axios请求,有些页面是需要服务端返回数据之后才能进行页面的渲染的。因此在那些地方调用请求就涉及到Vue的生命周期的问题。调用生命周期的钩子,可以从服务端获取到数据之后再进行渲染。比如,可以在created钩子中调用从服务端获取数据的代码。

9、v-on,缩写为@,绑定监听器,事件类型由参数指定,表达式可以是一个方法的名字或一个内联语句,如果没有修饰符也可以省略。

当用在普通元素上时,只能监听原生DOM时间,用在自定义元素组件上时,也可以监听子组件触发的自定义事件。

注意:.native表示监听组件根元素的原生事件。当有些地方不加.native时,会识别不出绑定的函数。

10、router.push的使用方法

1)path和params不能一起使用,当需要传参数的时候,需要用name指定名字,params传递参数;或者可以采用path配合query结合的方式。代码示例如下,

router.push({ name: 'user', params: { userId: 123 }})
router.push({ path: 'register', query: { plan: 'private' }})

不过,path和query的方式将在地址栏暴露出传递的参数的信息。

2)当采用router.link传对象,格式是上面的name和params时,需要JSON.stringify和JSON.parse,这样之后才可以解析出来。

3)路由的导航钩子,可以用来拦截导航或者一些其他的操作。

beforeRouteEnter
beforeRouteUpdate (2.2 新增)
beforeRouteLeave

4)router.go(n)表示前进(n>0)或者后退(n<0)了几层,不能传参数,router.go(-1)表示回退

11、本地存储localStorage

当需要存储一些信息在localStorage的时候,可以调用

window.localStorage.setItem('username', this.username)
var username = window.localStorage.getItem('username')
window.localStorage.removeItem('username')
window.localStorage.clear()

也可以使用vue.js的本地存储插件vue-local-storage
首先install
npm install vue-localstorage --save
然后在index.js中引入并use
import VueLocalStorage from 'vue-localstorage'
Vue.use(VueLocalStorage)

之后使用的时候,可以直接
this.$localStorage.set('username', this.username)
var username = this.$localStorage.get('username')

this.$localStorage.remove('username')

12、computed和methods的区别
计算属性computed可以像绑定普通属性一样的方式进行绑定,结果会被缓存,除非依赖的响应式属性变化才会重新计算。
可以将同一函数定义为一个method而不是一个计算属性。最终的结果,两种方式是相同的。
然而,不同的是计算属性是基于它们的依赖进行缓存的,计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要message还没有发生改变,多次访问,计算属性会立即放回之前计算的结果,而不必再次执行函数;但是只要发生重新渲染,method调用总会执行该函数。
13、父子组件通信props down,events up
1)父组件通过props向下传递数据给子组件
组件实例之间的作用域是孤立的,这意味着不能在子组件的模板内直接引用父组件的数据。需要在子组件的props里声明它期待得到的数据;同时在父组件中将这个数据传给子组件。举例来说:在子组件里,需要得到一个对象,一个布尔变量决定是否显示,以及一个必须的ID,可以这样定义
props: {
  models: Object,
  isShow: Boolean,
  id: { 
    type: Number,
    required: true
   }
}

在父组件中,引用该子组件的时候,传递给子组件
<your-item :models='yourModel' :isShow='false' :id='yourId'></your-item>
2)子组件通过events给父组件发送消息。
如果需要子组件做了操作,通知到父组件的,可以采用events来实现。举例如下:
在子组件里,当点击时,采用emit通知父组件对应的事件
<div @click='closeMenu'></div>
closeMenu: function() {
  this.$emit('myClose')
}

在父组件中,用v-on绑定相应的事件,调用对应的事件处理函数,控制menu是否显示

<my-menu v-show='isShow' v-on:myClose='receiveClose'></my-menu>
receiveClose:function () {
  this.isShow = false
}

14、v-model数据双向绑定
对于只需要在页面显示的数据来说,可以直接用{{}}表示,但是如果数据需要随着页面变化而更新,而不是每次进入页面时设置之后不再变化,这就要用v-model实现双向绑定了。
15、使用vue-chartjs绘制radar图官方文档)(git地址
vue-chartjs是对Chart.js的封装,可以实现各种图表的绘制。
首先需要安装
npm install vue-chartjs --save
安装完之后会需要安装chart.js
npm install chart.js --save
之后需要使用的时候直接import即可。例如,雷达图绘制时可以这样建立RadarChart.js
import {Radar, mixins} from 'vue-chartjs'
const { reactiveProp } = mixins
export default Radar.extend({
  mixins: [reactiveProp],
  mounted () {
    this.renderChart(this.chartData, {responsive: true, maintainAspectRatio: false})
  }
})

在对应需要画图的地方引入RadarChart.js,并在components里加入RadarChart,之后可以直接使用
 <radar-chart :chart-data='sendData' :height='600'></radar-chart>
注意的是,这里的chart-data是vue-chartjs默认的数据,如果使用别的名字,需要在RadarChart.js里用props声明一下
例如:
<radar-chart :my-data='sendData'></radar-chart>
import {Radar} from 'vue-chartjs'

export default Radar.extend({
  props: ['myData'],
  mounted () {
    console.log('chartData init: ' + this.myData)
    this.renderChart(this.myData, {responsive: true, maintainAspectRatio: false})
  }}

使用静态数据的时候,图可以正确显示,但是如果data是从服务端获取到的,在renderChart的时候,还没有获取到数据,导致不能正确绘制图表。这里的解决方案是,在RadarChart.js里调用watch函数,检测数据的变化,当数据变化之后,再次绘制图标。watch函数如下:
watch: {
    chartData: function () {
      console.log('chartData change: ' + this.chartData)
      this.renderChart(this.chartData, {responsive: true, maintainAspectRatio: false})
    }
  }

绘制的雷达图,图例显示不全的问题,图的默认的height和width的值都是400px,可以传height进去,可以改善这一问题。
设置雷达图的最大最小值:
 scale: {
          ticks: {
            beginAtZero: true,
            max: 100
          }
        }



参考文献
[1] https://cn.vuejs.org/ 
[2] https://github.com/Justineo/vue-awesome/
[3] http://www.alloyteam.com/2016/03/mobile-web-adaptation-tool-rem/ 
[4] http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
[5] https://juejin.im/entry/587599388d6d810058a7a41a 

[6] https://alligator.io/vuejs/rest-api-axios/

[7] https://stackoverflow.com/questions/38459451/vuejs-uncaught-in-promise-typeerror-cannot-read-property-push-of-undefined

[8] https://cn.vuejs.org/v2/guide/instance.html

[9] https://cn.vuejs.org/v2/api/#v-on
[10] https://router.vuejs.org/zh-cn/essentials/navigation.html 
[11] https://router.vuejs.org/zh-cn/advanced/navigation-guards.html
[12] http://www.opendigg.com/p/vue-local-storage
[13] https://cn.vuejs.org/v2/guide/computed.html
[14] https://cn.vuejs.org/v2/guide/components.html#Prop
[15] http://vue-chartjs.org/#/home?id=introduction
[16] https://github.com/apertureless/vue-chartjs











  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值