วิธีตั้งค่าพารามิเตอร์การสืบค้น URL ใน Vue ด้วย Vue-Router


114

ฉันพยายามตั้งค่าพารามิเตอร์การสืบค้นด้วยVue-routerเมื่อเปลี่ยนช่องป้อนข้อมูลฉันไม่ต้องการไปที่หน้าอื่น แต่ต้องการแก้ไขพารามิเตอร์การสืบค้น url ในหน้าเดียวกันฉันกำลังทำสิ่งนี้:

this.$router.replace({ query: { q1: "q1" } })

แต่สิ่งนี้ยังรีเฟรชหน้าและตั้งค่าตำแหน่ง y เป็น 0 เช่นเลื่อนไปที่ด้านบนสุดของหน้า นี่เป็นวิธีที่ถูกต้องในการตั้งค่าพารามิเตอร์การสืบค้น URL หรือมีวิธีที่ดีกว่านี้


แก้ไข:

นี่คือรหัสเราเตอร์ของฉัน:

export default new Router({
  mode: 'history',
  scrollBehavior: (to, from, savedPosition)  => {
    if (to.hash) {
      return {selector: to.hash}
    } else {
      return {x: 0, y: 0}
    }
  },
  routes: [
    ....... 
    { path: '/user/:id', component: UserView },
  ]
})

คำตอบ:


134

นี่คือตัวอย่างในเอกสาร:

// with query, resulting in /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})

อ้างอิง: https://router.vuejs.org/en/essentials/navigation.html

ตามที่กล่าวไว้ในเอกสารเหล่านั้นrouter.replaceทำงานเหมือนrouter.push

ดูเหมือนว่าคุณจะมีสิทธิ์ในโค้ดตัวอย่างที่เป็นปัญหา แต่ฉันคิดว่าคุณอาจต้องใส่อย่างใดอย่างหนึ่งnameหรือpathพารามิเตอร์ด้วยเพื่อให้เราเตอร์มีเส้นทางที่จะนำทางไป หากไม่มีnameหรือpathก็ดูไม่มีความหมายมากนัก

นี่คือความเข้าใจปัจจุบันของฉันตอนนี้:

  • query เป็นทางเลือกสำหรับเราเตอร์ - ข้อมูลเพิ่มเติมบางอย่างสำหรับส่วนประกอบเพื่อสร้างมุมมอง
  • nameหรือpathเป็นข้อบังคับ - เป็นตัวกำหนดองค์ประกอบที่จะแสดงใน<router-view>ไฟล์.

นั่นอาจเป็นสิ่งที่ขาดหายไปในโค้ดตัวอย่างของคุณ

แก้ไข: รายละเอียดเพิ่มเติมหลังความคิดเห็น

คุณได้ลองใช้เส้นทางที่มีชื่อในกรณีนี้หรือไม่? คุณมีเส้นทางแบบไดนามิกและง่ายกว่าในการระบุพารามิเตอร์และแบบสอบถามแยกกัน:

routes: [
    { name: 'user-view', path: '/user/:id', component: UserView },
    // other routes
]

จากนั้นในวิธีการของคุณ:

this.$router.replace({ name: "user-view", params: {id:"123"}, query: {q1: "q1"} })

ในทางเทคนิคไม่มีความแตกต่างระหว่างด้านบนและด้านบนthis.$router.replace({path: "/user/123", query:{q1: "q1"}})แต่การจัดหาพารามิเตอร์ไดนามิกบนเส้นทางที่ตั้งชื่อนั้นง่ายกว่าการเขียนสตริงเส้นทาง แต่ในทั้งสองกรณีควรคำนึงถึงพารามิเตอร์ของข้อความค้นหาด้วย ไม่ว่าในกรณีใดฉันไม่พบสิ่งผิดปกติกับวิธีจัดการพารามิเตอร์แบบสอบถาม

หลังจากที่คุณอยู่ในเส้นทางที่คุณสามารถดึงข้อมูลพารามิเตอร์แบบไดนามิกของคุณเป็นและการค้นหาของคุณเป็นthis.$route.params.id paramsthis.$route.query.q1


ฉันพยายามให้เส้นทางด้วย แต่สิ่งนี้ไม่ได้หยุดการเลื่อนไปที่ด้านบนของหน้าฉันได้แก้ไขคำถามด้วยตัวเลือกเราเตอร์ด้วยอาจมีการเปลี่ยนแปลงบางอย่างที่จำเป็นที่นั่น
Saurabh

พารามิเตอร์การสืบค้นของคุณมีวัตถุประสงค์เพื่อเลื่อนไปยังตำแหน่งที่ถูกต้องในเอกสารหรือไม่ เช่นเดียวกับคำถามอื่น ๆ ของคุณเกี่ยวกับแท็ก Anchor ?
มานี

ไม่ฉันแค่ต้องการเพิ่มพารามิเตอร์การค้นหาใน URL ฉันไม่ต้องการเลื่อนใด ๆ ที่นี่
Saurabh

ฉันเพิ่งทดสอบตัวเลือกในการตั้งค่าภายในเครื่องพารามิเตอร์แบบสอบถามทำงานได้ตามปกติ ฉันสามารถนำทางไปยังเส้นทางใหม่และเข้าถึงพารามิเตอร์การสืบค้นดังที่แสดงในคำตอบที่อัปเดตของฉัน ดังนั้นปัญหาคือ - คุณไม่ต้องการให้มันเลื่อน? หรือปัญหาคือการรีเฟรชแอปทั้งหมดอีกครั้ง?
มานี

ดังนั้นฉันจึงอยู่ในหน้าเดียวกันเมื่อฉันเลือกอินพุตบางอย่างฉันต้องการเพิ่มใน URL แต่เมื่อฉันทำเช่นนั้นการเลื่อนจะเกิดขึ้น การเลื่อนเป็นปัญหาสำหรับฉัน ฉันไม่ได้พยายามนำทางไปยังหน้าอื่นฉันแค่อยากอยู่ในหน้าเดียวกันและเพิ่ม / แก้ไขพารามิเตอร์การสืบค้น url ที่ดูเหมือนไม่มี
Saurabh

16

โดยไม่ต้องโหลดหน้าใหม่หรือรีเฟรชโดมhistory.pushStateก็สามารถทำงานได้
เพิ่มวิธีนี้ในส่วนประกอบของคุณหรือที่อื่น ๆ เพื่อทำสิ่งนั้น:

addParamsToLocation(params) {
  history.pushState(
    {},
    null,
    this.$route.path +
      '?' +
      Object.keys(params)
        .map(key => {
          return (
            encodeURIComponent(key) + '=' + encodeURIComponent(params[key])
          )
        })
        .join('&')
  )
}

ดังนั้นทุกที่ในคอมโพเนนต์ของคุณให้เรียกaddParamsToLocation({foo: 'bar'})เพื่อพุชตำแหน่งปัจจุบันด้วยพารามิเตอร์แบบสอบถามในหน้าต่างสแตกประวัติ

หากต้องการเพิ่มพารามิเตอร์การสืบค้นไปยังตำแหน่งปัจจุบันโดยไม่ต้องกดรายการประวัติใหม่ให้ใช้history.replaceStateแทน

ทดสอบด้วย Vue 2.6.10 และ Nuxt 2.8.1

ระวังด้วยวิธีนี้!
Vue Router ไม่ทราบว่า url มีการเปลี่ยนแปลงดังนั้นจึงไม่แสดง url หลัง pushState



5
this.$router.push({ query: Object.assign(this.$route.query, { new: 'param' }) })

1
ฉันชอบคำตอบนี้มากที่สุด น่าเสียดายที่สาเหตุนี้Error: Avoided redundant navigation to current location
Max Coplan

แก้ไข:this.$router.push({ query: Object.assign({...this.$route.query}, { new: 'param' }) })
Max Coplan

2
แต่ตอนนี้ฉันคิดเกี่ยวกับเรื่องนี้คุณก็ทำได้this.$router.push({ query: {...this.$route.query,new: 'param'},) })
Max Coplan

3

หากคุณพยายามเก็บพารามิเตอร์บางตัวไว้ในขณะที่เปลี่ยนพารามิเตอร์อื่น ๆ อย่าลืมคัดลอกสถานะของแบบสอบถาม vue router และไม่นำกลับมาใช้ใหม่

วิธีนี้ใช้ได้ผลเนื่องจากคุณกำลังทำสำเนาที่ไม่ได้อ้างอิง:

  const query = Object.assign({}, this.$route.query);
  query.page = page;
  query.limit = rowsPerPage;
  await this.$router.push({ query });

ในขณะที่ด้านล่างนี้จะนำไปสู่ ​​Vue Router โดยคิดว่าคุณกำลังใช้แบบสอบถามเดิมซ้ำและนำไปสู่NavigationDuplicatedข้อผิดพลาด:

  const query = this.$route.query;
  query.page = page;
  query.limit = rowsPerPage;
  await this.$router.push({ query });

แน่นอนคุณสามารถย่อยสลายออบเจ็กต์คิวรีได้ดังต่อไปนี้ แต่คุณจะต้องระวังพารามิเตอร์การค้นหาทั้งหมดในเพจของคุณมิฉะนั้นคุณอาจเสี่ยงที่จะสูญเสียพารามิเตอร์เหล่านี้ในการนำทางที่เป็นผลลัพธ์

  const { page, limit, ...otherParams } = this.$route.query;
  await this.$router.push(Object.assign({
    page: page,
    limit: rowsPerPage
  }, otherParams));
);

หมายเหตุในขณะที่ตัวอย่างข้างต้นใช้สำหรับpush()แต่ก็ใช้ได้replace()เช่นกัน

ทดสอบด้วย vue-router 3.1.6


3

สำหรับการเพิ่มพารามิเตอร์การสืบค้นหลายรายการนี่คือสิ่งที่ใช้ได้ผลสำหรับฉัน (จากที่นี่https://forum.vuejs.org/t/vue-router-programmatically-append-to-querystring/3655/5 )

คำตอบข้างบนนั้นใกล้เคียง ... แม้ว่าด้วย Object.assign มันจะกลายพันธุ์สิ่งนี้ $ route.query ซึ่งไม่ใช่สิ่งที่คุณต้องการทำ ... ตรวจสอบให้แน่ใจว่าอาร์กิวเมนต์แรกคือ {} เมื่อทำ Object.assign

this.$router.push({ query: Object.assign({}, this.$route.query, { newKey: 'newValue' }) });

2

ในการตั้ง / ลบพารามิเตอร์การสืบค้นหลายรายการพร้อมกันฉันได้ลงเอยด้วยวิธีการด้านล่างซึ่งเป็นส่วนหนึ่งของthisส่วนผสมระดับโลกของฉัน ( ชี้ไปที่องค์ประกอบ vue):

    setQuery(query){
        let obj = Object.assign({}, this.$route.query);

        Object.keys(query).forEach(key => {
            let value = query[key];
            if(value){
                obj[key] = value
            } else {
                delete obj[key]
            }
        })
        this.$router.replace({
            ...this.$router.currentRoute,
            query: obj
        })
    },

    removeQuery(queryNameArray){
        let obj = {}
        queryNameArray.forEach(key => {
            obj[key] = null
        })
        this.setQuery(obj)
    },

1

ปกติฉันใช้วัตถุประวัติสำหรับสิ่งนี้ นอกจากนี้ยังไม่โหลดหน้าเว็บซ้ำ

ตัวอย่าง:

history.pushState({}, '', 
                `/pagepath/path?query=${this.myQueryParam}`);

0

นี่คือวิธีง่ายๆของฉันในการอัปเดตพารามิเตอร์การสืบค้นใน URL โดยไม่ต้องรีเฟรชหน้า ตรวจสอบให้แน่ใจว่าใช้ได้กับกรณีการใช้งานของคุณ

const query = { ...this.$route.query, someParam: 'some-value' };
this.$router.replace({ query });
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.