Riot.jsでコンポーネント間のデータのやり取りやDOM要素へのアクセス
Riot.jsで コンポーネント間のやり取り をする際によく使う方法を紹介します。他にも色々あるかもしれませんが、以下で紹介する方法で大体のことはできると思います。
親から子を参照
this.tags
<child>
<script>
this.item = '子要素のプロパティ';
</script>
</child>
<parent>
<child></child>
<script>
// マウントが終わったら子要素にアクセスできる
this.on('mount', function() {
// 子要素
var child = this.tags.child;
// 子要素のプロパティ
var item = child.item;
});
</script>
</parent>
this.tags.タグ名
でネストしている子要素にアクセスできます。
this.refs
<child>
<script>
this.item = '子要素のプロパティ';
</script>
</child>
<parent>
<child ref="child"></child>
<script>
// マウントが終わったら子要素にアクセスできる
this.on('mount', function() {
// 子要素
var child = this.refs.child;
// 子要素のプロパティ
var item = child.item;
});
</script>
</parent>
また、 ref
属性を設定すると、 this.refs.ref属性値
でアクセスできます。
子から親を参照
<parent>
<child></child>
<script>
this.item = '親要素のプロパティ';
</script>
</parent>
<child>
<script>
// 親要素
var parent = this.parent;
// 親要素のプロパティ
var item = parent.item;
</script>
</child>
this.parent
で親要素にアクセスできます。
離れたコンポーネント間
riot.observable()
<one></one>
<other></other>
<script>
riot.mount('*', {
obs: riot.observable()
});
</script>
<one>
<button onclick="{click}">ボタン</button>
<script>
click() {
opts.obs.trigger('button:clicked', '任意の値');
}
</script>
</one>
<other>
<script>
opts.obs.on('button:clicked', function(data) {
console.log('one要素のボタンがクリックされました');
console.log(data); // 任意の値
});
</script>
</other>
riot.observable()
を使うとイベントを利用して one
要素から other
要素に値を渡すことができます。
親要素経由
<parent>
<one></one>
<other></other>
</parent>
<one>
<button onclick="{getTag}">ボタン</button>
<script>
getTag() {
// other要素
var other = this.parent.tags.other;
// other要素のプロパティ
var item = other.item;
}
</script>
</one>
<other>
<script>
this.item = 'other要素のプロパティ';
</script>
</other>
ネストされていれば .parent
や .tags
で辿れるのでそれを利用しています。
グローバルで管理
<one></one>
<other></other>
<script>
var store = {
item: ''
};
riot.mount('*');
</script>
<one>
<button onclick="{getTag}">ボタン</button>
<script>
getTag() {
// other要素でセットしたプロパティ
var item = store.item;
}
</script>
</one>
<other>
<script>
store.item = 'other要素のプロパティ';
</script>
</other>
グローバルにオブジェクトを定義しておいて、そこに状態などを保存しておく方法です。
riot.util.vdom
<one></one>
<other></other>
<script>
riot.mount('*');
function getTagByNode(node, context) {
var tag = null;
if (context == null) context = riot.util.vdom;
// 現在探索中の階層が配列のとき(riot.util.vdomまたはtagsが配列のとき)
if (Array.isArray(context)) {
context.some(function(tags) {
// 配列それぞれについて探索
tag = getTagByNode(node, tags);
// tagが初期値でない(見つかった)ときはループを抜けて値を返す
if (tag !== null) return tag;
});
} else { // 現在探索中の階層がオブジェクトのとき
// 見つかったら返す
if (context.root === node) return context;
// オブジェクトの数だけ探索
for (var key in context.tags) {
if (context.tags.hasOwnProperty(key)) {
tag = getTagByNode(node, context.tags[key]);
// tagが初期値でない(見つかった)ときはループを抜けて値を返す
if (tag !== null) return tag;
}
}
}
return tag;
}
</script>
<one>
<button onclick="{getTag}">ボタン</button>
<script>
getTag() {
// other要素
var other = getTagByNode(document.querySelector('other'));
// other要素のプロパティ
var item = other.item;
}
</script>
</one>
<other>
<script>
this.item = 'other要素のプロパティ';
</script>
</other>
riot.util.vdom
にはマウントされた全てのカスタムタグが格納されているので、そこから取得するという方法もあります。
カスタムタグでないDOM要素にアクセス
.querySelector()
<element>
<div class="title"></div>
<script>
this.on('mount', function() {
var node = this.root.querySelector('.title');
});
</script>
</element>
マウント後であれば普通に .querySelector()
等の関数で取得することができます。
this.refs
<element>
<div ref="title"></div>
<script>
this.on('mount', function() {
var node = this.refs.title;
});
</script>
</element>
先ほども紹介しましたが、カスタムタグでなくても this.refs
でアクセスできます。
CSS本執筆しました!!!
CSS本出します!1/29発売予定
— たかもそ@CSS本1/29発売!! (@takamosoo) 2018年12月31日
自分がCSS学びたての頃にもっとはやく知りたかったテクニックを載せています。CSSの基礎知識について解説していないので、中級者〜向けとなります。CSS入門書を読んではみたものの、思い通りに作れない人にオススメです。
よろしくお願いします。https://t.co/fkz1dM03Pj pic.twitter.com/suYyaPqwIs