想在不修改原函数的基础上(或者无察觉的基础上)给一些函数加上调用前通知的钩子,查了 Stack Overflow 得到的也是修改原函数的。在测试时发现好像没有效果,但查看组件中的this
中的 VNode 信息那个函数确实已经更改,后来想了想是不是绑定方法有问题于是试了试带括号的,结果发现真的有问题...
<template>
<div>
<a @click="test()">click</a>
</div>
</template>
<script>
export default {
methods: {
test () {
console.log(1)
}
},
mounted: function () {
this.test = function () {
console.log(2)
}
}
}
</script>
如果 <a @click="test">click</a>
未带括号,调用的函数是 methods 的旧函数,打印 1,
如果 <a @click="test()">click</a>
带上括号,那调用的就是新函数,打印 2。
有能直接给函数加调用前通知的钩子的方法没.
一般写代码对于无参数的写第一种还是第二种.
这两者还有什么坑点需要注意.
想两者兼容有什么办法吗.
如果是 created 时修改,两者都可以是修改后的函数。
♪(・ω・)ノ谢谢指教~。
1
IsaacYoung 2019-10-24 14:59:36 +08:00
test()返回值是 undefined
|
2
qping 2019-10-24 14:59:44 +08:00 1
|
3
TomVista 2019-10-24 15:02:28 +08:00 1
|
4
TomVista 2019-10-24 15:09:10 +08:00
我了去,
这是啥? 你可以试试 data:{ test:fun(){log(1)} }, 这个东西很复杂,我讲不明白,等个大佬 |
5
cyrbuzz OP @TomVista
谢谢~, Vue 似乎也是将`@click="test()"`这样的包裹在了一个函数里,包裹在函数中是可以任意修改的, 有没有兼容两者的方法修改方法或者直接给函数加个钩子?最初的目的也只是想在函数调用前能有个通知。 |
6
lllllliu 2019-10-24 15:33:19 +08:00
这就可以用代理实现了呀。或者你可以搞一下 AOP。
|
7
shintendo 2019-10-24 15:44:14 +08:00 4
1.
不带括号的情况下,绑定的是 this.test 函数,并且在 mount 阶段就绑好了,你后面改动 this.test 的指向,不影响绑定的那个函数。 带括号的情况下,绑定的是 function(){this.test()}函数,this.test 的值是每次函数调用时计算的,所以你改变 this.test 的指向有效。 2. 我个人习惯于始终带括号,因为传参更显式。 要说有什么坑点的话,不带括号需要注意默认的 e 参数。 |
8
TomVista 2019-10-24 15:47:02 +08:00
@cyrbuzz 不是这个原因 , 你试试下面的代码
<template> <div @click="test()">{{test}} <p>{{d}}</p> </div> </template> <script> export default { name: 'trainerList', layout: 'home', data () { return { d:function(){ } } }, async mounted () { }, beforeCreated () { this.test = function (params) { console.log('1'); } }, created () { this.test = function (params) { console.log('2'); } }, beforMounted () { this.test = function (params) { console.log('3'); } }, mounted () { this.test = function (params) { console.log('4'); } this.test() this.$forceUpdate() }, methods: { test:function () { console.log('123'); } } } </script> |
10
cyrbuzz OP @TomVista
喔...用$forceUpdate 可以强制刷新,近乎完美,非常感谢~~,如果能在其他组件里也应用就更好了~。 |
11
lllllliu 2019-10-24 16:24:47 +08:00
@cyrbuzz #9 function
你现在打开控制台~ 丢一个 function,其实也只是一个在 window 下的一个属性 /对象而已。。。可以去看一下 VUE 各个部分的实现原理。。暴力实现你这个所谓的前置方法其实很容易的。多看看呀。 |
12
cyrbuzz OP @lllllliu
谢谢,恕我愚昧,一开始在 Stack Overflow 里给出的方法也是 window 下的 hack。 ``` function a () { console.log('old') } let b = window.a window.a = function () { console.log('new') b() } a() ``` 结合后面 @TomVista 大佬给出的知乎中的解答和 @shintendo 大佬给出的解答, Vue 底层应该也是用的`addEventListener`给元素添加事件监听, ``` <body> <a id="click">click</a> </body> <script> function a () { console.log('old') } let c = document.getElementById('click') c.addEventListener('click', a) let b = window.a window.a = function () { console.log('new') b() } </script> ``` 这样的尝试后依然是无效的... 现在还是有点没解决~。 |
13
luoway 2019-10-24 19:46:02 +08:00 1
> 想在不修改原函数的基础上(或者无察觉的基础上)给一些函数加上调用前通知的钩子
使用 Vue.mixin 在 beforeMount、beforeUpdate 生命周期里对 this 上方法(排除 vue 保留方法)进行装饰 |
15
zlu1123 2019-10-24 22:39:41 +08:00
加与不加括号的区别在于事件对象参数 event 的处理。不加括号时,函数第一个参数为 event,加了括号后,需要手动传入 $event 才能获得事件对象
|