Element-Inject/Provide调用组件中的方法
Element-Inject/Provide调用组件中的方法
问题背景
在做一个前端多语言切换的效果时, 遇到一个问题. 就是系统菜单是后端提供的, 前端给一个语言字段, 后端做过滤,显示对应语言的菜单
这个时候前端切换语言时, ElementUI组件能自动切换成相应语言(引入i18n插件) 但是系统的菜单栏就必须要刷新页面才能更新成对应语言的菜单(可以直接ctrl+r 或者 window.location.reload(),太瓜皮了这样)
然后找到了一个方式, 就是通过inject/provide的方式可以在组件中调用另外一个组件中的方法. 不过那个例子上写的是在router-view上做的v-if, 我这里的场景只是单纯想在一个组件里调另外一个组件的方法(当然也可以使用this.$refs.refName.function(), 但是这个是要父子组件才能行). 然后实验了一下发现居然在其他组件里也能用, 所以就先记下来
解决方式
定义两个组件A 以及 组件B, 组件A中一个change事件想要触发组件B中的 function b(){}
此时可以直接在A组件中inject注入B组件provide的方法
参考地址: https://blog.csdn.net/weixin_43878117/article/details/114820914
- provide方法
<template>
<layout>
<side-menu slot="side" v-if="isRouterAlive"></side-menu>
<main-header slot="header"></main-header>
<div slot="main">
<transition name="fade" mode="out-in">
<router-view></router-view>
</transition>
</div>
</layout>
</template>
<script>
export default {
provide(){
return {
reload: this.reload
}
},
components: {
// 布局
Layout: () => import("@/components/layout/Layout.vue"),
// 左侧菜单
SideMenu: () => import("@/components/layout/SideMenu.vue"),
// 头部
MainHeader: () => import("@/components/layout/Header.vue")
},
data(){
return {
isRouterAlive: true
}
},
methods:{
reload(){
this.isRouterAlive = false;
this.$nextTick(()=>{
this.isRouterAlive = true;
})
}
}
};
</script>
此处通过v-if能够控制side-menu组件去重新加载一次DOM, 然后再method中顶一个一个方法reload(), 再把定义的reload()方法provide出去
- 然后在要调用reload()方法的组件中注入inject刚刚provide出的方法
<template>
<el-row type="flex" class="header" justify="space-between">
<el-col :span="10" class="header-left">
<div class="header-left-logo">
<a href="javascript:void(0)" class="logo">
<img src="@/assets/layout/head_logo_black.png" width="43px" height="29px" />
</a>
</div>
</el-col>
<el-col :span="14" class="header-right">
<div class="welcome-title">
<a href="../../../book/index.html" class="help" target="_blank"
><i class="el-icon-question">{{ $t("header.guideBook") }}</i></a
>
<img src="@/assets/layout/home_4_1@2x.png" width="40px" height="40px" />
{{ $t("header.welcome") }}
<span class="user">{{ user }}</span
> |
<a href="/" @click="logout" underline="false">{{ $t("header.exit") }} </a>
<el-dropdown @command="handleCommand" style="margin-left: 10px">
<span class="el-dropdown-link">
{{ lang }}<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
v-for="(item, index) in languageList"
:key="index"
:command="item.code"
>{{ item.name }}</el-dropdown-item
>
</el-dropdown-menu>
</el-dropdown>
</div>
</el-col>
</el-row>
</template>
<script>
export default {
inject: ['reload'],
data() {
return {
value: "",
lang: "English",
headerTitle: "Midea"
};
},
methods: {
handleCommand(command) {
this.reload();
this.languageList.forEach(item => {
if (item.code === command) {
this.lang = item.name;
if (command === "ja") {
this.$i18n.locale = "ja";
} else if (command === "zh-Hans" || command === "zh-Hant") {
this.$i18n.locale = "zh";
} else {
this.$i18n.locale = "en";
}
localStorage.setItem("lang", item.code);
return;
}
});
},
}
};
</script>
inject之后可以直接在当前组件中调用provide出的方法
延伸
- 此方法适用于调用没有引入的组件中的方法
- 这样控制组件显示隐藏可以不用整个页面去刷新
本文来自博客园,作者:你啊347,转载请注明原文链接:https://www.cnblogs.com/LinKinSJ/p/16326958.html