Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

写vOn:click={this.method}直接提示语法错误 #77

Closed
zengyuanqiu opened this issue Aug 21, 2019 · 21 comments
Closed

写vOn:click={this.method}直接提示语法错误 #77

zengyuanqiu opened this issue Aug 21, 2019 · 21 comments

Comments

@zengyuanqiu
Copy link

image

@haoqunjiang
Copy link
Member

See #52 microsoft/TypeScript#7411

@TimYi
Copy link

TimYi commented Sep 26, 2019

我也遇到同样的问题,项目中需要在typescript中使用jsx,但是目前这个状态绑定不了事件,进行不下去了。
有没有其它办法支持?比如换回旧版本的jsx语法,项目是使用最新vue-cli创建的。

@TimYi
Copy link

TimYi commented Sep 26, 2019

只能用spread语法来写了,满脸黑线。

@chenjiahan
Copy link
Contributor

Try this:

<div onClick={() => {}} />

@Ttou
Copy link

Ttou commented Oct 15, 2019

@chenjiahan 这样写的话,事件修饰符怎么加?

@chenjiahan
Copy link
Contributor

修饰符没法加哈,不过 prevent/stop 这种都是一行代码能搞定的

@TimYi
Copy link

TimYi commented Oct 16, 2019

@chenjiahan <div onClick={() => {}} />这是旧版本的语法,最新的vue-cli里好像不好使了,无效。新语法在typescript里又用不了。

@melunar
Copy link

melunar commented Nov 5, 2019

@chenjiahan <div onClick={() => {}} />这是旧版本的语法,最新的vue-cli里好像不好使了,无效。新语法在typescript里又用不了。

既然是jsx语法 就应该在语法上随从人家,vOn:click的写法太丑了,还有class也不能写成className

@xmsz
Copy link

xmsz commented Nov 11, 2019

@chenjiahan <div onClick={() => {}} />这是旧版本的语法,最新的vue-cli里好像不好使了,无效。新语法在typescript里又用不了。

既然是jsx语法 就应该在语法上随从人家,vOn:click的写法太丑了,还有class也不能写成className

+1

@TimYi
Copy link

TimYi commented Nov 14, 2019

@chenjiahan <div onClick={() => {}} />这是旧版本的语法,最新的vue-cli里好像不好使了,无效。新语法在typescript里又用不了。

既然是jsx语法 就应该在语法上随从人家,vOn:click的写法太丑了,还有class也不能写成className

关键是两种都用不了,得用最麻烦的spread语法(手动捂脸)

@TimYi
Copy link

TimYi commented Dec 3, 2019

@xinayu 在typescript环境里无法使用vOn:click

@xuanhen2013
Copy link

@TimYi 使用 on={{click: func}}

@harvey-woo
Copy link

harvey-woo commented Apr 14, 2020

@chenjiahan 这样写的话,事件修饰符怎么加?

// jsx-utils.ts
import { L } from 'ts-toolbelt';

export const keys = <{ <T>(o: NonNullable<T>): Array<keyof T> }>Object.keys;

type Decorators = { stop: boolean, prevent: boolean, self: boolean };
const defaultDecorators: Decorators = {
  stop: false,
  prevent: false,
  self: false,
};
type Handler = (this: any, event: Event, ...args: any[]) => any;
type HandlerWrapper<F extends Handler> = {
  (handler?: F): (this: ThisType<F>, event: Parameters<F>[0], ...args: L.Tail<Parameters<F>>)
   => ReturnType<F>
} & { [k in keyof Decorators]: HandlerWrapper<F> } & {
  handler: (event: Parameters<F>[0]) => void
};

const generateWrapper = <F extends Handler>(params: Partial<Decorators>) => {
  const { stop, prevent, self } = params;
  const wrapper = ((fn?: F) => {
    return function handler(event, ...args) {
      if (prevent) {
        event.preventDefault();
      }
      if (stop) {
        event.stopPropagation();
      }
      if (fn && (!self || event.target === event.currentTarget)) {
        return fn.call(this, event, ...args);
      }
      return undefined;
    };
  }) as HandlerWrapper<F>;
  keys(defaultDecorators).forEach((k) => {
    if (!(k in params)) {
      wrapper[k] = generateWrapper({ ...params, [k]: true });
    }
  });
  wrapper.handler = (event) => {
    if (prevent) {
      event.preventDefault();
    }
    if (stop) {
      event.stopPropagation();
    }
  };
  return wrapper;
};

export const stop = generateWrapper({ stop: true });
export const prevent = generateWrapper({ prevent: true });
export const self = generateWrapper({ self: true });
import { stop, prevent, self } from './jsx-utils'

export default {
    // 使用 prevent,self,stop,三个方法
    // 或者直接返回 prevent.handler, stop.handler
    // 也可以 prevent.stop 这样链式使用
    render() {
        return <div 
            onClick={prevent.handler} 
            onMousedown={prevent.stop.self(() => { console.log('HelloWorld')})} />
    }
}

@DUAN930909
Copy link

on-click={ this.fun }

@mikepxq
Copy link

mikepxq commented May 14, 2021

尽然 tsx 维护起来这么难
vue官方 就直接说不用 tsx的呢
免得,三方库也是遇到各种问题
vue底层也要做兼容的代码

@haoqunjiang
Copy link
Member

TS 4.2 已经支持此语法。请自行升级项目中的 TypeScript 版本。

@galenjiang
Copy link

galenjiang commented Oct 21, 2021

还有一个edge case没有考虑到,例如 emit('update:someValue'),
<SomeComponent vOn:update:someValue={callback} />
这时候编译不过。

@chenjiahan
Copy link
Contributor

@galenjiang 最新版 TS 已经支持冒号了

@galenjiang
Copy link

galenjiang commented Oct 22, 2021

@galenjiang 最新版 TS 已经支持冒号了

是两个冒号不是一个冒号
而且ts修复的是namespace, 但是vue奇怪的事件系统只是看起来像,但事实并不是。

@chenjiahan
Copy link
Contributor

两个冒号没有必要把? 直接 onUpdate:xxx 就可以

@galenjiang
Copy link

两个冒号没有必要把? 直接 onUpdate:xxx 就可以

没效果,不触发事件。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests