javascript - 在组件内部单击按钮,调用父方法。如何?
问题描述
下面是一个包含 3 个notify()
方法的功能性 App。
第notify()
一种方法在组件索引中找到。
第二种notify()
方法在组件登录中找到。
第三种notify()
方法在父App
实例中找到。
问题:
如何通过单击登录按钮调用notify()
在父实例中找到的第三个?App
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Simple Vue.js Router Example</title>
<!-- VUE JS v2.6.1 -->
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<!-- VUE ROUTER JS v3.1.3 -->
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
<!-- BOOTSTRAP CSS v4.3.1 -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<!-- GOOGLE FONT CSS - Roboto Mono -->
<link href="https://fonts.googleapis.com/css?family=Roboto+Mono:100,300,400,500,700&display=swap" rel="stylesheet">
<!-- GOOGLE FONT CSS - Material Icons -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!-- CSS -->
<style type="text/css">
body {
font-family: 'Roboto Mono', monospace;
font-weight: 400;
font-size: 1rem;
background-color: #d7ccc8;
}
.active {
color: MediumSeaGreen;
}
.exactActive {
color: #e57373;
}
</style>
</head>
<body>
<!--
HTML
-->
<!-- VUE APP - PARENT CONTAINER -->
<div id="app" class="container">
<!-- HEADER CONTAINER -->
<header>
<!--
LINKS
-->
<!-- ROUTER LINK(S) -->
<ul>
<li>
<router-link tag="a" to="/" exact>/index</router-link>
</li>
<li>
<router-link tag="a" to="/sign-in">/sign-in</router-link>
</li>
</ul>
<!--
VIEWS
-->
<!-- ANY OF THESE CAN/DO OR DO NOT RENDER -->
<!-- DEPENDS ON ROUTER-LINK SELECTED -->
<router-view name="RTV_index"></router-view>
<router-view name="RTV_sign_in"></router-view>
</header>
</div>
<!--
JAVASCRIPT
-->
<!-- JAVA SCRIPT -->
<script type="text/javascript">
// DISABLE
Vue.config.productionTip = false;
// DISABLE
Vue.config.devtools = false;
/*
COMPONENTS
*/
// COMPONENT INDEX
const CPT_index = {
template:
`
<!-- HTML PARENT CONTAINER -->
<div style="background-color: #bcaaa4;">
<strong>Component:</strong> CPT_index
<br>
<strong>Route :</strong> ./
<br>
<strong>Params:</strong> none
<br>
<button type="button" v-on:click="notify()">NOTIFY</button>
</div>
`,
// COMPONENT SIGN IN - METHODS
methods:{
notify: function() {
console.log('Hi! I am a method inside a local component CPT_index.');
}
}
};
// COMPONENT SIGN IN
const CPT_sign_in = {
template:
`
<!-- HTML PARENT CONTAINER -->
<div style="background-color: #bcaaa4;">
<strong>Component:</strong> CPT_sign_in
<br>
<strong>Route :</strong> ./sign-in
<br>
<strong>Params:</strong> none
<br>
<button type="button" v-on:click="notify()">NOTIFY</button>
</div>
`,
// COMPONENT SIGN IN - METHODS
methods:{
notify: function() {
console.log('Hi! I am a method inside a local component CPT_sign_in.');
}
}
};
// COMPONENT 404
const CPT_404 = {
template:
`
<!-- HTML PARENT CONTAINER -->
<div style="background-color: #ef9a9a;">
<strong>CPT_404</strong>
<br>
<strong>Route :</strong> ./404
<br>
<strong>Params:</strong> none
</div>
`
}
/*
ROUTER
*/
// VUE.JS ROUTER INSTANCE
const router = new VueRouter({
// IN THIS ROUTE I WILL RENDER THESE COMPONENTS..
// ROUTER MODE - hash, history
mode: 'hash',
base: '/',
// CSS FOR ROUTER-LINK ACTIVE
linkActiveClass: "active",
// CSS FOR ROUTER-LINK exact ACTIVE
linkExactActiveClass: "exactActive",
// ROUTES(S) TO EVALUATE IN ORDER
routes: [
/*
ROUTES
*/
// ROUTE INDEX
{ name: 'index',
path: '/',
// ROUTE(S) WITH COMPONENT(S) TO RENDER IN ORDER
components: {
// ONE OR MORE...
RTV_index: CPT_index,
}
}, // END ROUTE INDEX
// --------------------------------------------------------------------------------
// ROUTE SIGN IN
{ name: 'sign_in',
path: '/sign-in',
// ROUTE(S) WITH COMPONENT(S) TO RENDER IN ORDER
components: {
// ONE OR MORE...
RTV_sign_in: CPT_sign_in,
}
}, // END ROUTE SIGN IN
// --------------------------------------------------------------------------------
/*
REDIRECT
*/
// ROUTE REDIRECT
{ name: null,
path: '*', redirect: { name: '404' },
// TRAP ANY UNDEFINED ROUTE AND...
// FORWARD IT TO /404 ROUTE
}, // END ROUTE REDIRECT
/*
TO /404
*/
// ROUTE 404
{ name: '404',
path: '/404',
// ROUTE COMPONENT(S) TO RENDER IN ORDER
components: {
// ONE OR MORE...
RTV_404: CPT_404,
}
}, // END ROUTE 404
] // END ROUTES(S) TO EVALUATE IN ORDER
});
/*
APP
*/
// VUE.JS APP INSTANCE
const App = new Vue({
// ROOT ELEMENT
el: '#app',
// ROUTER
router,
/*
DATA
*/
// APP DATA (SINGLE SOURCE OF TRUTH)
data: {
data0: true,
data1: 'Data1 - Rendered successfuly.',
data2: 'Data2 - Rendered successfuly.',
data3: 'Data3 - Rendered successfuly.',
},
/*
COMPUTED
*/
// COMPUTED PROPERTIES
computed: {
},
/*
METHODS
*/
// APP METHODS
methods:{
//Initialize App.
init: function() {
console.log('App initialized.');
if (this.supportsLocalSessionStorage()) {
console.log('HTML5 localStorage & sessionStorage Supported.');
} else {
console.error('Fatal Error: No HTML5 localStorage & sessionStorage support.');
}
},
// HTML5 Local & Session sotrage detection
supportsLocalSessionStorage: function() {
return typeof(Storage) !== 'undefined';
},
notify: function() {
console.log('Hi! I am a method inside the parent instance App.');
}
}, // END APP METHODS
/*
HOOKS
*/
// APP LIFE CYCLE HOOKS
mounted(){
this.$nextTick(function () {
// Code that will run only after the
// entire view has been rendered
// Initialize App
this.init();
})
}
});
</script>
</body>
</html>
解决方案
要实现您正在寻找的内容,您只需更改:
<button type="button" v-on:click="notify()">NOTIFY</button>
至
<button type="button" v-on:click="$parent.notify()">NOTIFY</button>
但是,由于“父级”是 $root 组件,您实际上可以调用:
<button type="button" v-on:click="$root.notify()">NOTIFY</button>
这将解决使用父级的以下问题。调用 $parent 时,您正在耦合组件层次结构,这将使重用这些组件变得困难。您可能需要考虑使用 $emit 的事件驱动系统。
<button type="button" v-on:click="$emit('notify')">NOTIFY</button>
然后在任何父组件上,您将像这样收听“通知”:
mounted () {
this.$on('notify', (event) => {
// do something in your case it would be
this.notify()
})
}
您可能还需要考虑实现一个事件总线来从应用程序中的任何位置捕获事件。
一个简单的例子是:
在 main.js 添加:
Vue.prototype.$bus = new Vue
在组件中添加:
<button type="button" v-on:click="$bus.$emit('notify')">NOTIFY</button>
然后在任何其他组件中,您可以添加:
mounted () {
this.$bus.$on('notify', (event) => {
// do something in your case it would be
})
}
希望这可以帮助!
推荐阅读
- caching - 是否可以在 MarkLogic 中的扩展树缓存上设置超时?
- linux-kernel - 为什么linux GIC(中断)驱动只允许上升沿和高电平触发?
- azure - 如何从多个 Azure 服务中删除标签?
- ios - UIImage initWithCGImage 导致 Obj-C 中的内存问题
- python - Django - CreateView 将创建的对象 id 传递给另一个 CreateView
- pyspark - pyspark中不相等的运算符给出错误的结果
- ios - iOS 应用签名期间的预填充分发清单信息
- jmeter - JMeter:在“用户”之间划分数据集
- python - 如何从 chalice 应用程序调用 sagemaker xgboost 端点?
- arrays - 如何从数组中的数组创建列