Vue.js 如何防止在Vue js中更改参数化子组件时重新加载父组件
我有一个页面,其中包含证券列表(子组件)的ClientPortfolio(父组件)加载到v-data-table列表中 我遇到的问题是,每次单击列表中的安全性时,ClientPortfolio都会被完全重新加载,导致整个列表被刷新,导致scroll和所选类被重置,以及不必要的性能开销。 我查看了Vue的文档,但似乎没有任何内容指出如何仅在子组件具有参数时刷新它。看起来父组件正在刷新,因为每次选择安全性时路由都在更改,尽管希望Vue只知道子组件(嵌套路由)正在更改,因此只需重新加载子组件 我得到的最接近的答案是在代码中没有解释如何实现这一点的解释 routes.js: ClientPortfolions.vue中的路由器链接: 更新:Vue.js 如何防止在Vue js中更改参数化子组件时重新加载父组件,vue.js,vuejs2,vue-component,vue-router,Vue.js,Vuejs2,Vue Component,Vue Router,我有一个页面,其中包含证券列表(子组件)的ClientPortfolio(父组件)加载到v-data-table列表中 我遇到的问题是,每次单击列表中的安全性时,ClientPortfolio都会被完全重新加载,导致整个列表被刷新,导致scroll和所选类被重置,以及不必要的性能开销。 我查看了Vue的文档,但似乎没有任何内容指出如何仅在子组件具有参数时刷新它。看起来父组件正在刷新,因为每次选择安全性时路由都在更改,尽管希望Vue只知道子组件(嵌套路由)正在更改,因此只需重新加载子组件 我得
经过一段时间的更新,我终于找到了问题所在,@matpie在其他地方指出,我发现我的App.vue是罪魁祸首,因为在应用程序的根目录中有一个:key add:
这是一个我从某处使用的模板,但在“工作”时,我从不需要查看它,取下钥匙后,一切正常,标记matpie应答已接受。而不是在此处使用路由器。为所选证券和投资组合在根级别声明两个变量
根据所选投资组合列出证券
从显示的证券中选择证券时,使用
this.$root.selectedSecurityId = id;
您可以在安全组件级别使用watch
从根本上说
<security selectedid="selectedSecurityId" />
组件将如下所示:
<portfolio>
//active. list goes here
</portfolio>
........
<security selectedid="selectedSecurityId">
//info goes here
</security>
//活跃的。清单在这里
........
//信息在这里
上述方法将有助于避免路由器。希望这会有所帮助。我曾经遇到过类似的问题。在我看来,这是由路径字符串解析引起的。 尝试为路线设置名称。并用对象替换路由器链接到参数。 并移除路由器视图
:键道具。它不需要在那里。它用于在管线更改时强制更新零部件。这通常是坏代码的标志。您的组件(安全性
)应该对路由参数更新做出反应。不是父组件强制它
因此,请尝试将代码更改为:
路线:[
{
路径:'/client/:clientno/portfolioNo',
组成部分:客户组合,
name:“ClientPortfoliosName”//它可以是您想要的任何东西。它只是内部使用的别名。
儿童:[
{
路径:“security/:securityNo”,
名称:“投资组合”,无论如何,考虑将路由名称作为良好的实践。
构成部分:安全
}
]
},
]
它应该会起作用
注意:在您的路由器链接中
您应指向您想要导航到的路线。在这种情况下,Vue.js中的默认行为是防止组件重新加载。Vue的反应性系统自动映射属性依赖关系,并且只执行最少量的工作来确保DOM是最新的
通过在任意位置使用:key
属性,您可以告诉Vue.js,此元素或组件应仅在键匹配时匹配。如果密钥不匹配,旧密钥将被销毁,并创建一个新密钥
看起来您还在数据对象上引入路由参数(Security.vue
)。这些参数不会在管线参数更改时更新,您应该将它们拉入计算属性,以便它们始终保持最新
导出默认值{
计算:{
clientNo:(vm)=>vm.$route.params.clientNo,
}
}
这将确保clientNo
始终匹配路由器中找到的内容,而不管Vue是否决定重新使用此组件实例。如果在clientNo
更改时需要执行其他副作用,可以添加观察者:
vm.$watch(“clientNo”,(clientNo)=>{/*…*/})
删除安全组件的本地注册后,是否可以再次检查?因为这是由vue路由器本身处理的,所以不需要它
components: { // delete this code
security: Security
},
您可以提供JSFIDLE或等效工具吗?使用vuex存储当前选定的安全性是否比使用路由器加载子组件更容易?然后,只要vuex store属性更改,您就可以抓取子数据。这将如何解决在安全性更改时重新加载ClientPortfolio的问题?我可以vuex存储证券等,但父组件仍然需要重新加载一次。此外,我在每个投资组合中都有数千种证券,我不认为vuex设计用于存储如此多的od数据。如果您可以共享更多代码,那就太好了。您是否尝试过使用以下代码包装组件:您的顶层上碰巧没有定义:键?如果是这样的话,这可能就是问题所在。但是如果没有路由器,用户可以拥有特定证券的最终url,而不需要浏览客户和投资组合吗?为了安全起见,复制和粘贴url对于用户通过电子邮件/聊天等进行交流非常重要。这是一种非常好的方法。为此,我们可以在路由器中加载一个页面,从url读取传递的安全性和公文包,并相应地加载。如果未传递任何安全id或投资组合,则显示默认页面。设置将信息作为URL的一部分传递时的顶级变量。使用类似于/
的URL。因此,您可以避免使用静态关键字。但是使用此。$root.selectedSecurityId=id更新安全性将如何更新路由?我不明白it@Kajal... 你可以用gists,只要你想做什么就做什么
<template>
<v-flex>
<v-layout class="screen-header">
<v-flex class="screen-title">Security Details </v-flex>
</v-layout>
<v-divider></v-divider>
<v-layout align-center justify-space-between row class="contents-placeholder" mb-3 pa-2>
<v-layout column>
<v-flex class="form-group" id="security-portfolio-selector">
<label class="screen-label">Sequence</label>
<span class="screen-value">{{security.SequenceNo}}</span>
</v-flex>
<v-flex class="form-group">
<label class="screen-label">Security</label>
<span class="screen-value">{{security.SecurityNo}}-{{security.SequenceNo}}</span>
</v-flex>
<v-flex class="form-group">
<label class="screen-label">Status</label>
<span class="screen-value-code" v-if="security.Status !== ''">{{security.Status}}</span>
</v-flex>
</v-layout>
</v-layout>
</v-flex>
</template>
<script>
export default {
props: ['securityNo'],
data () {
return {
clientNo: this.$route.params.clientno,
securityDetailsLoading: false
}
},
computed: {
security () {
return this.$store.state.SecurityDetails
}
},
created () {
if (this.securityNo.length > 1) {
this.getSecurityDetails()
}
},
methods: {
getSecurityDetails: function () {
let self = this
this.securityDetailsLoading = true
this.$store.dispatch('getSecurityDetails', {
securityNo: this.securityNo,
clientNo: this.clientNo
}).then(function (serverResponse) {
self.securityDetailsLoading = false
})
}
}
}
</script>
const router = new Router({
mode: 'history',
routes: [
{
path: '/',
component: Dashboard
},
{
path: '/client/:clientno/details',
component: Client,
props: true
},
{
path: '/client/:clientno/portfolios/:portfolioNo',
component: ClientPortfolios,
name: 'ClientPortfolios',
children: [
{ path: 'security/:securityNo',
component: Security,
name: 'Security'
}
]
}
]
})
this.$root.selectedSecurityId = id;
<security selectedid="selectedSecurityId" />
....
watch:{
selectedid:function(){
//fetch info and show
}
}
...
<portfolio>
//active. list goes here
</portfolio>
........
<security selectedid="selectedSecurityId">
//info goes here
</security>
components: { // delete this code
security: Security
},