VueJS 中的模型 URL 参数
Model URL parameter in VueJS
从 继续,我只是想操作一个范围输入元素并使用该值更新 URL。
// https://github.com/vuejs/vue-router/blob/dev/examples/route-props/Hello.vue
var Hello = Vue.component('Hello', {
template: `
<div>
<h2 class="hello">Hello {{agility}} {{ $attrs }}</h2>
<input min=0 max=100 v-model="agility" type="range">
</div>
`,
props: {
agility: {
type: Number,
default: 25
}
}
});
const router = new VueRouter({
// mode: 'history',
routes: [
{ path: '*', component: Hello, props: true },
{ path: '/:agility', component: Hello, props: true },
]
})
new Vue({
router,
template: `
<div id="app">
<router-view></router-view>
</div>
`
}).$mount('#app')
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app"></div>
当没有提供任何值时,我希望将默认值 25 附加到 URL,例如https://dabase.com/tips/web/2021/Minimal-VueJS-route-bind/#25
如果有没有 vue-router 的更简单的方法,我洗耳恭听!
不用vue-router我解决了!
这里我们使用从 URL 散列部分得到的数据来设置数据:
created: function() {
var hash = window.location.hash.substr(1)
if (hash) {
this.agility = hash
}
},
当数据发生变化时,更新URL散列部分
watch: {
agility: function (newValue) {
window.location.hash = newValue
}
},
虽然该解决方案有效,但存在两个问题:
- Hello 组件改变了它自己的
agility
属性。这不应该发生(Vue 在控制台中生成警告),而是应该发出一个事件,以便上游更改 属性。这样,值总是只存储在一个地方,修改那个地方的值将在其他地方修改它。
- 如果 url 的哈希值发生变化,由于用户手动输入新的 url 或单击 link,输入中的值将不会更新
为了解决第一个问题,我们不会在 agility
属性 上使用 v-model
,因为我们不想改变它。我们需要直接监听输入的事件:
<input min=0 max=100 :value="agility" type="range" @input="updateAgility">
{
...,
methods: {
updateAgility(event /*: InputEvent */) {
this.$router.push({...this.$route, hash: "#" + event.target.value});
}
}
}
这将在输入更改值时直接更改 url。第二个问题是当 url 改变时如何更新 prop agility
.
在 created
中这样做是不够的,因为如果页面保持不变但哈希发生变化,则不会重新创建组件。
所以我们回到原来的解决方案,直接从路由器设置prop:
{
path: "*",
component: Hello,
props: route => route.hash.length > 1 ?
{ agility: Number(route.hash.slice(1))} :
{}
}
现在,无论您是从 URL 还是输入更新值,URL 和输入值始终保持同步。关于改变道具的警告消失了。
// https://github.com/vuejs/vue-router/blob/dev/examples/route-props/Hello.vue
var Hello = Vue.component('Hello', {
template: `
<div>
<h2 class="hello">Hello {{agility}}, Current route's hash: {{ $route.hash}}</h2>
<input min=0 max=100 :value="agility" @input=updateAgility type="range">
<br>
<router-link to="#1">Hash 1 link</router-link> <router-link to="#15">Hash 15 link</router-link>
</div>
`,
props: {
agility: {
type: Number,
default: 25
}
},
methods: {
updateAgility(event/*: InputEvent */) {
this.$router.push({...this.$route, hash: "#" + event.target.value});
}
}
});
const router = new VueRouter({
// mode: 'history',
routes: [
{ path: '*', component: Hello, props: route => route.hash.length > 1 ? { agility: Number(route.hash.slice(1))} : {}},
]
})
new Vue({
router,
template: `
<div id="app">
<router-view></router-view>
</div>
`
}).$mount('#app')
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app"></div>
仅供参考:也可以通过在 '$route.hash'
上创建观察器来监听组件本身的 url 变化,但这不是推荐的方式。
不用路由器也可以优雅高效的完成。使用更改或输入事件来更新哈希。
new Vue({
el: "#app",
data: {
agility: 25,
hash: 0
},
methods: {
addHash() {
window.location.hash = this.agility;
this.hash = this.agility;
}
},
created: () => {
const hash = window.location.hash.substr(1)
if (hash) {
this.agility = hash
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
<div id="app">
<h2 class="hello">Hello {{agility}}</h2>
<input min=0 max=100 v-model="agility" @change="addHash" type="range">
<h4>testing hash = {{hash}}</h4>
</div>
Change 事件在用户停止滚动或离开输入范围缩略图时触发。如果您想在移动拇指时看到变化,请使用输入事件。
为此创建一个可写的 cmoputed 属性。我认为这还不错,因为当您需要更新路线时,只需分配 this.agility = newAgility
即可,一切正常。要设置默认值 25,可以使用 created
挂钩。
但请记住,如此频繁地改变您的路线可能会导致性能问题。考虑在计算的 属性 上限制 set
函数(您可以使用 lodash.throttle
或实现您自己的)或将路由参数替换为散列参数。
// https://github.com/vuejs/vue-router/blob/dev/examples/route-props/Hello.vue
var Hello = Vue.component('Hello', {
template: `
<div>
<h2 class="hello">Hello {{agility}}</h2>
<input min=0 max=100 v-model="agility" type="range">
</div>
`,
created() {
if (typeof this.agility === 'undefined') {
this.agility = 25;
}
},
computed: {
agility: {
get() {
return this.$route.params.agility;
// Or with hash parameter
// return this.$route.hash;
},
set(agility) {
this.$router.replace(`/${agility}`);
// Or with hash parameter
// this.$router.replace({ hash: String(agility) });
},
},
},
});
const router = new VueRouter({
// mode: 'history',
routes: [
{ path: '*', component: Hello },
{ path: '/:agility', component: Hello },
]
})
new Vue({
router,
template: `
<div id="app">
<router-view></router-view>
</div>
`
}).$mount('#app')
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app"></div>
从 继续,我只是想操作一个范围输入元素并使用该值更新 URL。
// https://github.com/vuejs/vue-router/blob/dev/examples/route-props/Hello.vue
var Hello = Vue.component('Hello', {
template: `
<div>
<h2 class="hello">Hello {{agility}} {{ $attrs }}</h2>
<input min=0 max=100 v-model="agility" type="range">
</div>
`,
props: {
agility: {
type: Number,
default: 25
}
}
});
const router = new VueRouter({
// mode: 'history',
routes: [
{ path: '*', component: Hello, props: true },
{ path: '/:agility', component: Hello, props: true },
]
})
new Vue({
router,
template: `
<div id="app">
<router-view></router-view>
</div>
`
}).$mount('#app')
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app"></div>
当没有提供任何值时,我希望将默认值 25 附加到 URL,例如https://dabase.com/tips/web/2021/Minimal-VueJS-route-bind/#25
如果有没有 vue-router 的更简单的方法,我洗耳恭听!
不用vue-router我解决了!
这里我们使用从 URL 散列部分得到的数据来设置数据:
created: function() {
var hash = window.location.hash.substr(1)
if (hash) {
this.agility = hash
}
},
当数据发生变化时,更新URL散列部分
watch: {
agility: function (newValue) {
window.location.hash = newValue
}
},
虽然该解决方案有效,但存在两个问题:
- Hello 组件改变了它自己的
agility
属性。这不应该发生(Vue 在控制台中生成警告),而是应该发出一个事件,以便上游更改 属性。这样,值总是只存储在一个地方,修改那个地方的值将在其他地方修改它。 - 如果 url 的哈希值发生变化,由于用户手动输入新的 url 或单击 link,输入中的值将不会更新
为了解决第一个问题,我们不会在 agility
属性 上使用 v-model
,因为我们不想改变它。我们需要直接监听输入的事件:
<input min=0 max=100 :value="agility" type="range" @input="updateAgility">
{
...,
methods: {
updateAgility(event /*: InputEvent */) {
this.$router.push({...this.$route, hash: "#" + event.target.value});
}
}
}
这将在输入更改值时直接更改 url。第二个问题是当 url 改变时如何更新 prop agility
.
在 created
中这样做是不够的,因为如果页面保持不变但哈希发生变化,则不会重新创建组件。
所以我们回到原来的解决方案,直接从路由器设置prop:
{
path: "*",
component: Hello,
props: route => route.hash.length > 1 ?
{ agility: Number(route.hash.slice(1))} :
{}
}
现在,无论您是从 URL 还是输入更新值,URL 和输入值始终保持同步。关于改变道具的警告消失了。
// https://github.com/vuejs/vue-router/blob/dev/examples/route-props/Hello.vue
var Hello = Vue.component('Hello', {
template: `
<div>
<h2 class="hello">Hello {{agility}}, Current route's hash: {{ $route.hash}}</h2>
<input min=0 max=100 :value="agility" @input=updateAgility type="range">
<br>
<router-link to="#1">Hash 1 link</router-link> <router-link to="#15">Hash 15 link</router-link>
</div>
`,
props: {
agility: {
type: Number,
default: 25
}
},
methods: {
updateAgility(event/*: InputEvent */) {
this.$router.push({...this.$route, hash: "#" + event.target.value});
}
}
});
const router = new VueRouter({
// mode: 'history',
routes: [
{ path: '*', component: Hello, props: route => route.hash.length > 1 ? { agility: Number(route.hash.slice(1))} : {}},
]
})
new Vue({
router,
template: `
<div id="app">
<router-view></router-view>
</div>
`
}).$mount('#app')
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app"></div>
仅供参考:也可以通过在 '$route.hash'
上创建观察器来监听组件本身的 url 变化,但这不是推荐的方式。
不用路由器也可以优雅高效的完成。使用更改或输入事件来更新哈希。
new Vue({
el: "#app",
data: {
agility: 25,
hash: 0
},
methods: {
addHash() {
window.location.hash = this.agility;
this.hash = this.agility;
}
},
created: () => {
const hash = window.location.hash.substr(1)
if (hash) {
this.agility = hash
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
<div id="app">
<h2 class="hello">Hello {{agility}}</h2>
<input min=0 max=100 v-model="agility" @change="addHash" type="range">
<h4>testing hash = {{hash}}</h4>
</div>
Change 事件在用户停止滚动或离开输入范围缩略图时触发。如果您想在移动拇指时看到变化,请使用输入事件。
为此创建一个可写的 cmoputed 属性。我认为这还不错,因为当您需要更新路线时,只需分配 this.agility = newAgility
即可,一切正常。要设置默认值 25,可以使用 created
挂钩。
但请记住,如此频繁地改变您的路线可能会导致性能问题。考虑在计算的 属性 上限制 set
函数(您可以使用 lodash.throttle
或实现您自己的)或将路由参数替换为散列参数。
// https://github.com/vuejs/vue-router/blob/dev/examples/route-props/Hello.vue
var Hello = Vue.component('Hello', {
template: `
<div>
<h2 class="hello">Hello {{agility}}</h2>
<input min=0 max=100 v-model="agility" type="range">
</div>
`,
created() {
if (typeof this.agility === 'undefined') {
this.agility = 25;
}
},
computed: {
agility: {
get() {
return this.$route.params.agility;
// Or with hash parameter
// return this.$route.hash;
},
set(agility) {
this.$router.replace(`/${agility}`);
// Or with hash parameter
// this.$router.replace({ hash: String(agility) });
},
},
},
});
const router = new VueRouter({
// mode: 'history',
routes: [
{ path: '*', component: Hello },
{ path: '/:agility', component: Hello },
]
})
new Vue({
router,
template: `
<div id="app">
<router-view></router-view>
</div>
`
}).$mount('#app')
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<div id="app"></div>