Vue项目踩的坑

 

1.vue-router有两种模式  hash  和history  (前端路由)

 默认模式为hash, vue中使用router-link  to=`/home`  替代a标签 
   hash   修改 #后路径 并且#后路径不发送给服务器  
   history API 无# 可以前后跳转 但是怕回车  服务器没有配置对应路径指向同一个html文件就回404  mode=history 改为history模式

2.dev 与 build 的路径问题 

尽量使用相对路径而不是绝对路径 不然在服务器上根目录变化路径会报错

3.图片路径在变量里 打包出现解析不了路径的问题

  会把解析完的src变量当成字符串处理而不会去找到打包对应的位置。

  解决方法:1.使用线上的图片地址(需要先写好接口)

                    2.requiren引入图片

4.状态管理vuex / store

状态管理:是用来单个同步组件在不同页面的状态的,如tab-bar、购物车等。

如果你有一处需要被多个实例间共享的状态,可以简单地通过维护一份数据来实现共享:

1.如果只有简单的几个组件状态共享,我们采用一个简单的 store 模式

var store = {
  debug: true,
  state: {
    message: 'Hello!'
  },
  setMessageAction (newValue) {
    if (this.debug) console.log('setMessageAction triggered with', newValue)
    this.state.message = newValue
  },
  clearMessageAction () {
    if (this.debug) console.log('clearMessageAction triggered')
    this.state.message = ''
  }
}

2.如果复杂的话引入vuex 

vuex.vue:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

export default new Vuex.Store({
	state:{
		isLogin:false,
	},
	mutations:{
		//改变登陆状态
		handleLogin(state){
			state.isLogin = true;
		}
	}
})

app.vue:

import store from './vuex'
import Vue from 'vue'
import App from './App'
import router from './router'
// 注入全局组件
import './components'

window.$vm = new Vue({
  el: '#app',
  router,
  store:store,
  components: {
    App
  },
  template: '<App/>'
})

package.json导入vuex。  创建 vuex.Store 仓库对象用来保存全局的状态。再把store在实例里注册。

Store中state用来存储数据。 可以在需要的地方this.$store.state中取到值。并且state中的值只能通过mutations中的方法改变。

在需要的地方this.$store.commit('‘方法名’,‘选填参数’);

例:

this.$store.commit({
	type:'handleGoodsCar',
	goodsInfo:goodsInfo,
    aaaa:123
})
handleGoodsCar(state,params){
	var goodsInfo = parames.goodsInfo;
    var aaaa = params.aaaa;
}

5router-link 绑定事件无效

需要加.native   

.native是什么?  .native - 监听组件根元素的原生事件。 

主要是给自定义的组件添加原生事件。 而router-link就是用的别人定义的自定义组件 使能像H5标签一样接受事件

6.组件、弹窗切换缓动动画

<transition name="fade">
	  <div class="sign-success" v-if="showSignSuccess">
	         <span>签到成功,获得{{sign_data[today].integral}}积分</span>
	  </div>
</transition>
.fade-enter-active, .fade-leave-active {
  transition: opacity .5s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
  opacity: 0;
}

transtition标签里name可以定义变化类型 对应css写下变化效果。需要通过v-if  v-show来控制变化。

模块和引入的组件都可以使用。

7.router切换左右拉效果、引入VUEX 添加路由切换效果

vue有对应的切换组件。 只需要用transition包裹住切换的组件就行。 不同页面多种切换类型 可以设置动态name改变

注意:如果vuex会尽量复用组件、如果两个组件类似被复用了就不会有动效了!。可以添加一个key属性保证不复用。

<transition :name="transitionName">
        <router-view class="child-view"></router-view>
</transition>

8.路由守卫

创建路由就有router.beforEach方法。在跳转url时候。to就是下一个url。from是当前url。

如要给不同页面配置不同的访问效果。可以在路由中配置meta属性,可以在ro和from下面取到。

export default new Router({
  routes: [
  {
    path: '/index',
    name: '/index',
    component: resolve => require(['@/pages/index'], resolve),
  },
  {
  	path:'/user',
    name:'/user',
    component: resolve => require(['@/pages/user'], resolve),
    meta:{
    	requireAuto:true //添加改字段,表明该页面需要验证登陆状态才可以进入
    }
  }
  ]
})
//路由跳转时,判断该页面是否是需要登陆才能访问的。必须要调用next函数才会继续执行。
router.beforeEach((to,from,next) => {
	if(to.meta.requireAuto){
		if(!store.state.isLogin){
			console.log('不给进');
			router.replace({path:'/index'});
		}
		next();
		console.log('切换回index');
	}else{
		next();
		console.log('无序授权页面');
	}
   })
//路由全局跳转后钩子事件 用来重置到页面最上位置。不用next参数
router.afterEach((to,from) => {
  	window.scrollTo(0,0);
})

9.保存登录状态。

本地存储信息方式有 sessionStorage localstorage  cookie

1.可以在vuex中保存登录之后的状态。  但一刷新后就没有了

2.保存在sessionStorage中页面关闭前一直有效。刷新后在session中获取。但你关了页面后数据就没了

3.可以在localstorage中也保存一份账号密码。在服务端设置一段过期时间。每次打开页面获取数据。

10.分享承接页

11.多级路由

12.微信分享需要签名

13.页面跳转传递数据

 (1).路由参数

              1.name + params 

                     页面就不用router-link跳转了。绑定个click事件。用this.$router.push方法跳转(注意是使用 name 来配合params传值跳转)   (push方法跳会在history里留下痕迹 如果不想返回上一个页面可用 replace 调用方法与push一直,只是效果为替换当前页不留下history痕迹)

传递页如下:

toAddress(region_codes_, address_, id_) {
	this.$router.push({
		name: '/address',
		params: {
			region_codes: region_codes_,
			address: address_,
			id: id_
		}
	})
},

跳转页如下:可以通过 this.$router.params.XXX来取到对应设置的值

let region_codes = this.$route.params.region_codes;
let address = this.$route.params.address;
let id = this.$route.params.id;

               2.path + query

             使用方法与第一种类似,只是 path 替代了name     。 query 替代 params .。

获取值的时候由this.$route.params.XXX  变成了this.$route.query.XXX

 TIPS:1.区别是query配置的参数会在url显示出来 。( 例子:/index?id=1    参数以?拼接在url后方便刷新时获取)

            2.params 需要为对应router 设置name属性。(例子:/index  隐藏参数)

            3.在router里设置参数,再router-link里设置传值的方式(例子:/index/1    这种后台过滤了页面后刷新可能会找不到页面)

 (2).使用vuex进行数据传递

14.页面缓存

app.vue中设置keep-alive标签用来设置缓存页面。有部分页面不需要缓存的话 可在router中为每页配置对应的meta(keepAlive)属性进行判断、

{
    path: '/index',
    name: '/index',
    component: resolve => require(['@/pages/index'], resolve),
    meta:{
    	keepAlive:true
    }
  }
<keep-alive>
	<router-view v-if="$route.meta.keepAlive" class="child-view"></router-view>
</keep-alive>
<router-view class="child-view"></router-view>

15.数据交互方式。

跨域请求数据一般两种方式。

1.CORS "跨域资源共享"(Cross-origin resource sharing)

 后台配合开启。可完成get post 等简单请求。vue中推荐使用的 axios (也只支持这种方法!)

2.jsonp。

  也要处理接口能使用jsonp。常用jquery里封装的$.ajax方法。会自动调用回函函数、

16.http请求拦截器 与 响应拦截器

  请求拦截器即在发送请求之前做处理 例如 config.Api + path来配置url请求路径。

  响应拦截器即在返回后做相应处理  例如 返回为400时候 提示请求失败、

Tips: 1.数据交互方式推荐使用 axios + cors  而不是 jq + jsonp 。因为axios里做拦截器更便捷。且jsonp的拦截器有点小问题。

17.使用vuex中数据同步刷新

1.vue中data里变量值改变了,在本页面中所有使用的地方都会刷新

2.如果data中的数据是通过别的地方赋值的(想获取vuex里的数据),那么在vuex中的数据改变时候。data中数据不会同步刷新。因为data属性只是在组件实例化时赋值一次。

 如果想使用vuex中数据。且实时刷新 使用computed。

3.computed 是依赖于后者的计算属性。当vuex值改变时候。当前页面数据也会刷新。

18.本地mock数据

在后台接口未实现前、前端可以根据接口规范 先使用本地模拟数据进行页面制作、

常见的有 mock.js 。安装依赖 后在main中引用、为对应的url 配置返回数据。 即可在请求时候拦截、用mockHttpResquest对象替代作为返回数据。

Tips: 数据交互方式推荐使用 axios + cors  而不是 jq + jsonp 。因为mock.js是用mock对象替代返回的是。只支持ajax  不支持jsonp、

19.fixed定位挡住下拉内容

类似tabbar在最下方。 但是不在文档流里面 所以内容最下面一部分会被挡住。

目前做法是在tabbar组件里 再加上一个等高的div占据文档流的位置。(封在一个组件里)

Tips:有些页面是有选项卡的用来transtion组件。 就必须为absolute 。脱离文档流了。 可以把整体作为transtion组件就会在一个文档流里了

注意不能:在absolute里面给个等高下边距。ios有bug不生效

20.使用组件库(vex,swiper等)修改组件样式

在没提供修改方式的情况下。需要通过覆盖组件类名的方法修改样式。但注意如果开启了scoped 样式就只会作用于本页面。修改不了组件样式

21.swiper组件的使用。

swiper组件比vux的组件功能更全面。 但如果你已经引用了vux 。再组件化引入swiper可能会冲突。

建议就引入原生swiper使用。使用方法及配置与官网一致。

vue中使用原生swiper的方法:

1.安装  npm install vue-awesome-swiper --save

2.引入swiper   在main.js中  

import Vue from 'vue'
import 'swiper/dist/css/swiper.css' 
import VueAwesomeSwiper from 'vue-awesome-swiper'
Vue.use(VueAwesomeSwiper)

在要使用的组件中

<div class="swiper-container banner" id="swiper">
	<div class="swiper-wrapper">
		<div class="swiper-slide swiper-no-swiping">
			<img class="w100" src="../../static/images/index/banner.png" alt="" />
		</div>
		<div class="swiper-slide swiper-no-swiping">
			<img class="w100" src="../../static/images/index/banner.png" alt="" />
		</div>
	</div>
	<div class="swiper-pagination pagination" slot="pagination"></div>
</div>
import Swiper from 'swiper'
//在mounted中注册配置swiper
var mySwiper = new Swiper('#swiper', {
	pagination: '.swiper-pagination',
	loop: true,
	effect: 'coverflow',
	slidesPerView: 1.02,
	centeredSlides: true,
	coverflow: {
		rotate: 0,
		stretch: 0,
		depth: 100,
		modifier: 2,
		slideShadows: false
	}
})

22.select与省市级联选项

要绑定省市级联地址可以使用vux的 x-address组件。

select中用v-model绑定属性。 第一条为默认不可选取的提示语(要设置需要将group_id制空就会默认选中第一项)。

v-bind:value="" 绑定每一个选项的值。

<select required v-model="group_id" name="dealer">
	<option value="" disabled selected hidden>经销商名称</option>
	<option v-for="option in list_info.list" v-bind:value="option.id">
		{{option.name}}
	</option>
</select>

23.jssdk 签名问题

签名成功需要发送请求前与签名后的url一致才能成功、如果url变了签名就没用了(需要动态重新加载一遍)。

1.需要注意的是有些需要微信授权的应用首次访问URL会有跳转导致签名失败。

2.vue单页面应用 ios url会停留在首次进入的页面。因此只需要首次加载一次签名就好了 。而安卓正常 需要每个页面都动态加载一次。(这里需要区别处理)

猜你喜欢

转载自blog.csdn.net/qq_39643110/article/details/82620713