这是一篇新手篇的typescript插件编写方式!!!!
源码完整地址:https://gitee.com/dissucc/typescriptLearn
1.环境安装
node下载
cnpm安装
在安装完node后,npm默认就安装了,因为某种原因,npm下载组件包的速度太慢了,所以需要安装cnpm
安装命令
npm install -g cnpm --registry=https://registry.npm.taobao.org
推荐使用Vs Code开发
2.开发前的准备工作
a.新建一个文件夹,然后在vs code 中打开
ctrl+~唤起终端
输入
npm install -g typescript
然后建一个基本的环境
好了,大概就是这个结构,我们今天要实现的就是一个带额外提示的输入框
效果图如下
3.咱们开始吧!
首先,我们要写的是一个基于AMD规范的插件,所以页面代码先这个样子
<!DOCTYPE html> <html> <head> <title>TypeScript Greeter</title> <script src="https://cdn.bootcss.com/require.js/2.3.5/require.min.js"></script> </head> <body> <div class="box"></div> </body> <script> </script> </html>
先将requirejs引用到页面
添加2个帮助类到项目里
element.ts
import _ from './unit'; export default class mElement { tagName: string; props: any; children: any; key: any; count: number; constructor(tagName: string, props: any, children: any[]) { if (!(this instanceof mElement)) { if (!_.isArray(children) && children != null) { children = _.slice(arguments, 2).filter(_.truthy) } return new mElement(tagName, props, children) } if (_.isArray(props)) { children = props props = {} } this.tagName = tagName this.props = props || {} this.children = children || [] this.key = props ? props.key : void 666 var count = 0 _.each(this.children, function (child, i) { if (child instanceof mElement) { count += child.count } else { children[i] = '' + child } count++ }) this.count = count } render = function () { var el = document.createElement(this.tagName) var props = this.props for (var propName in props) { var propValue = props[propName] _.setAttr(el, propName, propValue) } _.each(this.children, function (child) { var childEl = (child instanceof mElement) ? child.render() : document.createTextNode(child) el.appendChild(childEl) }) return el } }
unit.ts
let _ = { type: function (obj) { return Object.prototype.toString.call(obj).replace(/\[object\s|\]/g, '') }, isArray: function (list) { return this.type(list) === 'Array' }, slice: function (arrayLike, index) { return Array.prototype.slice.call(arrayLike, index) }, truthy: function (value) { return !!value }, isString: function (list) { return this.type(list) === 'String' }, each: function (array, fn) { for (var i = 0, len = array.length; i < len; i++) { fn(array[i], i) } }, toArray: function (listLike: any[]) { if (!listLike) { return [] } let list: any = [] for (var i = 0, len = listLike.length; i < len; i++) { list.push(listLike[i]) } return list }, setAttr: function (node, key, value) { switch (key) { case 'style': node.style.cssText = value break case 'value': var tagName = node.tagName || '' tagName = tagName.toLowerCase() if ( tagName === 'input' || tagName === 'textarea' ) { node.value = value } else { // if it is not a input or textarea, use `setAttribute` to set node.setAttribute(key, value) } break default: node.setAttribute(key, value) break } } } export default _;
看一下最终的项目结构
准备工作完成,开始编写
input.ts
///input export class Input <T extends InputOption>{ private thatOption: T; //构造函数 constructor(inputOption: T) { this.thatOption = inputOption; } //渲染方法 render(ele) { console.log(this.thatOption) } } ///配置项的接口 export interface InputOption { label?: string, placeholder?: string, extra?: string, value?: string }
先将配置项输出出来看看,有没有问题!
XxxUI.ts
import { Input } from './base/input' let XxxUI = { Input: (option) => { return new Input(option); } } export default XxxUI;
index.html ->script
<script> require(['XXXUI/XxxUI'], function (XxxUI) { var core = XxxUI.default; var input = core.Input({ label: '测试', placeholder: '测试', extra: '测试', value: '1' }); var box = document.querySelector(".box"); input.render(box); }) </script>
编译一下代码
tsc src/XXXUI/XxxUI.ts -m amd
然后直接打开页面看看是否有输出
成功啦!开始写东西,哈哈哈哈
插件最后生成的结构差不多是这个样子的
<div class='xui-input'> <label>测试</label> <input type="text"></input> <span>附加信息</span> </div>
先建一个文件,将创建DOM的操作封装一层,要不然每次都要实例化,很麻烦
core.ts
import mElement from './element'; let ele: object; export function create(tagName: string, props: any, children: any[]) { ele = new mElement(tagName, props, children); return ele; }
然后修改我们的
input.ts
import { create } from './core'; ///input export class Input<T extends InputOption>{ private thatOption: T; //构造函数 constructor(inputOption: T) { this.thatOption = inputOption; } //渲染方法 render(ele) { console.log(this.thatOption) const { label, placeholder, extra, value, click } = this.thatOption; const dom: any = create('div', { class: 'xui-input' }, [ create('label', { type: 'text', onclick: click }, [label]), create('input', { placeholder, value }, undefined), create('span', undefined, [extra]) ]); ele.appendChild(dom.render()); } } ///配置项的接口 export interface InputOption { label?: string, placeholder?: string, extra?: string, value?: string, click: string }
这里演示了一下如何简单的绑定事件!当然,你也可以换自己的写法
index.html
<!DOCTYPE html> <html> <head> <title>TypeScript Greeter</title> <script src="https://cdn.bootcss.com/require.js/2.3.5/require.min.js"></script> </head> <body> <div class="box"> </div> </body> <script> function onclicktest() { console.log(1); } require(['XXXUI/XxxUI'], function (XxxUI) { var core = XxxUI.default; var input = core.Input({ label: '测试', placeholder: '测试', extra: '测试', value: '1', click: 'onclicktest()' }); var box = document.querySelector(".box"); input.render(box); }) </script> </html>
看看页面上的显示
嗯,搞定了,这篇文章就这样啦!
样式什么的,我就不写了,偷个懒偷个懒
是不是很简单?快去写个插件,封装好,给自己使用吧!!!!!!!!!!!!
源码地址:https://gitee.com/dissucc/typescriptLearn
请发表评论