正文 10042字数 797,683阅读


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

    用以上的方法是完全改变了参数里的值,而有时候需要改变其中一个值,这时要注意不能通过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})
    Run code
    Cut to clipboard

      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;
      Run code
      Cut to clipboard

        APP.vue也要处理一下
        window.router.isBack export default { watch: { $route(to, from) { if (window.router.isBack) { window.router.isBack = false; } } } }
        Run code
        Cut to clipboard

          有时候从某个页面返回到相应页面,或者当前页面不记入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);
          Run code
          Cut to clipboard


            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>
            Run code
            Cut to clipboard


              【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>//不缓存的页面
              Run code
              Cut to clipboard

                2、在路由router.js中设置.vue页面是否需要缓存
                { path: '/home', component: home, meta: { keepAlive: true },//当前的.vue文件需要缓存 }, { path: '/notice', component: notice,//当前页面不需要缓存 }
                Run code
                Cut to clipboard

                  3、从缓存页面跳转到不缓存页面,或者从不缓存页面跳转到缓存页面的时候,会发现watch是不能监听路由的,是因为缓存和不缓存页面分别在不同的div里面,一个div里面是不可能监听到另一个div的路由的,所有需要把监听的路由都加上缓存(在路由添加 meta: { keepAlive: true }),路由在缓存页面之间进行跳转的时候,就可以通过监听路由来进行判断数据是否需要更新。
                  watch: { '$route' (to, from) { if( from.path == "/index"){ console.log(888) } } }
                  Run code
                  Cut to clipboard


                    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 } ......
                    Run code
                    Cut to clipboard

                      显而易见 就是一个对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('') } } ......
                      Run code
                      Cut to clipboard

                        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 } } })
                        Run code
                        Cut to clipboard

                          显而易见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) } ......
                          Run code
                          Cut to clipboard

                            在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: '详情' } }
                            Run code
                            Cut to clipboard

                              获取参数
                              let id = this.$route.params.id
                              Run code
                              Cut to clipboard

                                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
                                Run code
                                Cut to clipboard

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

                                  使用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 } }
                                  Run code
                                  Cut to clipboard

                                    在其他需要获取参数的js中引入
                                    import Vue from 'vue' import utils from '../../assets/scripts/utils' // Vue.prototype.$utils = utils // main.js中全局引入 let id = utils.getUrlKey('id') console.log()
                                    Run code
                                    Cut to clipboard

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

                                      跳转页
                                      this.$router.push({name:'路由命名',params:{参数名:参数值,参数名:参数值}})
                                      Run code
                                      Cut to clipboard

                                        接收页
                                        this.$route.params.参数名
                                        Run code
                                        Cut to clipboard

                                          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) } }
                                          Run code
                                          Cut to clipboard


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

                                            问题原因:在组件mounted钩子中调用的刷新页面内容,但测试发现这个钩子没有被调用。后来发现App.vue中使用了<keep-alive>:
                                            <template> <div id="app"> <keep-alive> <router-view></router-view> </keep-alive> </div> </template>
                                            Run code
                                            Cut to clipboard

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

                                              使用Vue组件切换过程钩子activated(keep-alive组件激活时调用),而不是挂载钩子mounted:
                                              <script> export default { // ... activated: function() { this.getCase() } }
                                              Run code
                                              Cut to clipboard