账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    vue的路由跳转到新页面,scrollBehavior起作用了,可是页面并没有从顶部开始。
    20
    0

    我在route/index.js代码是这样的:
    import Vue from 'vue'
    import Router from 'vue-router'
    //import HelloWorld from '@/components/HelloWorld'
    import IndexPage from '@/pages/IndexPage'
    import dedtailPage from '@/pages/detailPage'
    import orderListPage from '@/pages/orderListPage'
    import count from '@/pages/detail/count'
    import forecast from '@/pages/detail/forecast'
    import analysis from '@/pages/detail/analysis'
    import publish from '@/pages/detail/publish'

    Vue.use(Router)

    const scrollBehavior = (to, from, savedPosition) => {

    console.log("position");

    if (savedPosition) {

      console.log("1");
    return savedPosition

    } else {

      console.log("2");
    const position = {}
    if (to.hash) {
      console.log("3");
        
      position.selector = to.hash
    }
    if (to.matched.some(m => m.meta.scrollToTop)) {
          console.log("4");
        
      position.x = 0
      position.y = 0
    }
    console.log(position);
    return position

    }
    }

    //const scrollBehavior = (to, from, savedPosition) => {
    //return { x: 0, y: 0 }
    //}

    export default new Router({

    mode: 'history',
    base: __dirname,
    
    //控制滚动位置
    scrollBehavior,
    routes: [
        {
            path: '/',
            component: IndexPage
        },
        {
            path: '/orderList',
            component: orderListPage,
            meta: { scrollToTop: true }
        },
        {
            path: '/detail',
            component: dedtailPage,
            redirect: '/detail/count',
            children: [
                {
                    path: 'count',//路径前不能加"/",否则就不是子路由了,而是同级路由了。
                    component: count,
                    meta: { scrollToTop: true }
                },
                {
                    path: 'forecast',//路径前不能加"/",否则就不是子路由了,而是同级路由了。
                    component: forecast,
                    meta: { scrollToTop: true }
                },
                {
                    path: 'analysis',//路径前不能加"/",否则就不是子路由了,而是同级路由了。
                    component: analysis,
                    meta: { scrollToTop: true }
                },
                {
                    path: 'publish',//路径前不能加"/",否则就不是子路由了,而是同级路由了。
                    component: publish,
                    meta: { scrollToTop: true }
                },
            ]
        }
    ]

    })
    我在浏览器中,可以看到执行了这个scrollBehavior,可是子路由的跳转时候,没有从顶部重新开始。
    其中的父组件的代码是这样的:
    <template>

    <div class="detail-wrap">
        <div class="detail-left">
            <div class="product-board">
                <img :src="productsIcon" alt="" />
                <ul>
                    <!--<li v-for="(item, index) in products" :key="index">{{item.name}}</li>-->
                    <router-link v-for="(item, index) in products" :key="index" tag="li" :to="{path:item.path === 'analysis'?item.path+'#product_intro':item.path}" active-class="active">{{item.name}}</router-link>
                </ul>
            </div>
        </div>
        <div class="detail-right">
            <keep-alive>
                <router-view></router-view>
            </keep-alive>
        </div>
    </div>

    </template>

    <script>

    export default {

    name: "detailPage",
    data () {
        return {
            products: [
                {
                    name: "数据统计",
                    path: "count",

    // icon: require("../assets/images/1.jpg"),

                    active: false
                },
                {
                    name: "数据预测",
                    path: "forecast",
                    active: false
                },
                {
                    name: "流量分析",
                    path: "analysis",
                    active: false
                },
                {
                    name: "广告发布",
                    path: "publish",
                    active: false
                },
            ],
            //图片的映射,根据url的地址来映射图片
            imgMap: {
                '/detail/count': require("../assets/images/1.jpg"),
                '/detail/forecast': require("../assets/images/2.jpg"),
                '/detail/analysis': require("../assets/images/3.jpg"),
                '/detail/publish': require("../assets/images/4.jpg")
            }
            
        }
    },
    computed: {
        productsIcon () {

    // console.log(this.$route,this.$router);

            return this.imgMap[this.$route.path]
        }
    }
    

    }
    </script>

    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style>
    .detail-wrap {
    width: 1200px;
    margin: 0 auto;
    overflow: hidden;
    padding-top: 20px;
    }
    .detail-left {
    float: left;
    width: 200px;
    text-align: center;
    }
    .detail-right {
    float: left;
    width: 980px;
    margin-left: 20px;
    padding-bottom: 40px;
    }
    .product-board {
    background: #fff;
    padding: 20px 0;
    }
    .product-board ul {
    margin-top: 20px;
    }
    .product-board li {
    text-align: left;
    padding: 10px 15px;
    cursor: pointer;
    }
    .product-board li.active,
    .product-board li:hover {
    background: #4fc08d;
    color: #fff;
    }
    .product-board li a {
    display: block;
    }
    .sales-board {
    background: #fff;
    }
    .sales-board-form {
    }
    .sales-board-intro h2 {
    font-size: 20px;
    padding: 20px;
    }
    .sales-board-intro p {
    background: #f7fcff;
    padding: 10px 20px;
    color: #999;
    line-height: 1.8;
    }
    .sales-board-form {
    padding: 30px 20px;
    font-size: 14px;
    }
    .sales-board-line {
    clear: both;
    padding-bottom: 20px;
    }
    .sales-board-line-left {

    display: inline-block;
    width: 100px;

    }
    .sales-board-line-right {

    display: inline-block;
    width: 75%;

    }
    .sales-board-des {
    border-top: 20px solid #f0f2f5;
    padding: 15px 20px;
    }
    .sales-board-des p {
    line-height: 1.6;
    }
    .sales-board-des h2 {
    font-size: 20px;
    padding-bottom: 15px;
    }
    .sales-board-des h3 {
    font-size: 18px;
    font-weight: bold;
    padding: 20px 0 10px 0;
    }
    .sales-board-des li {
    padding: 5px 0;
    }
    .sales-board-table {
    width: 100%;
    margin-top: 20px;
    }
    .sales-board-table th {
    background: #4fc08d;
    color: #fff;
    }
    .sales-board-table td {

    border: 1px solid #f0f2f5;
    padding: 15px;

    }
    .buy-dialog-title {
    font-size: 16px;
    font-weight: bold;
    }
    .buy-dialog-btn {
    margin-top: 20px;
    }
    .buy-dialog-table {
    width: 100%;
    margin-bottom: 20px;
    }
    .buy-dialog-table td,
    .buy-dialog-table th{
    border: 1px solid #e3e3e3;
    text-align: center;
    padding: 5px 0;
    }
    .buy-dialog-table th {
    background: #4fc08d;
    color: #fff;
    border: 1px solid #4fc08d;
    }
    </style>
    其中一个子路由代码:
    <template>
    <div class="sales-board">

      <div class="sales-board-intro">
        <h2>数据统计</h2>
        <p>历史资料、科学实验、检验、统计等所获得的和用于科学研究、技术设计、查证、决策等的数值加以统计为解决方案做前期准备。</p>
      </div>
      <div class="sales-board-form">
          <div class="sales-board-line">
              <div class="sales-board-line-left">
                  产品类型:
              </div>
              <div class="sales-board-line-right">
                  <v-chooser :selections="buyTypes" @on-change="onParamChange('buyType',$event)"></v-chooser>
              </div>
          </div>
          <div class="sales-board-line">
              <div class="sales-board-line-left">
                  适用地区:
              </div>
              <div class="sales-board-line-right">
                  <v-selection :selections="districts" @on-change="onParamChange('district',$event)"></v-selection>
              </div>
          </div>
          <div class="sales-board-line">
              <div class="sales-board-line-left">
                  有效时间:
              </div>
              <div class="sales-board-line-right">
                <v-chooser :selections="periodList" @on-change="onParamChange('period',$event)"></v-chooser>
              </div>
          </div>
          <div class="sales-board-line">
              <div class="sales-board-line-left">
                  总价:
              </div>
              <div class="sales-board-line-right">
                 {{price}}元
              </div>
          </div>
          <div class="sales-board-line">
              <div class="sales-board-line-left">&nbsp;</div>
              <div class="sales-board-line-right">
                  <div class="button" @click="showPayDialog">
                    立即购买
                  </div>
              </div>
          </div>
      </div>
      <div class="sales-board-des">
        <h2>产品说明</h2>
        <p>历史资料、科学实验、检验、统计等所获得的和用于科学研究、技术设计、查证、决策等的数值加以统计为解决方案做前期准备。</p>
    
        <table class="sales-board-table">
          <tbody>
              <tr class="ui-table-row">
                  <td class="col-first">
                      <div class="intro-pic">
                          <label>安全安保</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>办公文教</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>彩票</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>车辆物流</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>成人用品</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>出版传媒</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>电脑硬件</label>
                      </div>
                  </td>
              </tr>
              <tr class="ui-table-row">
                  <td class="col-first">
                      <div class="intro-pic">
                          <label>电子电工</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>房地产建筑装修</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>分类平台</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>服装鞋帽</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>箱包饰品</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>化工原料制品</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>机械设备</label>
                      </div>
                  </td>
              </tr>
              <tr class="ui-table-row">
                  <td class="col-first">
                      <div class="intro-pic">
                          <label>家庭日用品</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>家用电器</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>教育培训</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>节能环保</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>金融服务</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>礼品</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>旅游住宿</label>
                      </div>
                  </td>
              </tr>
              <tr class="ui-table-row">
                  <td class="col-first">
                      <div class="intro-pic">
                          <label>美容化妆</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>母婴护理</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>农林牧渔</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>软件</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>商务服务</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>生活服务</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>食品保健品</label>
                      </div>
                  </td>
              </tr>
              <tr class="ui-table-row">
                  <td class="col-first">
                      <div class="intro-pic">
                          <label>手机数码</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>通讯服务设备</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>网络服务</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>医疗服务</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>游戏</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>运动休闲娱乐</label>
                      </div>
                  </td>
                  <td>
                      <div class="intro-pic">
                          <label>招商加盟</label>
                      </div>
                  </td>
              </tr>
          </tbody>
      </table>
      </div>
      <my-dialog :is-show-dialog="isShowPayDialog" @close="hidePayDialog">
                <table class="buy-dialog-table">
                    <tr>
                        <th>产品类型</th>
                        <th>有效时间</th>
                        <th>适用地区</th>
                        <th>总价</th>
                    </tr>
                    <tr>
                        <td>{{ buyType.label }}</td>
                        <td>{{ period.label }}</td>
                        <td>{{ district.label }}</td>
                        <td>{{ price }}</td>
                    </tr>
                </table>
                <h3 class="buy-dialog-title">请选择银行</h3>
                <bank-chooser @on-change="onChangeBank"></bank-chooser>
                <div class="button buy-dialog-btn" @click="confirmBuy">确认购买</div>
            </my-dialog>
            <my-dialog :is-show="isShowErrDialog" @close="hideErrDialog">
                支付失败!
          </my-dialog>
            <check-order-dialog :is-show-check-dialog="isShowCheckDialog" :order-id="orderId" @on-close-check="closeCheckOrder"></check-order-dialog>

    </div>
    </template>

    <script>
    import VSelection from '../../components/base/selection'
    import VChooser from '../../components/base/chooser'
    import Dialog from '../../components/Dialog'
    import bankChooser from '../../components/bankChooser'
    import checkOrderDialog from "../../components/checkOrder"

    export default {
    components: {

    VChooser,
    VSelection,
    myDialog:Dialog,
    bankChooser,
    checkOrderDialog

    },
    data () {

    return {
        isShowPayDialog: false,
            isShowCheckDialog: false,
            isShowErrDialog: false,
        buyType: {},
        district:{},
        period: {},
        price: 0,
        bankId:null,
            orderId:null,
        buyTypes: [
            {
              label: '红色版',
              value: 0
            },
            {
              label: '绿色版',
              value: 1
            },
            {
              label: '紫色版',
              value: 2
            }
        ],
        periodList: [
            {
                label: '半年',
                value: 0
            },
            {
                label: '一年',
                value: 1
            },
            {
                label: '两年',
                value: 2
            },
            {
                label: '三年',
                value: 3
            }
        ],
        districts: [
            {
              label: '北京',
              value: 0
            },
            {
              label: '上海',
              value: 1
            },
            {
              label: '广州',
              value: 2
            },
            {
              label: '天津',
              value: 3
            },
            {
              label: '武汉',
              value: 4
            },
            {
              label: '重庆',
              value: 5
            },
        ]
    }

    },
    methods: {

      getPrice () {
            let reqParams = {
                district: this.district,
                buyType: this.buyType.value,
                period: this.period.value,
            }
            this.$http.post('/api/getPrice', reqParams).then((res) => {
                console.log(res);
                this.price = res.data.amount;
                
            }, (err) => {
                console.log(err);
            })
            
        },
      onParamChange (attr_, val) {
            this[attr_] = val;
            console.log(attr_,this[attr_]);
        },
        onChangeBank (bankObj) {
            this.bankId = bankObj.id;
            console.log(this.bankId);
        },
        confirmBuy () {
            let reqParams = {
                district: this.district,
                buyType: this.buyType.value,
                period: this.period.value,
                bankId: this.bankId
            }
            this.$http.post('/api/createOrder', reqParams).then((res) => {
                console.log(res);
                this.orderId = res.data.orderId;
                this.isShowCheckDialog = true;
                this.isShowPayDialog = false;
                
            }, (err) => {
                console.log(err);
                this.isShowErrDialog = true;
                
            })
        },
        showPayDialog () {
            this.isShowPayDialog = true
        },
        hidePayDialog () {
            this.isShowPayDialog = false
        },
        hideErrDialog () {
            this.hideErrDialog = false
        },
        closeCheckOrder () {
            this.isShowCheckDialog = false
        },
      

    },
    mounted () {

        this.buyType = this.buyTypes[0];
        this.district = this.districts[0];
        this.period = this.periodList[0];
        this.getPrice();

    }
    }
    </script>

    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style scoped>

    .buy-dialog-title {
      font-size: 16px;
      font-weight: bold;
    }
    .buy-dialog-btn {
      margin-top: 20px;
    }
    .buy-dialog-table {
      width: 100%;
      margin-bottom: 20px;
    }
    .buy-dialog-table td,
    .buy-dialog-table th{
      border: 1px solid #e3e3e3;
      text-align: center;
      padding: 5px 0;
    }
    .buy-dialog-table th {
      background: #4fc08d;
      color: #fff;
      border: 1px solid #4fc08d;
    }
    

    </style>
    实在找不到问题所在,明明该函数scrollBehavior执行了,可是页面跳转的时候,新页面没有从顶部开始,还是会从上一个页面的滚动条位置开始。求救

    0
    打赏
    收藏
    点击回答
        全部回答
    • 0
    • 爪良 普通会员 1楼

      在Vue中,当跳转到新的页面时,如果使用了scrollBehavior,那么页面的高度可能会发生改变,导致页面无法从顶部开始。为了解决这个问题,可以使用Vue Router的beforeRouteUpdate生命周期钩子函数来实现。

      首先,你需要在你的Vue Router配置文件中添加一个beforeRouteUpdate钩子函数。这个函数将在页面从某个状态改变时被调用。

      javascript export default { routes: [ { path: '/my-page', name: 'myPage', component: MyPage, beforeRouteUpdate: function (to, from, next) { // 在这里,你可以处理从某个状态改变的情况 } } ] }

      在beforeRouteUpdate钩子函数中,你可以根据需要来处理页面的高度变化。例如,你可以设置一个新的height属性,或者在页面的高度改变时清除滚动条。

      javascript export default { routes: [ { path: '/my-page', name: 'myPage', component: MyPage, beforeRouteUpdate: function (to, from, next) { to.height = 100; // 设置新的高度属性 } } ] }

      这样,当页面从某个状态改变时,它就会从顶部开始,而不是从新的页面开始。

    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部