ahk编程_AHK编程可视化的实现
AHK編程可視化的實現
可視化編程意義
可視化編程是一個語言能力的提現,這個是AHK實現的可視化編程!本實例為一個公開分享的實例,為方便大家參考,特搬運轉移到這里!
實例
實例的使用方法就是將實例替換掉類庫的U()函數!歡迎大家!進一步創新分享!
;旋轉的點
;~ u(){
;~ f(r(,20,40)),f=0
;~ while 17>++f,p:=s(t*3-f/9),a=0
;~ loop 16
;~ fc(w/2+s(r:=p+a++*pi/8)*f*h/35,h/2+c(r)*f*h/35,4,h(t/2+(16-f)/16))
;~ }
;旋轉的線
;~ u(){
;~ f(),i=0,j=99
;~ loop,%j%
;~ dl(n:=w/2,m:=h/2,n+c(i/j*pi*2)*c(i/j*pi*4+t)*n,m+s(i/j*pi*2)*s(i/j*pi*4+t)*m,h(i++/j))
;~ }
;燈籠
;~ u(){
;~ f(),i=0,j=256
;~ loop,%j%
;~ fc(w/2+sin(i/j*pi)*cos(i/j*pi*32+t)*w/2,h*i/j,3,h(i++/j+t/8))
;~ }
;旋轉立方體
;~ u()
;~ {
;~ f()
;~ q:=pi*2/3
;~ loop,3
;~ dl(j+c(d*q+t-u:=q/2)*j:=w/2,k:=h*2/3,n:=j+c(d*q+t)*j,l:=h/3)dl(j,0,n,l)dl(j,h,m:=j+c(++d*q+t-u)*j,k)dl(n,l,m,k)
;~ }
;詭異圖像
;~ u(){
;~ y:=0,x=mod(++t|=0,w)
;~ Loop,%h%{
;~ sp(x,y++,i<30?h(i/30):0),a=b=i=0
;~ while,b*b+a*a<4&&++i<30
;~ a:=(a*a-b*b+x*3/w-2,b=2*a*b+y*2.5/h-5/4)
;~ }}
;一串字母
;~ u(){
;~ q=Q_q@FiRIf@_Ez@_P_@_BdH_@_@_UU@@
;~ f()
;~ loop,480
;~ (1<
;~ }
;固定的飛鳥
;~ u(){
;~ l=DJCDHIPLOIPETCYDZE^C[G^F[IZRQZG[AYFXJVBQGRALGN
;~ i:=&l-2,b=2*a:=7/c:=31
;~ while,x:=*(i+=2)&c,y=*(i+=2)&c
;~ dl(a*w,b*h,w*a:=x/c,h*b:=y/c)
;~ }
;十字架
;~ u(){
;~ l=DJCDHIPLOIPETCYDZE^C[G^F[IZRQZG[AYFXJVBQGRALGN
;~ i:=&l-2,b=2*a:=7/c:=31
;~ while,x:=*(i+=2)&c,y=*(i+=2)&c
;~ dl(a*w,b*h,w*a:=x/c,h*b:=y/c)
;~ }
;畫圈圈
;~ u(){
;~ loop 3 {
;~ i := A_Index
;~ loop 3 {
;~ a := 9*t
;~ d := 4*t
;~ x := (A_Index-0.5)/3 * w + s(a)*d
;~ y := (i-0.5)/3 * h + c(a)*d
;~ sp( x, y, h(t/9) )
;~ }
;~ }
;~ }
;噴繪效果
;~ u(i=.3){
;~ j:=i?t-.2:t
;~ y=-.5
;~ while 4>++y,x=-.5
;~ loop 4
;~ fc(w/2+ ++x*s(j)*80,h/2+y*c(j)*80,a(s(j))*3+c(j)*3+5,c:=h(x/y*.98+t/99,.7-i))
;~ i?u(0)
;~ }
;移動的花點
;~ u(i=1,y=-.5){
;~ (t<1)?f(9999)
;~ while 4>++y,x=-.5,j=t-.2*i
;~ loop 4
;~ fc(++x*s(j/x)*80+w/2,h/2+y*c(j/y)*80,s(j)+c(j)+7-i,h(x/y,.7-i))
;~ i?u(0)
;~ }
;下雪了
;~ u(i=0){
;~ static s:=[]
;~ if (f()t<1)
;~ while 999>++i,s[i]:=r
;~ Random r,0,% w
;~ while 500>++i,a=i*2
;~ sp(s[a+1]+s(t+i)*20,Mod(s[a]+t*99,h))
;~ }
;禮花
;~ u(r=1){
;~ r?u(0)
;~ p:=Mod(t+.1*r,q:=pi/2),i=0
;~ loop 98
;~ fc(w/2+s(a:=++i/24*q)*d:=(s(p)*15)**2,h/3+c(a)*d+(p*3)**3,p*7-r*3,h(t//q/3+i/2,452/d*r))
;~ }
;展開的花
;~ u(d=3,x=0){
;~ while 256>++x,y=0
;~ while 3>++y
;~ fc(s(t*4-x/8+pi*y)*d*x+w/2,c(t*4-x/8+pi*y)*d*x+w/2,11,h(t/4+y/2))
;~ }
;球
;~ u() {
;~ f()
;~ Loop 2 {
;~ i := A_Index
;~ p := (Mod(t/9+a(t(i)),pi/2))
;~ fc(s(t/99)*20+a(s(p))*w*(1+i/99),h-a(c(t+i/9))*h*c(p)**2-8,4,h(i/9))
;~ }
;~ }
;球的軌跡線
;~ u(){
;~ static x,y,a:=0.5,s
;~ s+=(d,x+=a)
;~ y+=s
;~ if(y+8>h)
;~ s*=-0.9,a*=0.97,y:=h-8
;~ if(x<0||x+8>w)
;~ a*=-1,x:=(x<0?0:h-8)
;~ fc(x,y,4,h(t))
;~ }
;紅心
;~ u(){
;~ i:=2*r:=A_Index/2
;~ fc(0,0,r,i)
;~ fc(w-i,0,r,i)
;~ fc(0,h-i,r,i)
;~ fc(w-i,h-i,r,i)
;~ if i<100
;~ Sleep 1
;~ if i>5000
;~ pause
;~ }
;上例子改進版
;~ u(){
;~ i:=2*r:=A_Index/2
;~ fc(0,0,r,h(t))
;~ fc(w-i,0,r,h(t))
;~ fc(0,h-i,r,h(t))
;~ fc(w-i,h-i,r,h(t))
;~ if i<100
;~ Sleep 1
;~ if i>5000
;~ pause
;~ }
;齒輪
;~ u(j=0,@=1){
;~ f()
;~ while 3>j,i=.5,@*=-1,x=j++*w/2
;~ while 97>i,?=?,?=?,?=x+s(p:=pi/48*i+t*@)*q:=(i&2?.26:.24)*w,?=h/2+c(p)*q
;~ i++>1?dl(?,?,?,?)
;~ }
;飛線
;~ u(i=0) {
;~ f()
;~ while 9>i
;~ dl(x:=i/9*w,y:=h/5+c(i+t+9)*h/3,x,b:=h/2+y)i++==0&&pi>y&&pi
;~ k?fc(6,pi+=GetKeyState("w")?-t/99:.1,9):pi:=t:=0
;~ }
;進出效果
;~ u(s=0){
;~ while 63>++s
;~ a:=w*(s-1)/128,fr(a+s(t*-2+s/7)*32,a+s-128+a/3,w-a*2,w-a*2+128,r(255,255,255,(s(t*-2+s/24)+1.1)/2.2))
;~ }
;星星
;~ u() {
;~ static x=0,y=9,a=1
;~ q:=x+s(a)*99,e=y+c(a)*99
;~ q>w||e>h||q<0||e<0?a-=1.5:x:=q+0*y:=e
;~ fc(q//8*8,e//8*8,2,r(w,,w,s(t*99)))
;~ }
;跳球球
;~ u(r=2,i=99) {
;~ while i-->0,c=t-r*d/2,p=Mod(c/6+a(t(i)),1.5)
;~ fc(a(s(p))*w//9*9-r,h-a(c(c+i/9))*h*c(p)**2//9*9-r-9,2+r,h(i/9,1-r*.4))
;~ r?u(0)
;~ }
;跳跳球加強版
;~ u(r=2,i=80) {
;~ while i-->0,c=t-r*d/2,p=Mod(c/6+a(t(i)),1.5)
;~ fc(a(s(p+i))*w//9*9-r,h-a(c(c+i/9))*h*c(p)**2//9*9-r-9,2+r,h(i/9,1-r*.4))
;~ r?u(0)
;~ }
;神奇的畫圈圈,鼠標控制
;~ u(){
;~ static x=0,y=0
;~ fc(x-r:=9+s(t-d)*7,y-r,r,h(t-d,.5))
;~ MouseGetPos a,b
;~ b-=c(t)*9,x=x*.999+a/999,y=y*.998+b/w
;~ fc(x-r:=9+s(t)*7,y-r,r,h(t))
;~ }
;~ ;強迫癥治療
;~ u(){
;~ z:=pi*(3-Sqrt(5)),i:=0,r:=Sqrt(w/2*w/2+h/2*h/2)+5,l:=4,k:=l-1,t:=(r*r)/(l*l)
;~ Loop,%t%
;~ i++,r:=l*sqrt(i),a:=i*z,x:=r*c(a),y:=r*s(a),fc(w/2+x,h/2+y,k,h(a))
;~ }
;亂彈線
;~ u() {
;~ static x=0,y=9,a=1
;~ q:=x+s(a),e=y+c(a)
;~ q>w||e>h||q<0||e<0?a-=Mod(t,2)+1:x:=q+0*y:=e
;~ fc(q//2*2,e//9*9,4,h(t,s(t)*.5+.5))
;~ }
;~ u(){
;~ z:=pi*(3-Sqrt(5)),i:=0,r:=Sqrt(w/2*w/2+h/2*h/2)+5,l:=4,k:=l-1,t:=(r*r)/(l*l)
;~ Loop,%t%
;~ i++,r:=l*sqrt(i),a:=i*z,x:=r*c(a),y:=r*s(a),fc(w/2+x,h/2+y,k,h(a))
;~ }
;~ u(i=0){
;~ Loop,12800
;~ fc(w/2+c(a:=++i*2.3999632297)*r:=4*i**.5,h/2+r*s(a),3,h(a))
;~ }
;潛水艇小游戲
;~ global Vy := 50
;~ global Vx := 50
;~ u() {
;~ f()
;~ Vy := GetKeyState("Up") ? Vy-1 : GetKeyState("Down") ? Vy+1 : Vy
;~ Vx := GetKeyState("Left") ? Vx-1 : GetKeyState("Right") ? Vx+1 : Vx
;~ fe(Vx,Vy,58,30,h(2/20))
;~ fc(Vx+25,Vy-10,4,h(6/3))
;~ loop, 4
;~ fc(Vx+(10*a_index),Vy+10,4,h(2/3))
;~ if GetKeyState("space")
;~ loop, 20
;~ fc(Vx+25,Vy+30+(a_index*40),4,h(a_index/6))
;~ }
;~ ;打飛機小游戲
;~ u() {
;~ static p=320,v=0,px=0,py=0,sx=0,sy=0,row,number,numbers,aliens,alien=[[[0,0,1,0,0,0,0,0,1,0,0],[0,0,0,1,0,0,0,1,0,0,0],[0,0,1,1,1,1,1,1,1,0,0],[0,1,1,0,1,1,1,0,1,1,0],[1,1,1,1,1,1,1,1,1,1,1],[1,0,1,1,1,1,1,1,1,0,1],[1,0,1,0,0,0,0,0,1,0,1],[0,0,0,1,1,0,1,1,0,0,0]],[[0,0,0,0,1,0,1,0,0,0,0],[1,0,0,1,0,0,0,1,0,0,1],[1,0,1,1,1,1,1,1,1,0,1],[1,1,1,0,1,1,1,0,1,1,1],[0,1,1,1,1,1,1,1,1,1,0],[0,0,1,1,1,1,1,1,1,0,0],[0,0,1,0,0,0,0,0,1,0,0],[0,0,0,1,1,0,1,1,0,0,0]]]
;~ static reset=0
;~ if (reset) {
;~ reset := 0
;~ d := 0
;~ }
;~ d?:d:=0
;~ --row?:row:=5
;~ if(!aliens) {
;~ f()
;~ t:=0
;~ number:=55
;~ numbers:=[11,11,11,11,11]
;~ y:=0,aliens=[]
;~ while y++<5,x=0,aliens.push(r:=[])
;~ while x++<11
;~ r.push(1)
;~ }
;~ d+=d*(55-number)/20
;~ t+=d
;~ offsetX := ((t*9)&63)*3 -30
;~ offsetY := (t*9)//64
;~ if (offsetY>19-numbers.length()) {
;~ MsgBox game over
;~ reset := 1 ;temp
;~ return aliens:=0
;~ }
;~ offsetY&1?offsetX:=129-offsetX
;~ offsetY*=30
;~ y:=(offsetY+row*30)//3|0
;~ fr(0,y*3-$:=(row>1?0:30),640,30+$,0)
;~ dl(px,py,px,py+20,0)
;~ px:=sx,py:=sy
;~ dl(sx,0,sx,offsetY,0)
;~ if(!sy) {
;~ GetKeyState("space")?sy:=580+0*sx:=p+10
;~ } else {
;~ a:=(sy-offsetY)//30|0
;~ b:=(sx-offsetX)//39|0
;~ if (aliens[a][b]) {
;~ aliens[a][b]:=0
;~ number--
;~ numbers[a]--
;~ loop 5
;~ numbers[numbers.Length()]?:numbers.pop()
;~ if(!numbers.Length()) {
;~ MsgBox You won!
;~ return aliens := 0
;~ }
;~ sy:=0
;~ } else {
;~ dl(sx,sy,sx,sy+20)
;~ sy:=Max(0,sy-d*400)
;~ }
;~ }
;~ c := 0
;~ r:=row
;~ while c++<11,y=0
;~ if(aliens[r][c])
;~ while y++<8,x=0
;~ while x++<11
;~ alien[(t&1)+1][y][x]?fr(offsetX+c*39+x*3, offsetY+r*30+y*3, 2, 2)
;~ l:=GetKeyState("left"),r=GetKeyState("right"),v=(v>0&&l)||(v<0&&r)||!(l+r)?0:v+9*d*(r-l)
;~ p:=Max(0,Min(620,p+v)),fr(0,596,640,30,0)fr(p,600,20,5)fc(p+7,596,3)
;~ }
類庫
;~ /*
;~ forum thread: https://autohotkey.com/boards/viewtopic.php?f=6&p=191294
;~ u() is called as fast as possible.
;~ --- global constants ---
;~ t - time elapsed since script start (seconds)
;~ d - time elapsed since last frame (seconds, delta time)
;~ w - canvas width
;~ h - canvas height
;~ pi - 3.1415...
;~ g - GDI object
;~ --- functions ---
;~ f(Color) - Fill (or clear) canvas (Color is defaulted to 0x000000)
;~ sp(x, y, Color) - SetPixel
;~ dl(x1, y1, x2, y2, Color) - DrawLine
;~ fc(x, y, r, Color) - FillCircle
;~ fr(x, y, w, h, Color) - FillRectangle
;~ fe(x, y, w, h, Color) - FillEllipse
;~ r(r, g, b, brightness) - transform rbg values to hex
;~ h(hue, brightness) - get hue color from fraction. example: h(0) is red, h(1/3) is green and h(2/3) is blue.
;~ if not specified, Color is always defaulted to 0xFFFFFF (white)
;~ if not specified, brightness is always defaulted to 1
;~ --- shorthands ---
;~ s() - sin()
;~ c() - cos()
;~ t() - tan()
;~ a() - abs()
;~ */
; this is the function you overwrite!
u(){
f(r(,20,40)),f=0
while 17>++f,p:=s(t*3-f/9),a=0
loop 16
fc(w/2+s(r:=p+a++*pi/8)*f*h/35,h/2+c(r)*f*h/35,4,h(t/2+(16-f)/16))
}
/*
=== BOILERPLATE BELOW ===
*/
#SingleInstance force
#NoEnv
#Persistent
SetWinDelay -1
SetBatchLines -1
global g, t, d
global pi := 3.14159265359
global w := 640
global h := 640
Gui, -MinimizeBox +Resize
Gui, Color, Black, Black
Gui, Margin, 0, 0
Gui, Add, Progress, % "hwndctrl BackgroundBlack x0 y0 w" w " h" h
Gui, Show
g := new GDI(ctrl, w, h)
SetTimer, FPS, 1000
DllCall("QueryPerformanceFrequency", "Int64P", freq)
Loop {
t += d := (end - start) / freq
DllCall("QueryPerformanceCounter", "Int64P", start)
u()
g.bitblt()
DllCall("QueryPerformanceCounter", "Int64P", end)
frames++
}
return
f(Color := 0x000000) {
g.FillRectangle(0, 0, g.CliWidth, g.CliHeight, Color)
}
sp(x, y, Color := 0xFFFFFF) {
g.SetPixel(x, y, Color)
}
dl(x1, y1, x2, y2, Color := 0xFFFFFF) {
g.DrawLine(x1, y1, x2, y2, Color)
}
fc(x, y, r, Color := 0xFFFFFF) {
g.FillEllipse(x, y, r*2, r*2, Color)
}
fr(x, y, w, h, Color := 0xFFFFFF) {
g.FillRectangle(x, y, w, h, Color)
}
fe(x, y, w, h, Color := 0xFFFFFF) {
g.FillEllipse(x, y, w, h, Color)
}
s(x) {
return sin(x)
}
c(x) {
return cos(x)
}
t(x) {
return tan(x)
}
a(x) {
return abs(x)
}
r(r := 0, g := 0, b := 0, brightness := 1) {
return (b * brightness << 16) + (g * brightness << 8) + (r * brightness)
}
h(hue, brightness := 1) {
if (hue<0,hue:=abs(mod(hue, 1)))
hue:=1-hue
Loop 3
col+=max(min(-8*abs(mod(hue+A_Index/3-0.5,1)-0.5)+2.5,1),0)*255*brightness<<16-(A_Index-1)*8
return col
}
min(Param*) {
Out := Param.1
for Index, Value in param
if (Value < Out)
Out := Value
return Out
}
max(Param*) {
Out := Param.1
for Index, Value in Param {
if (Value > Out)
Out := Value
} return Out
}
FPS:
Gui +LastFound
WinSetTitle,,,% "FPS: " frames
frames := 0
return
GuiClose:
GuiEscape:
ExitApp
return
GuiSize(hwnd, type, gw, gh) {
global time
w := gw, h:=gh
GuiControl, Move, % g.hwnd, w%w% h%h%
g.Resize(w, h)
Sleep, -1
u()
g.bitblt()
}
class GDI
{
__New(hWnd, CliWidth=0, CliHeight=0)
{
if !(CliWidth && CliHeight)
{
VarSetCapacity(Rect, 16, 0)
DllCall("GetClientRect", "Ptr", hWnd, "Ptr", &Rect)
CliWidth := NumGet(Rect, 8, "Int")
CliHeight := NumGet(Rect, 12, "Int")
}
this.CliWidth := CliWidth
this.CliHeight := CliHeight
this.hWnd := hWnd
this.hDC := DllCall("GetDC", "UPtr", hWnd, "UPtr")
this.hMemDC := DllCall("CreateCompatibleDC", "UPtr", this.hDC, "UPtr")
this.hBitmap := DllCall("CreateCompatibleBitmap", "UPtr", this.hDC, "Int", CliWidth, "Int", CliHeight, "UPtr")
this.hOriginalBitmap := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", this.hBitmap)
}
__Delete()
{
DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", this.hOriginalBitmap)
DllCall("DeleteObject", "UPtr", this.hBitmap)
DllCall("DeleteObject", "UPtr", this.hMemDC)
DllCall("ReleaseDC", "UPtr", this.hWnd, "UPtr", this.hDC)
}
Resize(w, h)
{
this.CliWidth := w
this.CliHeight := h
this.hBitmap := DllCall("CreateCompatibleBitmap", "UPtr", this.hDC, "Int", w, "Int", h, "UPtr")
hPrevBitmap := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", this.hBitmap)
DllCall("DeleteObject", "UPtr", hPrevBitmap)
}
BitBlt(x=0, y=0, w=0, h=0)
{
w := w ? w : this.CliWidth
h := h ? h : this.CliHeight
DllCall("BitBlt", "UPtr", this.hDC, "Int", x, "Int", y
, "Int", w, "Int", h, "UPtr", this.hMemDC, "Int", 0, "Int", 0, "UInt", 0xCC0020) ;SRCCOPY
}
; DrawLine
DrawLine(x, y, x2, y2, Color)
{
Pen := new GDI.Pen(Color)
DllCall("MoveToEx", "UPtr", this.hMemDC, "Int", this.TranslateX(x), "Int", this.TranslateY(y), "UPtr", 0)
hOriginalPen := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", Pen.Handle, "UPtr")
DllCall("LineTo", "UPtr", this.hMemDC, "Int", this.TranslateX(x2), "Int", this.TranslateY(y2))
DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", hOriginalPen, "UPtr")
}
; SetPixel
SetPixel(x, y, Color)
{
x := this.TranslateX(x)
y := this.TranslateY(y, this.Invert) ; Move up 1 px if inverted (drawing "up" instead of down)
DllCall("SetPixelV", "UPtr", this.hMemDC, "Int", x, "Int", y, "UInt", Color)
}
FillRectangle(x, y, w, h, Color, BorderColor=-1)
{
if (w == 1 && h == 1)
return this.SetPixel(x, y, Color)
Pen := new this.Pen(BorderColor < 0 ? Color : BorderColor)
Brush := new this.Brush(Color)
; Replace the original pen and brush with our own
hOriginalPen := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", Pen.Handle, "UPtr")
hOriginalBrush := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", Brush.Handle, "UPtr")
x1 := this.TranslateX(x)
x2 := this.TranslateX(x+w)
y1 := this.TranslateY(y)
y2 := this.TranslateY(y+h)
DllCall("Rectangle", "UPtr", this.hMemDC
, "Int", x1, "Int", y1
, "Int", x2, "Int", y2)
; Reselect the original pen and brush
DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", hOriginalPen, "UPtr")
DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", hOriginalBrush, "UPtr")
}
FillEllipse(x, y, w, h, Color, BorderColor=-1)
{
Pen := new this.Pen(BorderColor < 0 ? Color : BorderColor)
Brush := new this.Brush(Color)
; Replace the original pen and brush with our own
hOriginalPen := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", Pen.Handle, "UPtr")
hOriginalBrush := DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", Brush.Handle, "UPtr")
x1 := this.TranslateX(x)
x2 := this.TranslateX(x+w)
y1 := this.TranslateY(y)
y2 := this.TranslateY(y+h)
DllCall("Ellipse", "UPtr", this.hMemDC
, "Int", x1, "Int", y1
, "Int", x2, "Int", y2)
; Reselect the original pen and brush
DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", hOriginalPen, "UPtr")
DllCall("SelectObject", "UPtr", this.hMemDC, "UPtr", hOriginalBrush, "UPtr")
}
TranslateX(X)
{
return Floor(X)
}
TranslateY(Y, Offset=0)
{
if this.Invert
return this.CliHeight - Floor(Y) - Offset
return Floor(Y)
}
class Pen
{
__New(Color, Width=1, Style=0)
{
this.Handle := DllCall("CreatePen", "Int", Style, "Int", Width, "UInt", Color, "UPtr")
}
__Delete()
{
DllCall("DeleteObject", "UPtr", this.Handle)
}
}
class Brush
{
__New(Color)
{
this.Handle := DllCall("CreateSolidBrush", "UInt", Color, "UPtr")
}
__Delete()
{
DllCall("DeleteObject", "UPtr", this.Handle)
}
}
}
[/erphpdown]
總結
以上是生活随笔為你收集整理的ahk编程_AHK编程可视化的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 购房组合贷款条件
- 下一篇: vue 点击事件传递多个参数_vue传事