vue的路由跳转到新页面,scrollBehavior起作用了,可是页面并没有从顶部开始。

我在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执行了,可是页面跳转的时候,新页面没有从顶部开始,还是会从上一个页面的滚动条位置开始。求救

阅读 3.2k
1 个回答
新手上路,请多包涵

请问楼主这个问题解决了嘛,我也遇到了这个问题,查询资料
router.beforeEach((to, from, next) => {

document.documentElement.scrollTop = 0;
document.body.scrollTop = 0;
window.scrollTo(0, 0);
next()

});
也不行啊

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题