Skip to content

14 实现on事件指令 #16

@xwjie

Description

@xwjie

就是 v-on, 缩写为 @

代理组件的methods方法

function initMethods(vm: any, methods: Object) {
  for (const key in methods) {
    vm[key] = methods[key] == null ? noop : bind(methods[key], vm)
  }
}

/**
 * Simple bind, faster than native
 */
export function bind (fn: Function, ctx: Object): Function {
  function boundFn (a) {
    const l: number = arguments.length
    return l
      ? l > 1
        ? fn.apply(ctx, arguments)
        : fn.call(ctx, a)
      : fn.call(ctx)
  }
  // record original fn length
  boundFn._length = fn.length
  return boundFn
}

修改生成render字符串方法

/**
 * 解析属性
 * @param {*} node
 */
function genAttrStr(node: any) {
  let attrs = node.attrsMap

  if (!attrs) {
    return ""
  }

  let propsStr: string = ''
  let styleStr: string = ''
  let onStr: string = ''

  // why not use for..in, see eslint `no-restricted-syntax`
  Object.keys(attrs).forEach(attrname => {
    let str = ''
    let isEvent = false
    const val = attrs[attrname].trim()

    // 如果是数据绑定,则后面的是表达式
    if (attrname.charAt(0) == ':') {
      str = JSON.stringify(attrname.substr(1)) + ':' + val + ','
      attrname = attrname.substr(1).toLocaleLowerCase()
    }
    else if (attrname.charAt(0) == '@') {
      str = JSON.stringify(attrname.substr(1)) + ':' + getFunctionStr(val) + ','
      isEvent = true
      attrname = attrname.substr(1).toLocaleLowerCase()
    }
    else {
      str = JSON.stringify(attrname) + ':' + JSON.stringify(val) + ','
    }

    // class已经处理了。
    if (attrname !== 'class') {
      if (isEvent) {
        onStr += str
      } else if (isStyle(attrname)) {
        styleStr += str
      }
      else {
        propsStr += str
      }
    }
  })

  let str = '';

  if (propsStr != '') {
    str += `props:{${propsStr}},`
  }

  if (styleStr != '') {
    str += `style:{${styleStr}},`
  }

  if (onStr != '') {
    str += `on:{${onStr}},`
  }

  return str;
}


function isStyle(name: string) {
  return name === 'style'
}

function isFuncNameStr(name: string): boolean {
  return /[-A-Za-z0-9_]+$/.test(name)
}

function getFunctionStr(funcStr: string): string {
  // 如果只是函数名,加一个()调用
  if (isFuncNameStr(funcStr)) {
    funcStr += '(event)'
  }

  return `function($event){${funcStr}} `
}

测试代码

//D:\OutPut\VUE\VueStudyNote\Xiao\example\14 directive-on.html

<!DOCTYPE html>
<html>
<head>
	<title>Xiao框架之helloworld</title>
	<script src="../dist/xiao.js"></script>
</head>
<body>
<h1>@(on)指令测试</h1>
<div id="demo1">
	<button @click="click1">{{btnText}}</button><br/>
	<button @click="click2(count>1)">按钮2</button><br/>
	<button @click="btnText='改变值'">按钮3</button>
</div>
<script>
var app = new Xiao({
	data:{
		btnText: "按钮1",
		count:2
	},
	methods:{
		click1 : function(e){
			console.log('按钮1', e);
		},
		click2 : function(flag){
			console.log('按钮2:' + this.count, flag);
		},
	}
});

app.$mount("#demo1");

setTimeout(function(){
	app.count = 1;
}, 3000);

</script>

</body>
</html>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions