質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

1回答

4871閲覧

あいうえお順に並んでほしい【javascript?】

terame120

総合スコア14

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2018/11/29 13:55

編集2018/11/30 01:43

ttps://cr-vue.mio3io.com/tutorials/todo.html
こちらを参考に、自分用にアプリを作りたいと思っています。
初心者で、全部を理解できていない状況です。

作っているのは、ことばの管理用のアプリです。
URLの先を参考に、
・ことば、かなを登録する
・「メモ(未記入)」、「記入済」という2つの振り分けをできるようにする
・振り分け先が別のページになるようにする
というところまでできました。

そして次に絶対ほしい機能が、**『記入済のページのみ(かなの頭文字で)あいうえお順に並ぶこと』**です。
あいうえお順からまた別の形に変える機能はつけません。
未記入ページは登録順に並んでほしいのですが、これは今のままで達成されています。

先ほどまで調べつつ試していましたが、さっぱり分からず進展がなく、自分で解決することが難しく感じたので、質問してみることにしました。
どのようにすればあいうえお順に並べることができるか、方法またはアドバイスを頂けますと幸いです。

イメージ説明

以下、すべてのコードです。

write.html【ここから追加すると<notyet.html><done.html>にことばが追加されていきます】

html

1<!doctype html> 2<html><head> 3<meta charset="utf-8"> 4<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 5<script type="text/javascript" src="main.js"></script> 6<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> 7<title></title> 8</head> 9 10 11 12<body> 13 <div id="app"> 14 15 <!-- ★STEP11 --> 16 17 <label v-for="label in options" > 18 <input type="radio" 19 v-model="current" 20 v-bind:value="label.value">{{ label.label }} 21 </label> 22 <!-- ★STEP12 --> 23 ({{ computedTodos.length }} 件を表示) 24 25 <!-- ★STEP4 リスト用テーブル --> 26 <table> 27 <thead v-pre> 28 <tr> 29 <th class="id">ID</th> 30 <th class="comment">ことば</th> 31 <th class="kana">かな</th> 32 <th class="state">状態</th> 33 <th class="button">-</th> 34 </tr> 35 </thead> 36 <tbody> 37 <!-- ★STEP5 ToDo の要素をループ --> 38 <tr 39 v-for="item in computedTodos" 40 v-bind:key="item.id" 41 v-bind:class="{done:item.state}"> 42 <th>{{ item.id }}</th> 43 <td>{{ item.comment }}</td> 44 <td>{{ item.kana }}</td> 45 <td class="state"> 46 <!-- ★STEP10 状態変更ボタン --> 47 <button v-on:click="doChangeState(item)"> 48 {{ labels[item.state] }} 49 </button> 50 </td> 51 <td class="button"> 52 <!-- ★STEP10 削除ボタン --> 53 <button v-on:click.ctrl="doRemove(item)"> 54 削除 55 </button> 56 </td> 57 </tr> 58 </tbody> 59 </table> 60 <p>※削除ボタンはコントロールキーを押しながらクリックして下さい</p></div> 61 62 63 64 65</body> 66</html> 67

notyet.html
文字数が収まりきらないので割愛

done.html【こちらをあいうえお順にしたい】

html

1<!doctype html> 2<html><head> 3<meta charset="utf-8"> 4<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 5<script type="text/javascript" src="main.js"></script> 6<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> 7<title></title> 8</head> 9 10 11 12<body> 13 <div id="appp"> 14 15 <!-- ★STEP11 --> 16 <label v-for="label in options" > 17 <input type="radio" 18 v-model="current" 19 v-bind:value="label.value">{{ label.label }} 20 </label> 21 22 <!-- ★STEP12 --> 23 ({{ computedTodos.length }} 件を表示) 24 25 <!-- ★STEP4 リスト用テーブル --> 26 <table> 27 <thead v-pre> 28 <tr> 29 <th class="kana">かな</th> 30 <th class="comment">ことば</th> 31 <th class="id">ID</th> 32 <th class="state">状態</th> 33 <th class="button">-</th> 34 </tr> 35 </thead> 36 <tbody> 37 <!-- ★STEP5 ToDo の要素をループ --> 38 <tr 39 v-for="item in computedTodos" 40 v-bind:key="item.id" 41 v-bind:class="{done:item.state}"> 42 <td>{{ item.kana }}</td> 43 <td>{{ item.comment }}</td> 44 <td>{{ item.id }}</td> 45 <td class="state"> 46 <!-- ★STEP10 状態変更ボタン --> 47 <button v-on:click="doChangeState(item)"> 48 {{ labels[item.state] }} 49 </button> 50 </td> 51 <td class="button"> 52 <!-- ★STEP10 削除ボタン --> 53 <button v-on:click.ctrl="doRemove(item)"> 54 削除 55 </button> 56 </td> 57 </tr> 58 </tbody> 59 </table> 60 <p>※削除ボタンはコントロールキーを押しながらクリックして下さい</p></div> 61 62 63</body> 64</html> 65

main.js

javascript

1 2// ★STEP2 3// https://jp.vuejs.org/v2/examples/todomvc.html 4var STORAGE_KEY = 'todos-vuejs-demo' 5var todoStorage = { 6 fetch: function () { 7 var todos = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]') 8 todos.forEach(function (todo, index) { 9 todo.id = index 10 }) 11 todoStorage.uid = todos.length 12 return todos 13 }, 14 save: function (todos) { 15 localStorage.setItem(STORAGE_KEY, JSON.stringify(todos)) 16 } 17} 18 19 20// ★STEP1 21document.addEventListener("DOMContentLoaded", function(event) { 22new Vue({ 23 el: '.app', 24 25 data: { 26 // ★STEP5 localStorage から 取得した ToDo のリスト 27 todos: [], 28 // ★STEP11 抽出しているToDoの状態 29 current: -1, 30 // ★STEP11&STEP13 各状態のラベル 31 options: [ 32 { value: -1, label: 'すべて' }, 33 { value: 0, label: '未記入' }, 34 { value: 1, label: '記入済' } 35 ] 36 }, 37 38 computed: { 39 40 // ★STEP12 41 computedTodos: function () { 42 return this.todos.filter(function (el) { 43 return this.current < 0 ? true : this.current === el.state 44 }, this) 45 }, 46 47 // ★STEP13 作業中・完了のラベルを表示する 48 labels() { 49 return this.options.reduce(function (a, b) { 50 return Object.assign(a, { [b.value]: b.label }) 51 }, {}) 52 // キーから見つけやすいように、次のように加工したデータを作成 53 // {0: '作業中', 1: '完了', -1: 'すべて'} 54 } 55 }, 56 57 // ★STEP8 58 watch: { 59 // オプションを使う場合はオブジェクト形式にする 60 todos: { 61 // 引数はウォッチしているプロパティの変更後の値 62 handler: function (todos) { 63 todoStorage.save(todos) 64 }, 65 // deep オプションでネストしているデータも監視できる 66 deep: true 67 } 68 }, 69 70 // ★STEP9 71 created() { 72 // インスタンス作成時に自動的に fetch() する 73 this.todos = todoStorage.fetch() 74 }, 75 76 methods: { 77 78 // ★STEP7 ToDo 追加の処理 79 doAdd: function(event, value) { 80 // ref で名前を付けておいた要素を参照 81 var comment = this.$refs.comment, 82 kana = this.$refs.kana, 83 val= $('.add-form [name=stts]:checked').val() 84 // 入力がなければ何もしないで return 85 if (!comment.value.length) { 86 return 87 } 88 // { 新しいID, コメント, 作業状態 } 89 // というオブジェクトを現在の todos リストへ push 90 // 作業状態「state」はデフォルト「作業中=0」で作成 91 this.todos.push({ 92 id: todoStorage.uid++, 93 comment: comment.value, 94 kana: kana.value, 95 state: Number(val) 96 }) 97 // フォーム要素を空にする 98 comment.value = '', 99 kana.value = '' 100 }, 101 102 // ★STEP10 状態変更の処理 103 doChangeState: function (item) { 104 item.state = !item.state ? 1 : 0 105 }, 106 107 // ★STEP10 削除の処理 108 doRemove: function (item) { 109 var index = this.todos.indexOf(item) 110 this.todos.splice(index, 1) 111 } 112 113 } 114}) 115}) 116 117document.addEventListener("DOMContentLoaded", function(event) { 118new Vue({ 119 el: '#appp', 120 121 data: { 122 // ★STEP5 localStorage から 取得した ToDo のリスト 123 todos: [], 124 // ★STEP11 抽出しているToDoの状態 125 current: 1, 126 // ★STEP11&STEP13 各状態のラベル 127 options: [ 128 { value: 1, label: '記入済' } 129 ] 130 }, 131 132 computed: { 133 134 // ★STEP12 135 computedTodos: function () { 136 return this.todos.filter(function (el) { 137 return this.current < 0 ? true : this.current === el.state 138 }, this) 139 }, 140 141 // ★STEP13 作業中・完了のラベルを表示する 142 labels() { 143 return this.options.reduce(function (a, b) { 144 return Object.assign(a, { [b.value]: b.label }) 145 }, {}) 146 // キーから見つけやすいように、次のように加工したデータを作成 147 // {0: '作業中', 1: '完了', -1: 'すべて'} 148 } 149 }, 150 151 // ★STEP8 152 watch: { 153 // オプションを使う場合はオブジェクト形式にする 154 todos: { 155 // 引数はウォッチしているプロパティの変更後の値 156 handler: function (todos) { 157 todoStorage.save(todos) 158 }, 159 // deep オプションでネストしているデータも監視できる 160 deep: true 161 } 162 }, 163 164 // ★STEP9 165 created() { 166 // インスタンス作成時に自動的に fetch() する 167 this.todos = todoStorage.fetch() 168 }, 169 170 methods: { 171 172 // ★STEP7 ToDo 追加の処理 173 doAdd: function(event, value) { 174 // ref で名前を付けておいた要素を参照 175 var comment = this.$refs.comment, 176 kana = this.$refs.kana, 177 val= $('.add-form [name=stts]:checked').val() 178 // 入力がなければ何もしないで return 179 if (!comment.value.length) { 180 return 181 } 182 // { 新しいID, コメント, 作業状態 } 183 // というオブジェクトを現在の todos リストへ push 184 // 作業状態「state」はデフォルト「作業中=0」で作成 185 this.todos.push({ 186 kana: kana.value, 187 comment: comment.value, 188 id: todoStorage.uid++, 189 state: Number(val) 190 }) 191 // フォーム要素を空にする 192 comment.value = '', 193 kana.value = '' 194 }, 195 // ★STEP10 状態変更の処理 196 doChangeState: function (item) { 197 item.state = !item.state ? 1 : 0 198 }, 199 200 // ★STEP10 削除の処理 201 doRemove: function (item) { 202 var index = this.todos.indexOf(item) 203 this.todos.splice(index, 1) 204 } 205 206 } 207}) 208})

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

「配列の要素を、特定の条件で並び替えたい」ということだとおもいますので、
Array.prototype.sort()メソッドが使えます。

JavaScript

1var array = [1, 3, 2, 5, 4]; 2 3var sortedArray = array.sort(function(a, b) { 4 return a - b; 5}); 6 7console.log(sortedArray); // -> [1, 2, 3, 4, 5]

質問のケースでは、もとの配列を並び替えてしまうと、未記入ページでも並びが変わってしまうので、
computedプロパティで、必要に応じて、別の並び替えた配列を返すようにします。

JavaScript

1new Vue({ 2 data() { 3 return { 4 // 登録順の配列を想定 5 todos: [ 6 { kana: 'う' }, 7 { kana: 'あ' }, 8 { kana: 'い' } 9 ] 10 } 11 }, 12 computed: { 13 sortedTodos: function() { 14 var copiedTodos = this.todos.slice(); // 配列の要素をコピー 15 16 return copiedTodos.sort(function(a, b) { 17 return a - b; 18 }); 19 } 20 } 21});

参考リンク
[Vue.jsのリスト(配列)レンダリング]((https://jp.vuejs.org/v2/guide/list.html)

投稿2018/11/29 14:56

編集2018/11/29 14:57
NozomuIkuta

総合スコア1260

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

terame120

2018/11/29 16:26

こちらでもご回答をいただきありがとうございます。 computedプロパティからその順番でデータを返すようにすることが必要だということが分かりました。 しばらく自分なりに試してみましたが、うまくできず、変わらずIDの数値で並んでいるので、疑問点をお聞きしたいです。 ①記入済みの表示はmain.jsのel:#appp指定から行い、登録はel:#appから行っているのですが、この場合コードの記述は#apppで良いでしょうか。それとも新しくnew Vueを記述するのでしょうか。 #apppで良い場合、すでにcomputed:{に振り分けのための記述があるのですが、書く順番は特に決まりはないでしょうか。 ②保存されている配列はkana以外の要素もあり、 [ { "id": ●, "comment": "ことば", "kana"="かな,"state": ● },...] といった形で収まっていると思うのですが、この場合kanaの文字列を参照させるための操作はあるでしょうか? または登録時にkanaが先頭に来るようにするとよいでしょうか。 (kanaが先頭にくるよう自分なりにやってみましたがうまくいかず…) ③参考にしたサイトのJSでは、ひとつも;がなく、すべて,でつながれているのですが、(別のサイトを参考にしたとき;を入れるとJavascriptが動かなくなることがほとんどで…)(こちらのコードを;が入ったままで挿入してみたところjavascriptが働いていない様子はありませんでした) こちらのコードでの;の扱いは、ないと通用しないのか、なくてもなんとかなるのか、分かれば教えていただけると嬉しいです。 computed: { sortedTodos: function() { var copiedTodos = this.todos.slice(); // 配列の要素をコピー return copiedTodos.sort(function(a, b) { return a - b; }); } を#apppのcompured:{に入れるという形で、その周辺をいじって反応を見ていましたが、成功せず、勉強不足の身で何度も伺ってしまい恐縮なのですが、可能な範囲でアドバイスを頂けましたら嬉しいです。(説明が下手で状況が伝わらなかったら申し訳ありません。)
terame120

2018/12/01 08:28

この後また考えて、main.jsの#apppの場所のcompted内、すでにあったcomputedTodo:{以下に記述するとやりやすいと分かりました。 sortが働いている気がしますが、(sort以外の要素を排しても配列がきちんと表示されるので)並び順は変わらないため、idを参照してソートしているのかなと推測しています。 全くの見当違いでしたら申し訳ありませんが、.sortを使用する際に、オブジェクトのなかのあるデータを参照する方法はありますでしょうか。 htmlのほうで@click="sortBy('kana')"の要素を入れるとソートするボタンが作れるようにも思いましたが、最初から並んでいてほしいので、その方法が知りたいです。 アドバイスを頂けないでしょうか。
terame120

2018/12/02 02:46

できました。a.kana b.kanaでよかったのですね。 また、ひらがなのソートのコードのことも知らずにおりました。 しつこく聞いて申し訳ありませんでした。ヒントをありがとうございました。とても助かりました。
NozomuIkuta

2018/12/02 05:56

返信できておらず、すみません。 解決したようでよかったです。 内容をみる限り、Vue.jsよりも、JavaScriptの構文(文法)であいまいな部分があるようですので、一度ざっと見返すことをおすすめします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問