在日常开发时,有时候需要更新路由中的某些参数,用到的方法是router.push()或router.replace(),用前者会记录到历史的路径,而后者不会。调用方法的前提,是不需要改变路径,所以,在方法中传入query就可以(假设router是挂在了VUE的原型下),如下:

this.$router.push({ query: { status: 1 } })

用以上的方法是完全改变了参数里的值,而有时候需要改变其中一个值,这时要注意不能通过this.$route.query.status=1改写后再重新赋值给query,这是不会改变路由的。像 let params = this.$route.query; params.status = 1;this.$router.push({ query: params });这种方式是无效的,需要让query指定为另外一个对象。实现如下:

let query = Object.assign({status: 1}, this.$route.query )
this.$router.push({ query})

vue 中router.go;router.push和router.replace的区别

router.go(n) 

这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)

router.push(location) 
想要导航到不同的 URL,则使用 router.push 方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。

router.replace(location) 
跟 router.push 很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。

router路由自定义后退事件

项目用的 vue+vue-router;
APP返回时自定义的window.back();
全局缓存了window.routerList = [];
前进添加路由,后退删除路由;
router.js代码如下

import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)

const Home = () = >import(/* webpackChunkName: "systemManage" */ './views/Home.vue') 
 
const router = new Router({
    routes: [{
        path: '/Home',
        name: 'Home',
        component: Home,
    }]
}) 

window.routerList = [];

router.afterEach((to, from) = >{
    window.back = function() {
        window.router.isBack = true;
        if (window.routerList.length == 0) {
            window.router.isBack = false;
            return;
        } else if (window.routerList.length == 1) {
            window.router.isBack = false;
            console.log('不能后退了!!!');
        } else {
            let backPath = window.routerList[window.routerList.length - 2];
            window.router.push(backPath);
        }
    }
    if (!window.router.isBack) {
        var routerListLen = window.routerList.length;
        if (routerListLen > 1 && to.fullPath === window.routerList[routerListLen - 2]) {
            window.router.isBack = true;
        }
    }

    // 修改title    
    document.title = to.meta.title || '默认标题';

    if (window.router.isBack) {
        console.log('后退') window.routerList.pop();
    } else {
        console.log('前进') window.routerList.push(to.fullPath);
    }
});
window.router = router;
export default router;

APP.vue也要处理一下

window.router.isBack export default {
    watch: {
        $route(to, from) {            
            if (window.router.isBack) {                
                window.router.isBack = false;            
            }        
        }    
    }
}

有时候从某个页面返回到相应页面,或者当前页面不记入routerList;
这时候就要做特殊处理了;方法如下:

// 处理当前页不记入历史
const currentRouter = this.$route.fullPath; 
// 当前页路由地址
window.routerList = window.routerList.filter(item => {    
    return item.indexOf(currentRouter) < 0;
})
// 如果从当前页跳走又跳回来时有重复路由,则添加下边这一段代码(两项相等则删除最后一个)
const rl = window.routerList;
if (window.routerList[rl.length - 1] === rl[rl.length - 2]) {    
    window.routerList.pop();
}
const targetRoute = '/history/page';
// 清除当前路由以后的所有路由
window.routerList = window.routerList.slice(0, window.routerList.indexOf(targetRoute) + 1)
// 返回到指定路由
let routerList = window.routerList;
const index = routerList.indexOf(targetRoute);
routerList.splice(index + 1, routerList.length - 2);

vue之watch用法

对应一个对象,键是观察表达式,值是对应回调。值也可以是方法名,或者是对象,包含选项。在实例化时为每个键调用 $watch() ;

//使用官方vue-cli脚手架书写
<template>
  //观察数据为字符串或数组
   <input v-model="example0"/>
   <input v-model="example1"/>
  /当单观察数据examples2为对象时,如果键值发生变化,为了监听到数据变化,需要添加deep:true参数
   <input v-model="example2.inner0"/>
</template>
<script>
   export default {
      data(){
        return {
          example0:"",
          example1:"",
          example2:{
            inner0:1,
            innner1:2
          }
        }
      },
      watch:{
        example0(curVal,oldVal){
          console.log(curVal,oldVal);
        },
        example1:'a',//值可以为methods的方法名
        example2:{
         //注意:当观察的数据为对象或数组时,curVal和oldVal是相等的,因为这两个形参指向的是同一个数据对象
          handler(curVal,oldVal){
            console.log(curVal,oldVal)
          },
          deep:true
        }
      },
      methods:{
        a(curVal,oldVal){
          conosle.log(curVal,oldVal)
        }
      }
    }
</script>

【Vue】Vue2.0页面缓存和不缓存的方法,以及watch监听会遇到的问题

vue2.0页面缓存和不缓存的方法:
1、在app中设置需要缓存的div

<keep-alive>//缓存的页面
   <router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>//不缓存的页面

2、在路由router.js中设置.vue页面是否需要缓存

{
   path: '/home',
   component: home,
   meta: { keepAlive: true },//当前的.vue文件需要缓存
},
{
   path: '/notice',
   component: notice,//当前页面不需要缓存
}

3、从缓存页面跳转到不缓存页面,或者从不缓存页面跳转到缓存页面的时候,会发现watch是不能监听路由的,是因为缓存和不缓存页面分别在不同的div里面,一个div里面是不可能监听到另一个div的路由的,所有需要把监听的路由都加上缓存(在路由添加 meta: { keepAlive: true }),路由在缓存页面之间进行跳转的时候,就可以通过监听路由来进行判断数据是否需要更新。

watch: {
	'$route' (to, from) {
	    if( from.path == "/index"){
		console.log(888)
	    } 
        }
}

method/computed/watch的使用和区别
methods
在vue中method就是普通意义的function域,可以定义方法来进行属性的修改,或者返回,很简单下面来看例子:

<template>
    <p>{{msg}}</p>
    <button v-on:click="reverseMessage">逆转消息</button>
</template>
export default {

  name: 'Home',
  data: function () {
    return {
      ......
      msg: 'this msg for vue.js!!!',
      ......
    }
  },
  methods: {
    reverseMessage: function () {
      this.msg = this.msg.split('').reverse().join('')
      return this.msg
    }
 ......

显而易见 就是一个对msg这个串的反转;

computed
其实在一定程度上 methods和computed效果是一样的.但是:

计算属性(computed)是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。

可以这样理解,computed并不是一个方法,而是依赖于属性的,就是一个属性的封装,属性的值不变化,那么不会多次调用computed,所以性能更好 
ok~ 继续抛出一个例子:

<template>
      <p>Computed reversed message: "{{ reversedMessage }}"</p>
</template>
export default {

  name: 'Home',
  data: function () {
    return {
      ......
    }
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // console.log('1')
      return this.msg.split('').reverse().join('')
    }
  }
......

watch
Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch——特别是如果你之前使用过 AngularJS。然而,通常更好的做法是使用计算属性而不是命令式的 watch

下面这段代码摘自官网


### watch

var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
  },
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
})


### computed
var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  }
})

显而易见watch在这里就显得有一些多余了 
但是watch其实他是一个侦听,就类似与java中的接口会调,可以支持异步操作 
抛一段代码:

<template>
    {{firstname}}
    <button @click="firstname = 'change complete'">修改txt</button>
</template>
export default {

  name: 'Home',
  data: function () {
    return {
      ......
      firstname: 'hello',
      ......
    }
  },
   watch: {
    firstname: function (newval, oldval) {
      console.log(oldval, newval)
    }
 ......

在div中input输入框v-model这个firstname,然后在input中输入时,watch会侦听这个firstname,进而打出newval和oldval的日志 
method/computed/watch是vue中script域中核心的使用

获取url后面的参数
使用路由获取页面参数

在路由中设置path:

{
    path: '/detail/:id/',
    name: 'detail',
    component: detail,
    meta: {
        title: '详情'
    }
}

获取参数

let id = this.$route.params.id

1
备注: 
1、参数名需要保持一致 
2、如果路由中没有传参(http://192.168.1.12:8080/#/detail),会报错,页面无法显示,正常页面为 http://192.168.1.12:8080/#/detail/234

如果有的参数可传可不传,可以使用?传参 
例如:http://192.168.1.12:8080/#/detail/?id=123 
获取的时候:

let id = this.$route.query.id

这样即使取不到参数,页面也不会报错

使用js获取页面参数 
如果是在普通js文件中,想获取url后面的参数,可以新建一个工具类,utils.js:


/* eslint-disable */
export default{
    getUrlKey: function (name) {
        return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.href) || [, ""])[1].replace(/\+/g, '%20')) || null
    }
}

在其他需要获取参数的js中引入

import Vue from 'vue'
import utils from '../../assets/scripts/utils'
// Vue.prototype.$utils = utils // main.js中全局引入
let id = utils.getUrlKey('id')
console.log()

url为http://192.168.1.12:8080/#/detail/?id=123时,可以得到id为123

跳转页

this.$router.push({name:'路由命名',params:{参数名:参数值,参数名:参数值}})

接收页

this.$route.params.参数名
index.js页面

{
   path: '/info/:phone',
   name: 'info',
   component: info,
   props: true
}
info页传参:

<router-link :to="/info/13800138000">我的订单</router-link>
update页接收:

props: ['phone'],
watch: {
  phone(v) {
    console.log(v)
  }
}

路由切换时页面刷新页面
第二次进入页面,页面路由参数已经改变,但是页面内容不会刷新。

问题原因:在组件mounted钩子中调用的刷新页面内容,但测试发现这个钩子没有被调用。后来发现App.vue中使用了<keep-alive>:

<template>
  <div id="app">
    <keep-alive>
      <router-view></router-view>
    </keep-alive>
  </div>
</template>

keep-alive是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。这就是问题所在了。
解决办法:

使用Vue组件切换过程钩子activated(keep-alive组件激活时调用),而不是挂载钩子mounted:

<script>
export default {
  // ...
  activated: function() {
    this.getCase()
  }
}
打赏作者
微信
支付宝

发表评论

返回顶部