本文作者:IMWeb 杨文坚 原文出处:IMWeb社区 未经同意,禁止转载 紧接上文:https://cloud.tencent.com/developer/article/1015967
当组件可以嵌套,组件件可以拆成较小的颗粒,使得复用性大大提升。
下面我们是一个codeclick
组件,其用途是高亮展示代码片段,点击代码弹出dialog,也就是说我们准备嵌套上面做出来的third-code
和dialog
组件:
/** 可以给组件定义一些特殊样式,但为了简单我们什么也不做 **/
<div>
<third-code q-ref="code">
<content></content>
</third-code>
<dialog q-ref="dialog">
<header>欢迎使用Ques</header>
<article>你点击了代码</article>
</dialog>
</div>
var $ = require('jquery');
module.exports = {
data: {},
ready: function () {
var code = this.$.code,
dialog = this.$.dialog;
// 点击代码,弹出dialog
$(code.el).on('click', function () {
dialog.show();
});
}
};
<codeclick>
<ui-button class="ui-default">DEFAULT</ui-button>
<ui-button class="ui-success">SUCCESS</ui-button>
<ui-button class="ui-info">INFO</ui-button>
<ui-button class="ui-warning">WARNING</ui-button>
<ui-button class="ui-danger">DANGER</ui-button>
</codeclick>
<content>
标签另一个神奇的用法是可传递,我们从third-code
传递到codeclick
,再传递到最外部。使得我们可以在最外部改third-code
内部的节点。q-ref
本来是Q.js
用于组件嵌套从母Component(为了和扩展中的父Component其分开来,这里称之为母Component)拿到子Component的引用,同样可以拿到第三方Component的引用。组件可扩展,则差别不大的组件可以继承同一个父组件。
下面dialog
组件扩展的例子,效果是弹出一个dialog,要求输入内容:
/** 同样为了简单我们什么也不做 **/
<dialog extend>
<header>
<h2>欢迎使用Ques</h2>
</header>
<article>
<p>请输入要设置的值</p>
<ui-input value="" q-model="curVal" q-on="keyup: submit | key enter" q-focus="focus"></ui-input>
</article>
</dialog>
var filters = require('filters');
module.exports = {
methods: {
submit: function () {
if (!this.curVal) {
this.$set('focus', true);
} else {
this.$emit('submit', this.curVal);
this.$set('curVal', '');
this.hide();
}
},
show: function () {
// call super.show
this.constructor.super.options.methods.show.call(this);
this.$set('focus', true);
}
},
directives: {
focus: function (val) {
val && this.el.focus();
}
},
filters: {
key: filters.key
}
};
inputval
:<inputval id="my-dialog"></inputval>
var Q = require('Q');
Q.get('#my-dialog').show();
extend
属性,用于表示该组件继承哪个组件。dialog
的submit
和show
方法,并且可以调用其父Componnet的方法,如:this.constructor.super.options.methods.show.call(this);
我们可以嵌套使用扩展后的组件。
下面是一个复杂的例子,一个按钮点击后弹出inputval
,输入后alert出输入的内容。
.$__anchor {
padding: 13px 35px 17px;
box-shadow: inset 0 -4px 0 #2a6496;
border: 0;
color: #fff;
transition: all .2s ease-in-out;
background-color: #337ab7;
border-color: #2e6da4;
display: block;
margin-bottom: 0;
font-size: 14px;
font-weight: 400;
line-height: 1.42857143;
text-align: center;
white-space: nowrap;
vertical-align: middle;
touch-action: manipulation;
cursor: pointer;
user-select: none;
border-radius: 4px;
text-decoration: none;
margin: 0 auto;
}
.$__anchor:hover,
.$__anchor:active
.$__anchor:focus {
background-color: #286090;
border-color: #204d74;
}
<div>
<a href="void(0);" class="$__anchor" q-on="click: setMessage">
<content></content>
</a>
<inputval q-ref="input"></inputval>
</div>
module.exports = {
data: {},
methods: {
setMessage: function (e) {
var self = this;
this.$.input.$once('submit', function (value) {
value && alert('输入了:' + value);
});
this.$.input.show();
}
}
};
<clkme>请点击我</clkme>
DIY组件允许页面通过Markup的方法引用NodeJS组件,这样我们可以使用该NodeJS组件分析我们的代码来做一些神奇的事情。
例如我们提供的diy-preload
组件提供的CGI预加载方案,整个过程没有改变开发人员的编码体验,只是简简单单标记一下哪个CGI需要预加载,则系统会自动预加载CGI。
diy-preload
组件<diy-preload></diy-preload>
db.*.js
,的对应CGI设置成preload = true: var DB = require('db');
DB.extend({
ke: DB.httpMethod({
url: 'http://ke.qq.com/cgi-bin/index_json',
type: 'JSONP',
preload: true
})
})
module.exports = DB;
diy-preload
组件会找到db.*.js
,然后分析出什么CGI需要预加载,在<diy-preload>
标签对应的位置插入预加载脚本。整个过程开发人员感知不到,体验上还是调取一个CGI,但是实际上在页面文档打开后CGI请求立刻发出,而不是等待Javascript加载完后才发出。