SOFTELメモ Developer's blog

会社概要 ブログ 調査依頼 社員募集 ...

【vue.js】自動リンク表示するコンポーネントを作る

問題

例えば以下のようなURLを含む文字列を、

ソフテルをGoogleで検索
https://www.google.com/search?q=%E3%82%BD%E3%83%95%E3%83%86%E3%83%AB
ソフテルをYahoo!で検索
https://search.yahoo.co.jp/search?p=%E3%82%BD%E3%83%95%E3%83%86%E3%83%AB

URLの部分をaタグでリンクにして表示してほしいです。

答え

vueのコンポーネントを作って対応する例。

Vue.component('autolink', {
	props: ['text'],
	render: function (createElement) {
		var a = this.text.split(/(https?:\/\/[\w!?\/\+\-_~=;\.,*&@#$%\(\)\'\[\]]+)/i)
		var vnodes = a.map(function(x, i) {
			if (i % 2) {
				return createElement('a', {attrs:{href:x}}, x)
			} else {
				return this._v(x)
				//return createElement('span', {}, x)
			}
		}, this);
		return createElement(
			'span',
			vnodes
		)
	}
});

自動リンク表示したい文字列が何らかの変数に入っているとして、

以下のように使うと、

<autolink :text="変数名"></autolink>

以下のように表示される。

メモ

splitで1個だけキャプチャする正規表現を使うと、[分割された部分, キャプチャされた部分, 分割された部分, キャプチャされた部分 …… 分割された部分, キャプチャされた部分, 分割された部分] の形の配列がもらえるので、偶数個目はテキスト、奇数個目はリンクにしている。

vueのrender関数の中で使っている this._v(文字列) は、タグのないただのテキストノードを生成してくれるのだが、謎の関数を使うのが気持ち悪かったら、createElement関数でspan要素を作るとよい。

span要素だらけになるのがイヤだったら _v が使える。

_v は、テキストノードを作る関数として内部に存在している。

https://github.com/vuejs/vue/blob/994aee4f869d68a00c3b9d87daa9c8d84623ac42/dist/vue.runtime.common.js#L2249

関連するメモ

コメント