10533

在学习用vue做项目中,有这样一个需求,在某个页面中有一个分页组件,组件的功能有一个是点击某一数字,需要往url中push参数,但原来url中可能有其他的参数,也有可能没有其他参数,有可能已经有关于页数的参数,也有可能没有,使用 $router.push() 的形式则会覆盖原有的query,因此开始了我的探索之路(可以直接看最后结论)

step 1 (查找其他方法)

主要试图找到其他方法,可以直接添加新参数或者修改已有参数,绕过需要获取已有参数的坑

很明显失败了,一个是没有找到其他方法,二是 $router.push() 也没有发现满足我需求的调用方法,因此确定必须要获取原有参数,进行修改或者新增,最后调用 $router.push() 完成任务

step 2 (确定思路)

经过思考,我觉得代码逻辑应该是这样:

methods: {
    changePage (num) {
        var _this = this,
            oldQuery = _this.$router.currentRoute.query,
            newQuery = _this.getNewQuery(oldQuery, 'page', num);
        _this.$router.push({
            query: newQuery
    getNewQuery (oldQuery, name, val) {
        var obj = {}, // 这里初始化一定是{}而不是null,否则会出错
            flag = false;
        for (key in oldQuery) {
            if (oldQuery.hasOwnProperty(key)) {
                if (key === name) {
                    // 这里是修改已有参数
                    obj[key] = val;
                    flag = true;
                } else {
                    obj[key] = oldQuery[key]
        // 这里是新增参数
        if (!flag) {
            obj[name] = val
        return obj;
复制代码

到此已经可以完成任务了

step3 (尝试优化,假如要添加或者修改多个参数)

这样是可以完成任务的,然后我又想了一下,如果是要修改或者是添加多个参数呢,可以把要修改或者添加的放到一个对象中,大概是这样

methods: {
    changePage (num) {
        var _this = this,
            oldQuery = _this.$router.currentRoute.query,
            obj = {
                page: num,
                category: 'all'
            newQuery = _this.getNewQuery(oldQuery, obj);
        _this.$router.push({
            query: newQuery
    getNewQuery (oldQuery, new) {
        var obj = {}, // 这里初始化一定是{}而不是null,否则会出错
            flag = false;
        obj = ....(这里还没想清楚怎么写)
        return obj;
复制代码

这时突然发现,这不就是两个对象合并吗,好像有个原生方法可以直接用啊—— Object.assign(obj1, obj2) ,如果能成功的话,那根本不用写个新函数啊(当初我还再想为啥vue-router不提供一个类似我上面实现的函数)

step4 (尝试Object.assign())

因为这里涉及到深浅拷贝的知识,我就顺便又学习了一下 深浅拷贝 对象深拷贝的两种方法

methods: {
    changePage (num) {
        Object.assign(_this.$router.currentRoute.query, {page: num})
复制代码

讲道理我感觉已经完成任务了,但实际情况是我打开devtool,发现 $route.query 确实和我想的一样变化,但是 url 没有变,可能直接修改 $route.query 参数不管用,必须调用 $route.push() 方法,因此再作调整(这里究竟为什么直接改query参数不管用,应该是涉及到了vue-router的源码实现,目前这阶段,我就先忽视了。。。):

final

methods: {
    changePage (num) {
       var _this = this,
        obj = JSON.parse(JSON.stringify(_this.$router.currentRoute.query)) // 这里我们需要的应该是值,因此必须转为深拷贝
      Object.assign(obj, {page: num})
      _this.$router.push({
        query: obj
复制代码

成功!(不忘忘记巩固一下数组、对象各自的深浅拷贝方法啊)

追风筝的呆子 vue-router
私信