nextjs.orgをただ読んでいくだけの投稿 その1

※ nextjs.orgをGoogle翻訳したのをただ読んで、気になった部分だけをコピペしていくだけの投稿です

Getting Started - Next.js Documentation <-のURLの以下カテゴリーを読みました

  • How to use
    • Setup
    • Automatic code splitting
    • CSS
      • Built-in CSS support
      • CSS-in-JS
      • Importing CSS / Sass / Less / Stylus files

Setup

https://nextjs.org/docs#setup

それをインストールしてください。

npm install --save next react react-dom

このようにpackage.jsonスクリプトを追加します。

{
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  }
}

自分の環境では以下のようになりました

{
  "name": "code",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "next": "^7.0.2",
    "react": "^16.7.0",
    "react-dom": "^16.7.0"
  }
}

それ以降は、ファイルシステムがメインのAPIです。すべての.jsファイルは自動的に処理されレンダリングされるルートになります。

Populate ./pages/index.js inside your project:

export default () => <div>Welcome to next.js!</div>

それから npm run dev を実行して http:// localhost:3000 に行きます。別のポートを使用するには、npm run dev - -p <自分のポートはこちら> を実行します。

これまでのところ、

  • 自動transpilationと同梱(webpackとbabelを使って)
  • ホットコードの再読み込み
  • サーバーレンダリング./pages のインデックス作成
  • 静的ファイルサービング ./static// static /マッピングされます(プロジェクト内に ./static/ ディレクトリを作成した場合)。

これがどれほど簡単かを確認するには、サンプルアプリ - nextgramをチェックしてください。

Automatic code splitting

https://nextjs.org/docs#automatic-code-splitting

Every import you declare gets bundled and served with each page. That means pages never load unnecessary code!

import cowsay from 'cowsay-browser'

export default () => (
  <pre>
    {cowsay.say({ text: 'hi there!' })}
  </pre>
)

f:id:okumuraa1:20190110225707p:plain

CSS

https://nextjs.org/docs#css

Built-in CSS support

孤立したスコープ付きCSSをサポートするためにstyled-jsxをバンドルします。目的はWebコンポーネントに似た「シャドウCSS」をサポートすることです。残念ながらサーバーレンダリングはサポートしておらず、JSのみです。

export default () => (
    <div>
        Hello world
        <p>scoped!</p>
        <style jsx>{`
            p {
                color: blue;
            }
            div {
                background: red;
            }
            @media (max-width: 600px) {
                div {
                background: blue;
                }
            }
        `}</style>
        <style global jsx>{`
            body {
                background: black;
            }
        `}</style>
    </div>
)

他の例についてはstyled-jsxのドキュメントを参照してください。

f:id:okumuraa1:20190117235549p:plain

CSS-in-JS

既存のCSS-in-JSソリューションを使用することは可能です。最も簡単なのはインラインスタイルです。

export default () => <p style={{ color: 'red' }}>hi there</p>

より洗練されたCSS-in-JSソリューションを使用するには、通常、サーバーサイドレンダリング用のスタイルフラッシュを実装する必要があります。これを可能にするのは、各ページをラップする独自のカスタムコンポーネントを定義できるようにすることです。

f:id:okumuraa1:20190120190920p:plain

f:id:okumuraa1:20190120191008p:plain

Importing CSS / Sass / Less / Stylus files

.css.scss.less、または.stylファイルのインポートをサポートするために、これらのモジュールを使用することができます。これらのモジュールは、サーバーでレンダリングされたアプリケーションに適切なデフォルトを設定します。

vuejs.orgをただ読んでいくだけ - その6

クラスとスタイルのバインディング — Vue.js <- ここを読みました

Vue.js v2.5.21で確認しています

https://github.com/okumurakengo/vuejsorg-reading/blob/master/guide/class-and-style.html <- 自分で試したコード

※ vuejs.orgをただ読んで、気になった部分だけをコピペしていくだけの投稿です


データバインディングに一般に求められることの 1 つは、要素のクラスリストとインラインスタイルを操作することです。それらはどちらも属性ですから、v-bind を使って扱うことができます。最終的な文字列を式で計算するだけです。しかしながら、文字列の連結に手を出すのは煩わしく、エラーのもとです。そのため、Vue は v-bindclassstyle と一緒に使われるとき、特別な拡張機能を提供します。文字列だけではなく、式はオブジェクトまたは配列を返すことができます。

HTML クラスのバインディング

オブジェクト構文

v-bind:class にオブジェクトを渡すことでクラスを動的に切り替えることができます:

<div v-bind:class="{ active: isActive }"></div>

上記の構文は、active クラスの有無がデータプロパティ isActive の真偽性によって決まることを意味しています。

オブジェクトにさらにフィールドを持たせることで複数のクラスを切り替えることができます。加えて、v-bind:class ディレクティブはプレーンな class 属性と共存できます。つまり、次のようなテンプレートと:

<div
  class="static"
  v-bind:class="{ active: isActive, 'text-danger': hasError }"
></div>

次のようなデータがあったとすると:

data: {
  isActive: true,
  hasError: false
}

このように描画されます:

<div class="static active"></div>

isActive もしくは hasError が変化するとき、クラスリストはそれに応じて更新されます。例えば、hasErrortrue になった場合、クラスリストは "static active text-danger" になります。

束縛されるオブジェクトはインラインでなくてもかまいません:

<div v-bind:class="classObject"></div>
data: {
  classObject: {
    active: true,
    'text-danger': false
  }
}

これは同じ結果を描画します。オブジェクトを返す算出プロパティに束縛することもできます。これは一般的で強力なパターンです:

<div v-bind:class="classObject"></div>
data: {
  isActive: true,
  error: null
},
computed: {
  classObject: function () {
    return {
      active: this.isActive && !this.error,
      'text-danger': this.error && this.error.type === 'fatal'
    }
  }
}

自分で試したコードはこのようになりました

    <div id="sample">
            <div
            class="static"
            v-bind:class="{ active: isActive, 'text-danger': hasError }"
        >hogehoge</div>
        <div v-bind:class="classObject">fugafuga</div>
    </div>
    <script>
    new Vue({
        el: '#sample div:first-child',
        data: {
            isActive: true,
            hasError: false
        }
    });
    new Vue({
        el: '#sample div:last-child',
        data: {
            classObject: {
                active: true,
                'text-danger': false
            }
        },
    });
    </script>

f:id:okumuraa1:20190115235607p:plain

配列構文

v-bind:class に配列を渡してクラスのリストを適用することができます:

<div v-bind:class="[activeClass, errorClass]"></div>
data: {
  activeClass: 'active',
  errorClass: 'text-danger'
}

これは次のように描画されます:

<div class="active text-danger"></div>

リスト内のクラスを条件に応じて切り替えたい場合は、三項演算子式を使って実現することができます:

<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>

この場合 errorClass は常に適用されますが、activeClass クラスは isActive が真と評価されるときだけ適用されます。

しかしながら、これでは複数の条件つきクラスがあると少し冗長になってしまいます。そのため、配列構文の内部ではオブジェクト構文を使うこともできます:

<div v-bind:class="[{ active: isActive }, errorClass]"></div>

コンポーネントにおいて

カスタムコンポーネント上で class 属性を使用するとき、これらのクラスはコンポーネントの root 要素 に追加されます。この要素上に存在するクラスは、上書きされません。

例えば、このコンポーネントを宣言して:

Vue.component('my-component', {
  template: '<p class="foo bar">Hi</p>'
})

使用するときにいくつかのクラスを追加したとします:

<my-component class="baz boo"></my-component>

以下の HTML が描画されます:

<p class="foo bar baz boo">Hi</p>

クラスバインディングに対しても同様です:

<my-component v-bind:class="{ active: isActive }"></my-component>

isActive が真と評価されるときは、以下の HTML が描画されます:

<p class="foo bar active">Hi</p>

インラインスタイルのバインディング

オブジェクト構文

v-bind:style 向けのオブジェクト構文は非常に簡単です。JavaScript オブジェクトということを除けば、ほとんど CSS のように見えます。CSS のプロパティ名には、キャメルケース (camelCase) またはケバブケース (kebab-case: クォートとともに使うことになります) のどちらでも使用することができます:

<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
data: {
  activeColor: 'red',
  fontSize: 30
}

テンプレートをクリーンにするために、直接 style オブジェクトに束縛するのは、よいアイディアです:

<div v-bind:style="styleObject"></div>
data: {
  styleObject: {
    color: 'red',
    fontSize: '13px'
  }
}

ここでもまた、オブジェクト構文はしばしばオブジェクトを返す算出プロパティと併せて使用されます。

配列構文

v-bind:style 向けの配列構文は、同じ要素に複数のスタイルオブジェクトを適用することができます:

<div v-bind:style="[baseStyles, overridingStyles]"></div>

自動プリフィックス

v-bind:style でベンダー接頭辞を要求される CSS プロパティを使用するとき、例えば、transform においては、Vue.js は自動的に適切な接頭辞を検出し、適用されるスタイルに追加します。

複数の値

2.3.0 以降では、 style プロパティに複数の (接頭辞付き) 値の配列を設定できます。例えば次のようになります:

<div v-bind:style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>

これは、配列内でブラウザがサポートしている最後の値だけを描画します。この例では、flexbox の接頭されていないバージョンをサポートしているブラウザでは display: flex を描画します。

vuejs.orgをただ読んでいくだけ - その5

算出プロパティとウォッチャ — Vue.js <- ここを読みました

Vue.js v2.5.21で確認しています

https://github.com/okumurakengo/vuejsorg-reading/blob/master/guide/computed.html <- 自分で試したコード

※ vuejs.orgをただ読んで、気になった部分だけをコピペしていくだけの投稿です


算出プロパティ

テンプレート内に式を書けるのはとても便利ですが、非常に簡単な操作しかできません。テンプレート内に多くのロジックを詰め込むと、コードが肥大化し、メンテナンスが難しくなります。例えば:

<div id="example">
  {{ message.split('').reverse().join('') }}
</div>

こうなってくると、テンプレートはシンプルでも宣言的でもなくなってしまっています。しばらく眺めて、やっとこれが message を逆にして表示していることに気付くでしょう。逆にしたメッセージをテンプレートの中で 2 回以上使おうとすると、問題はより深刻になります。 上記の理由から、複雑なロジックには算出プロパティを利用すべきです。

基本的な例

    <div id="example">
        <p>Original message: "{{ message }}"</p>
        <p>Computed reversed message: "{{ reversedMessage }}"</p>
    </div>
    <script>
        var vm = new Vue({
            el: '#example',
            data: {
                message: 'Hello'
            },
            computed: {
                // 算出 getter 関数
                reversedMessage: function () {
                    // `this` は vm インスタンスを指します
                    return this.message.split('').reverse().join('')
                }
            }
        })
    </script>

f:id:okumuraa1:20190109233858p:plain

ここでは、算出プロパティ reversedMessage を宣言しました。私たちが提供した機能は、プロパティ vm.reversedMessage に対する getter 関数として利用されます:

console.log(vm.reversedMessage) // => 'olleH'
vm.message = 'Goodbye'
console.log(vm.reversedMessage) // => 'eybdooG'

コンソールを開いて、vm で遊んでみてください。vm.reversedMessage の値は、常に vm.message の値に依存しています。

通常のプロパティと同じように、テンプレート内の算出プロパティにデータバインドすることもできます。Vue は vm.reversedMessage が vm.message に依存していることを知っているので、vm.message が変わると vm.reversedMessage に依存する全てのバインディングを更新します。さらに、最も良いところは、この依存関係が宣言的に作成されていることです。算出 getter 関数は副作用がないので、テストや値の推論が容易になります。

算出プロパティ vs メソッド

<p>Reversed message: "{{ reverseMessage() }}"</p>
// コンポーネント内
methods: {
  reverseMessage: function () {
    return this.message.split('').reverse().join('')
  }
}

算出プロパティの代わりに、同じような関数をメソッドとして定義することも可能です。最終的には、2つのアプローチは完全に同じ結果になります。しかしながら、算出プロパティは依存関係にもとづきキャッシュされるという違いがあります。算出プロパティは、それが依存するものが更新されたときにだけ再評価されます。これはつまり、message が変わらない限りは、reversedMessage に何度アクセスしても、関数を再び実行することなく以前計算された結果を即時に返すということです。

Date.now() はリアクティブな依存ではないため、次の算出プロパティは二度と更新されないことを意味します:

computed: {
  now: function () {
    return Date.now()
  }
}

対称的に、メソッド呼び出しは、再描画が起きると常に関数を実行します。

算出プロパティ vs 監視プロパティ

Vue は Vue インスタンス上のデータの変更を監視し反応させることができる、より汎用的な 監視プロパティ(watched property) を提供しています。他のデータに基づいて変更する必要があるデータがある場合、特に AngularJS に慣れていたら、watch を多く利用したいと思うかもしれません。しかし、命令的な watch コールバックよりも、多くの場合では算出プロパティを利用するほうが良いでしょう。次の例で考えてみましょう:

<div id="demo">{{ fullName }}</div>
var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
})

上記のコードは命令的で冗長です。算出プロパティを利用したバージョンと比較してみましょう:

var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  }
})

こちらの方が、はるかに良くありませんか?

算出 Setter 関数

算出プロパティはデフォルトでは getter 関数のみですが、必要があれば setter 関数も使えます:

// ...
computed: {
  fullName: {
    // getter 関数
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter 関数
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}
// ...

vm.fullName = 'John Doe' を呼ぶと、setter 関数が呼び出され、vm.firstNamevm.lastName が適切に更新されます。

ウォッチャ

多くの場合では算出プロパティの方が適切ではありますが、カスタムウォッチャが必要な時もあるでしょう。データの変更に対して反応する、より汎用的な watch オプションを Vue が提供しているのはそのためです。データが変わるのに応じて非同期やコストの高い処理を実行したいときに最も便利です。

<div id="watch-example">
  <p>
    Ask a yes/no question:
    <input v-model="question">
  </p>
  <p>{{ answer }}</p>
</div>
<!-- ajax ライブラリの豊富なエコシステムや、汎用的なユーティリティ -->
<!-- メソッドがたくさんあるので、Vue のコアはそれらを再発明せずに       -->
<!-- 小さく保たれています。この結果として、慣れ親しんでいるものだけを   -->
<!-- 使えるような自由さを Vue は持ち合わせています。           -->
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script>
<script>
var watchExampleVM = new Vue({
  el: '#watch-example',
  data: {
    question: '',
    answer: 'I cannot give you an answer until you ask a question!'
  },
  watch: {
    // この関数は question が変わるごとに実行されます。
    question: function (newQuestion, oldQuestion) {
      this.answer = 'Waiting for you to stop typing...'
      this.debouncedGetAnswer()
    }
  },
  created: function () {
    // _.debounce は特にコストの高い処理の実行を制御するための
    // lodash の関数です。この場合は、どのくらい頻繁に yesno.wtf/api
    // へのアクセスすべきかを制限するために、ユーザーの入力が完全に
    // 終わるのを待ってから ajax リクエストを実行しています。
    // _.debounce (とその親戚である _.throttle )  についての詳細は
    // https://lodash.com/docs#debounce を見てください。
    this.debouncedGetAnswer = _.debounce(this.getAnswer, 500)
  },
  methods: {
    getAnswer: function () {
      if (this.question.indexOf('?') === -1) {
        this.answer = 'Questions usually contain a question mark. ;-)'
        return
      }
      this.answer = 'Thinking...'
      var vm = this
      axios.get('https://yesno.wtf/api')
        .then(function (response) {
          vm.answer = _.capitalize(response.data.answer)
        })
        .catch(function (error) {
          vm.answer = 'Error! Could not reach the API. ' + error
        })
    }
  }
})
</script>

この場合では、watch オプションを利用することで、非同期処理( API のアクセス)の実行や、処理をどのくらいの頻度で実行するかを制御したり、最終的な answer が取得できるまでは中間の状態にしておく、といったことが可能になっています。これらはいずれも算出プロパティでは実現できません。

watch オプションに加えて、命令的な vm.$watch API を利用することもできます。

複雑な処理だとwatchの方を使った方が良さそう

ドットインストールのUNIXコマンド入門 [一般ユーザー編] を一通り真似して実行した備忘録

タイトルの通りです。 私の備忘録ですのでところどころ飛ばしながらかいています。正しい情報を知りたい方はドットインストールをご確認お願いいします。

https://dotinstall.com/lessons/basic_unix_v2


現在のパス

[vagrant@localhost ~]$ pwd
/home/vagrant
  • clear または Ctrl+l

画面表示をリセット

f:id:okumuraa1:20190105232252g:plain

  • cd

ディレクトリ移動

[vagrant@localhost ~]$ cd unix_lessons/
[vagrant@localhost unix_lessons]$ 
[vagrant@localhost ~]$ cd unix_lessons/
[vagrant@localhost unix_lessons]$ cd - # 一つ前のディクトリに戻れる
/home/vagrant
  • mkdir

ディレクトリ作成

[vagrant@localhost unix_lessons]$ mkdir myqpp
[vagrant@localhost unix_lessons]$ ls
myqpp
  • cp

コピー

[vagrant@localhost unix_lessons]$ cp -r myqpp myqpp2 # -r でディクトリコピー
[vagrant@localhost unix_lessons]$ ls
myqpp  myqpp2
[vagrant@localhost unix_lessons]$ mkdir -p myqpp3/config # -p で途中のディレクトリがない場合作成する
[vagrant@localhost unix_lessons]$ ls myqpp3
config
  • mv

移動

$ mv myqpp3 myqpp2

f:id:okumuraa1:20190105233911p:plain

  • rmdir

ディレクトリ削除

[vagrant@localhost unix_lessons]$ rmdir myqpp2/myqpp3/config
[vagrant@localhost unix_lessons]$ ls myqpp2/myqpp3/
[vagrant@localhost unix_lessons]$ 
  • rm

削除

[vagrant@localhost unix_lessons]$ rm -r myqpp2 # -r でフォルダ内も全て削除
[vagrant@localhost unix_lessons]$ ls
myqpp
  • cat

ファイルの中身を見る

$ cat myqpp/hello.txt 
1.

hello. hello. hello. hello. hello. hello. 
(省略)
  • less

長いファイルを表示する時に便利

$ less myqpp/hello.txt

f:id:okumuraa1:20190105234618p:plain

    • スペースCtrl + fで一画面先
    • Ctrl + bで一画面前
    • gでファイルの先頭
    • Shift + gでファイルの末尾
    • qでlessの終了
  • history

コマンドの履歴

[vagrant@localhost unix_lessons]$ history
(省略)
  408  cd ..
  409  cd -
  410  cd home/vagrant/
  411  cd unix_lessons/
  412  history
  413  pwd
  414  history
[vagrant@localhost unix_lessons]$ !413 # historyで表示された番号のコマンドを実行できる
pwd
/home/vagrant/unix_lessons
[vagrant@localhost unix_lessons]$ !! # 直前のコマンドを実行
pwd
/home/vagrant/unix_lessons
[vagrant@localhost unix_lessons]$ !-2 # 2つ前のコマンドを実行
history
(省略)

[vagrant@localhost unix_lessons]$ ls myqpp/
hello.txt
[vagrant@localhost unix_lessons]$ cd !$ # 直前のコマンドの引数を使用できる
cd myqpp/
[vagrant@localhost myqpp]$ cd ..
[vagrant@localhost unix_lessons]$ !pw # 直近でpwから始まるコマンドを実行
pwd
/home/vagrant/unix_lessons
[vagrant@localhost unix_lessons]$ !pw:p # 直近でpwから始まるコマンドを表示だけして実行はしない
pwd
[vagrant@localhost unix_lessons]$ !!
pwd
/home/vagrant/unix_lessons

ヘルプ表示

$ mkdir --help
Usage: mkdir [OPTION]... DIRECTORY...
Create the DIRECTORY(ies), if they do not already exist.

Mandatory arguments to long options are mandatory for short options too.
  -m, --mode=MODE   set file mode (as in chmod), not a=rwx - umask
  -p, --parents     no error if existing, make parent directories as needed
  -v, --verbose     print a message for each created directory
  -Z                   set SELinux security context of each created directory
                         to the default type
      --context[=CTX]  like -Z, or if CTX is specified then set the SELinux
                         or SMACK security context to CTX
      --help     display this help and exit
      --version  output version information and exit

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
Report mkdir translation bugs to <http://translationproject.org/team/>
For complete documentation, run: info coreutils 'mkdir invocation'
  • man

ヘルプ表示

$ man ls

f:id:okumuraa1:20190106001035p:plain

  • vi

エディタを起動

$ vi hello.txt

f:id:okumuraa1:20190106001327p:plain

$ pwd
/home/vagrant/unix_lessons/myqpp
$ mkdir -p config/production/database
$ ln -s config/production/database/ dbconfig # シンボリックリンク作成
$ ls -l # シンボリックリンクが作成されていることを確認
total 8
drwxrwxr-x. 3 vagrant vagrant 4096 Jan  5 15:16 config
lrwxrwxrwx. 1 vagrant vagrant   27 Jan  5 15:16 dbconfig -> config/production/database/
-rw-rw-r--. 1 vagrant vagrant 3149 Jan  5 14:44 hello.txt
$ touch dbconfig/commands.sql # リンクしているところにファイルを作成
$ ls dbconfig/
commands.sql
$ ls config/production/database/ # リンク元を見てもファイルが作成されている
commands.sql
$ rm dbconfig/commands.sql # リンクしているところで削除
$ ls config/production/database/ # リンク元を見ても削除されている
$ unlink dbconfig # シンボリックリンク削除
$ ls
config  hello.txt
  • コマンド作成
$ type hi # hiというコマンドがないことを確認
-bash: type: hi: not found
$ type cat # コマンドが存在した場合は情報が表示される
cat is hashed (/usr/bin/cat)
$ vi hi
$ cat hi
#!/bin/bash
echo "hi!"

$ ls -l
total 12
drwxrwxr-x. 3 vagrant vagrant 4096 Jan  5 15:16 config
-rw-rw-r--. 1 vagrant vagrant 3149 Jan  5 15:21 hello.txt
-rw-rw-r--. 1 vagrant vagrant   24 Jan  5 15:27 hi
$ chmod u+x hi # 実行権限を与える
$ ls -l
total 12
drwxrwxr-x. 3 vagrant vagrant 4096 Jan  5 15:16 config
-rw-rw-r--. 1 vagrant vagrant 3149 Jan  5 15:21 hello.txt
-rwxrw-r--. 1 vagrant vagrant   24 Jan  5 15:27 hi # <- 実行権限が付いていることを確認
$ ./hi
hi!
  • PATHを通す
$ echo $PATH # 現在設定されているパスを確認
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/vagrant/.local/bin:/home/vagrant/bin
$ printenv # 環境変数の一覧をみれる
(省略)
PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/vagrant/.local/bin:/home/vagrant/bin
PWD=/home/vagrant/unix_lessons/myqpp
LANG=en_US.UTF-8
SELINUX_LEVEL_REQUESTED=
HISTCONTROL=ignoredups
SHLVL=1
HOME=/home/vagrant
LOGNAME=vagrant
SSH_CONNECTION=10.0.2.2 59837 10.0.2.15 22
LC_CTYPE=UTF-8
LESSOPEN=||/usr/bin/lesspipe.sh %s
XDG_RUNTIME_DIR=/run/user/1000
_=/usr/bin/printenv
$ pwd
/home/vagrant/unix_lessons/myqpp
$ export PATH=/home/vagrant/unix_lessons/myqpp:$PATH # 現在のパスを環境変数に追加で設定する
$ echo $PATH # パスが追加されたことを確認
/home/vagrant/unix_lessons/myqpp:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/vagrant/.local/bin:/home/vagrant/bin
$ hi # 実行確認
hi!
$ which hi # コマンドの場所を確認
~/unix_lessons/myqpp/hi

※↑のやり方だと追加したパスはログアウトすると無効になる

  • 管理者ユーザー
$ ls -l /var/log/messages 
-rw-------. 1 root root 495634 Jan  5 15:39 /var/log/messages
$ cat !$ # 一般ユーザーだと見れない
cat /var/log/messages
cat: /var/log/messages: Permission denied
$ su - # 管理者ユーザーになる、-lで再ログインする、-lを省略して-でもOK
Password: 
Last login: Sat Jan  5 15:39:21 UTC 2019 on pts/0
# pwd
/root
# cat /var/log/messages 
(省略)
# exit # 管理者権限を終了
logout
$ sudo cat /var/log/messages # これでも実行できる
  • chown
$ cp /var/log/messages .
cp: cannot open '/var/log/messages' for reading: Permission denied
$ sudo !! # ファイルコピー
sudo cp /var/log/messages .
$ ls -l
total 496
-rw-------. 1 root    root    495691 Jan  5 15:49 messages
$ cat messages # 所有者が違うため見れない
cat: messages: Permission denied
$ sudo chown vagrant:vagrant messages # 所有者変更
$ ls -l # 所有者が変更されていることを確認
total 496
-rw-------. 1 vagrant vagrant 495691 Jan  5 15:49 messages
$ cat messages 
(省略)
  • wc
$ wc messages 
  5468  61272 495691 messages
    • 行数 -> 5468
    • 単語数 -> 61272
    • バイト数 -> 495691
    • ファイル名 -> messages
$ wc -l messages # -lで行数だけ出せる
5468 messages
  • head、tail

ファイルの先頭(デフォルトでは10行)を読み込む

$ head messages 
Jan  1 15:40:28 localhost journal: Runtime journal is using 4.0M (max allowed 24.3M, trying to leave 36.5M free of 239.8M available → current limit 24.3M).
Jan  1 15:40:28 localhost kernel: Initializing cgroup subsys cpuset
Jan  1 15:40:28 localhost kernel: Initializing cgroup subsys cpu
Jan  1 15:40:28 localhost kernel: Initializing cgroup subsys cpuacct
Jan  1 15:40:28 localhost kernel: Linux version 3.10.0-862.14.4.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC) ) #1 SMP Wed Sep 26 15:12:11 UTC 2018
Jan  1 15:40:28 localhost kernel: Command line: BOOT_IMAGE=/boot/vmlinuz-3.10.0-862.14.4.el7.x86_64 root=UUID=b5b20816-947c-4616-b15a-abaae4afe31b ro no_timer_check console=tty0 console=ttyS0,115200n8 net.ifnames=0 biosdevname=0 elevator=noop crashkernel=auto LANG=en_US.UTF-8
Jan  1 15:40:28 localhost kernel: e820: BIOS-provided physical RAM map:
Jan  1 15:40:28 localhost kernel: BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable
Jan  1 15:40:28 localhost kernel: BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved
Jan  1 15:40:28 localhost kernel: BIOS-e820: [mem 0x00000000000f0000-0x00000000000fffff] reserved

$ head -3 messages # 先頭3行を読み込む
Jan  1 15:40:28 localhost journal: Runtime journal is using 4.0M (max allowed 24.3M, trying to leave 36.5M free of 239.8M available → current limit 24.3M).
Jan  1 15:40:28 localhost kernel: Initializing cgroup subsys cpuset
Jan  1 15:40:28 localhost kernel: Initializing cgroup subsys cpu

$ tail -3 messages # 末尾3行を読み込む
Jan  5 15:01:01 localhost systemd: Removed slice User Slice of root.
Jan  5 15:39:21 localhost su: (to root) vagrant on pts/0
Jan  5 15:42:51 localhost su: (to root) vagrant on pts/0
$ grep 'etc' messages # etcが含まれている行を表示してくれる
(省略)
  • リダイレクション
$ echo "date" > cmd.txt # ファイルにdateを書き込む
$ cat cmd.txt 
date
$ echo "free" >> cmd.txt # ファイルに追記する
$ cat cmd.txt 
date
free
$ bash < cmd.txt # 書かれていることを実行もできる
$ bash < cmd.txt 
Sat Jan  5 15:58:46 UTC 2019
              total        used        free      shared  buff/cache   available
Mem:         498892       61616      278768        4588      158508      398680
Swap:       2097148           0     2097148
$ bash < cmd.txt > result.txt
$ cat result.txt
Sat Jan  5 15:58:56 UTC 2019
              total        used        free      shared  buff/cache   available
Mem:         498892       61736      278604        4588      158552      398536
Swap:       2097148           0     2097148
  • パイプ
$ ls -l /etc | grep "yum" # パイプで渡すことができる
drwxr-xr-x.  6 root root     4096 Jan  1 15:45 yum
-rw-r--r--.  1 root root      970 Nov  5 01:53 yum.conf
drwxr-xr-x.  2 root root     4096 Jan  1 16:22 yum.repos.d
$ ls -l /etc | grep "yum" | wc -l # 複数渡すこともできる
3
$ ls /etc/*.conf
/etc/GeoIP.conf   /etc/idmapd.conf    /etc/logrotate.conf    /etc/resolv.conf     /etc/sysctl.conf
/etc/asound.conf  /etc/krb5.conf      /etc/man_db.conf       /etc/rsyncd.conf     /etc/tcsd.conf
/etc/chrony.conf  /etc/ld.so.conf     /etc/nfs.conf          /etc/rsyslog.conf    /etc/vconsole.conf
/etc/dracut.conf  /etc/libaudit.conf  /etc/nfsmount.conf     /etc/sestatus.conf   /etc/yum.conf
/etc/fuse.conf    /etc/libuser.conf   /etc/nsswitch.conf     /etc/sudo-ldap.conf
/etc/host.conf    /etc/locale.conf    /etc/request-key.conf  /etc/sudo.conf
$ ls /etc/c??.*
/etc/csh.cshrc  /etc/csh.login
  • find、xargs
$ sudo find /etc -name "yum*"
/etc/yum.conf
/etc/bash_completion.d/yum-utils.bash
/etc/yum
/etc/yum.repos.d
/etc/logrotate.d/yum
$ sudo find /etc -name "yum*" -type f
/etc/yum.conf # ファイルだけを検索
/etc/bash_completion.d/yum-utils.bash
/etc/logrotate.d/yum
$ sudo find /etc -name "yum*" -type f -exec wc -l {} + # 結果をさらにwcコマンドに渡す場合
   26 /etc/yum.conf
  427 /etc/bash_completion.d/yum-utils.bash
    7 /etc/logrotate.d/yum
  460 total
$ sudo find /etc -name "yum*" -type f | xargs wc -l # ↑と同じ意味
   26 /etc/yum.conf
  427 /etc/bash_completion.d/yum-utils.bash
    7 /etc/logrotate.d/yum
  460 total
  • ブレース展開
$ echo {a,b,c}
a b c
$ echo {1..10}
1 2 3 4 5 6 7 8 9 10
$ echo {1..10}{a..g}
1a 1b 1c 1d 1e 1f 1g 2a 2b 2c 2d 2e 2f 2g 3a 3b 3c 3d 3e 3f 3g 4a 4b 4c 4d 4e 4f 4g 5a 5b 5c 5d 5e 5f 5g 6a 6b 6c 6d 6e 6f 6g 7a 7b 7c 7d 7e 7f 7g 8a 8b 8c 8d 8e 8f 8g 9a 9b 9c 9d 9e 9f 9g 10a 10b 10c 10d 10e 10f 10g
$ mkdir test && cd test
$ pwd
/home/vagrant/unix_lessons/test
$ mkdir app{1..5}
$ ls
app1  app2  app3  app4  app5
$ touch app{1..5}/test{1..3}{.txt,.jpeg,.gif}
$ ls app2
test1.gif  test1.jpeg  test1.txt  test2.gif  test2.jpeg  test2.txt  test3.gif  test3.jpeg  test3.txt
$ rm app{1..5}/test{1..3}{.jpeg,.gif}
$ ls app2
test1.txt  test2.txt  test3.txt

vuejs.orgをただ読んでいくだけ - その4

テンプレート構文 — Vue.js <- ここを読みました

https://github.com/okumurakengo/vuejsorg-reading/blob/master/guide/syntax.html <- 自分で試したコード

※ vuejs.orgをただ読んで、気になった部分だけをコピペしていくだけの投稿です


Vue.js では HTML ベースのテンプレート構文を使っているので、Vue インスタンスのデータと描画された DOM を宣言的に対応させることができます。全ての Vue.js テンプレートは、仕様に準拠しているブラウザや HTML パーサによってパースできる有効な HTML です。

内部では、Vue はテンプレートを Virtual DOM の描画関数にコンパイルします。リアクティブシステムと組み合わせて、Vue は再描画に必要なコンポーネントをインテリジェントに把握でき、アプリケーションの状態が変わった時に最低限の DOM 操作を適用します。

もし、あなたが Virtual DOM の概要に詳しく、JavaScript で直接描画するのを好む場合、テンプレートの代わりに直接 render 関数で書く ことも可能で、オプションで JSX をサポートしています。

展開

テキスト

データバインディングのもっとも基本的な形は、”Mustache” 構文(二重中括弧)を利用したテキスト展開です:

<span>Message: {{ msg }}</span>

Mustacheの読み方はマスタッシュでいいのかな

mustache タグは、対応するオブジェクトの msg プロパティの値に置き換えられます。また、msg プロパティが変更される時、それに応じて更新されます。

v-once ディレクティブを使用することで、データ変更時の更新はおこなわず、一度だけ展開することができます。ただし、同じノードのあらゆる他のバインディングが影響を受けることに注意してください:

<span v-once>This will never change: {{ msg }}</span>

生の HTML

2重中括弧の mustaches は、データを HTML ではなく、プレーンなテキストとして扱います。実際の HTML として出力するためには、v-html ディレクティブを使用する必要があります:

<p>Using mustaches: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>

XSS 脆弱性を容易に引き起こすので、ウェブサイトで動的に任意のHTMLを描画することは、非常に危険です。信頼できるコンテンツにだけ HTML 展開を利用してください。ユーザーから提供されたコンテンツに対しては決して使用してはいけません。

属性

Mustache は、HTML 属性の内部で使用することはできません。代わりに、v-bind ディレクティブを使用してください:

<div v-bind:id="dynamicId"></div>

属性が単に存在していることを true と示すといった真偽値属性の場合、v-bind は少し異なった働きをします。この例では:

<button v-bind:disabled="isButtonDisabled">Button</button>

isButtonDisabled が null、undefined、または false の値を持つ場合、disabled 属性は描画された <button> 要素に含められません。

JavaScript 式の使用

これまで、テンプレートに単純なキーをバインディングしてきました。実際には Vue.js は全てのデータバインディング内部で JavaScript 式を完全にサポートします:

{{ number + 1 }}

{{ ok ? 'YES' : 'NO' }}

{{ message.split('').reverse().join('') }}

<div v-bind:id="'list-' + id"></div>

これらの式は、Vue インスタンスが所有するデータスコープ内で JavaScript として評価されます。制限として、それぞれのバインディングは、単一の式だけ含むことができるというものです。なので、以下は動作しません:

<!-- これは文であり、式ではありません: -->
{{ var a = 1 }}

<!-- フロー制御もいずれも動作しません。三項演算子を使用してください -->
{{ if (ok) { return message } }}

テンプレート式はサンドボックスで、Math や Date といったホワイトリストにあるグローバルオブジェクトだけアクセスできます。テンプレート式内でユーザーが定義したグローバルオブジェクトにアクセスしようとしてはいけません。

ホワイトリストにあるかってどこを見たら確認できるのだろう

ディレクティブ

ディレクティブは v- から始まる特別な属性です。ディレクティブ属性値は、単一の JavaScript 式を期待します(ただし、v-forは例外で、これについては後から説明します)。ディレクティブの仕事は、属性値の式が変化したときに、リアクティブに副作用を DOM に適用することです。イントロダクションで見た例を振り返ってみましょう:

<p v-if="seen">Now you see me</p>

ここでの v-if ディレクティブは seen 式の値が真か否かに基づいて、 <p> 要素を削除/挿入します。

引数

ディレクティブの中には “引数” を取るものもあります。これはディレクティブ名の後にコロンで表記します。例えば、v-bindディレクティブは、リアクティブに HTML 属性を更新します:

<a v-bind:href="url"> ... </a>

ここでの href は v-bind ディレクティブに要素の href 属性に式 url の値を束縛することを教えるための引数です。

v-on ディレクティブの別の例を見てみましょう。これは DOM イベントを受け取ります:

<a v-on:click="doSomething"> ... </a>

ここでの引数は受け取りたいイベント名です。ここからイベントハンドリングの詳細について説明します。

修飾子

修飾子 (Modifier) は、ドットで表記された特別な接尾語で、ディレクティブが特別な方法で束縛されるべきということを示します。例えば、.prevent 修飾子は v-on ディレクティブに、イベントがトリガされた際 event.preventDefault() を呼ぶように伝えます:

<form v-on:submit.prevent="onSubmit"> ... </form>

これらの機能を調べるとき、この後、v-on や v-modelについては、修飾子の他の例を見るでしょう。

省略記法

v- 接頭辞は、テンプレート内の Vue 独自の属性を識別するための目印となっています。これは既存のマークアップに対して、 Vue.js を利用して動的な振る舞いを適用する場合に便利ですが、頻繁に利用されるディレクティブに対しては冗長に感じることがあるでしょう。同時にシングルページアプリケーションを作成するにあたり、全てのテンプレートを Vue.js で管理しているとき、v- 接頭辞を付ける必要性は低いものになるでしょう。したがって、 Vue.js は 2 つの最もよく使われるディレクティブ v-bind と v-on に対して特別な省略記法を提供しています:

v-bind 省略記法

<!-- 完全な構文 -->
<a v-bind:href="url"> ... </a>

<!-- 省略記法 -->
<a :href="url"> ... </a>

v-on 省略記法

<!-- 完全な構文 -->
<a v-on:click="doSomething"> ... </a>

<!-- 省略記法 -->
<a @click="doSomething"> ... </a>

これらは普通の HTML とはちょっと違うように見えるかもしれません。ですが、 : や @ は属性名に利用可能な文字です。すべての Vue.js のサポートしているブラウザで、正しくパースすることができます。加えて、最終的に描画されるマークアップにそれらは現れません。省略記法の構文の利用は完全に任意ですが、後でその使用方法について詳しく学んだ時に便利と感じることでしょう。

これ知らなくて他の人のvue.jsの記事を見ても何をしてるのかよくわからなかったから省略記法と知れて良かったです。

vuejs.orgをただ読んでいくだけ - その3

https://jp.vuejs.org/v2/guide/instance.html <- ここを読みました

https://github.com/okumurakengo/vuejsorg-reading/blob/master/guide/instance.html <- 自分で試したコード

※ vuejs.orgをただ読んで、気になった部分だけをコピペしていくだけの投稿です

Vue インスタンスの作成

全ての Vue アプリケーション は、Vue 関数で新しい Vue インスタンスを作成することによって起動されます。

データとメソッド

Vue インスタンスが作成されると、自身の data オブジェクトの全てのプロパティをリアクティブシステムに追加します。これらのプロパティの値を変更すると、ビューが”反応”し、新しい値に一致するように更新します。

// データオブジェクト
var data = { a: 1 }

// Vue インスタンスにオブジェクトを追加する
var vm = new Vue({
  data: data
})

// インスタンスのプロパティを取得すると、
// 元のデータからそのプロパティが返されます
vm.a == data.a // => true

// プロパティへの代入は、元のデータにも反映されます
vm.a = 2
data.a // => 2

// ... そして、その逆もまたしかりです
data.a = 3
vm.a // => 3

このデータを変更すると、ビューが再レンダリングされます。dataのプロパティは、インスタンスが作成されたときに存在していた場合にのみリアクティブです。 つまり、以下のように新しいプロパティを追加する場合、

vm.b = 'hi'

その後、 b への変更はビューの更新を引き起こさないでしょう。 後でプロパティが必要になることがわかっているならば、空でも存在しない場合でも初期値を設定するだけで済みます。 例:

data: {
  newTodoText: '',
  visitCount: 0,
  hideCompletedTodos: false,
  todos: [],
  error: null
}

初期値にないとあとで変更しようとしても無理だから、初期値に空文字とか0とかとりあえず設定しおけば良い、ということなのか。

これに対する唯一の例外は、既存のプロパティの変更を防ぐ Object.freeze()の使用です。これはリアクティブシステムが変更を 追跡 することができないことも意味します。

var obj = {
  foo: 'bar'
}

Object.freeze(obj)

new Vue({
  el: '#app',
  data: obj
})
<div id="app">
  <p>{{ foo }}</p>
  <!-- これは `foo` を更新しなくなります! -->
  <button v-on:click="foo = 'baz'">Change it</button>
</div>

data プロパティに加えて、Vue インスタンスは、いくつかの便利なプロパティとメソッドを持っています。これらはユーザ定義のプロパティと区別するために、頭に $ が付けられています。 例:

var data = { a: 1 }
var vm = new Vue({
  el: '#example',
  data: data
})

vm.$data === data // => true
vm.$el === document.getElementById('example') // => true

// $watch はインスタンスメソッドです
vm.$watch('a', function (newValue, oldValue) {
   // このコールバックは `vm.a` の値が変わる時に呼ばれます
})

インスタンスライフサイクルフック

各 Vue インスタンスは、生成時に一連の初期化を行います。例えば、データの監視のセットアップやテンプレートのコンパイル、DOM へのインスタンスのマウント、データが変化したときの DOM の更新などがあります。その初期化の過程で、特定の段階でユーザー自身のコードを追加する、いくつかの ライフサイクルフック(lifecycle hooks) と呼ばれる関数を実行します。

例えば、created フックはインスタンスが生成された後にコードを実行したいときに使われます。

new Vue({
  data: {
    a: 1
  },
  created: function () {
    // `this` は vm インスタンスを指します
    console.log('a is: ' + this.a)
  }
})
// => "a is: 1"

この他にもインスタンスのライフサイクルの様々な段階で呼ばれるフックがあります。例えば、mounted、 updated、そして destroyed などがあります。全てのライフサイクルフックは、this が Vue インスタンスを指す形で実行されます。

f:id:okumuraa1:20190105034659p:plain

アロー関数ダメなんだ、知らなかったらハマりそう。

Visual Studio Codeをオシャレにしてみた

参考

vscbui.rocks

marketplace.visualstudio.com


Beautiful UIをVS Codeにインストールした後に、

「Code」>「基本設定」>「設定」 設定ファイルに参考サイトを真似して以下のように設定してみた

{
    "window.zoomLevel": 1,
    "files.associations": {
        "Vagrantfile": "ruby"
    },
    "workbench.colorTheme": "βui - Ayu Dark",
    "editor.fontFamily": "Operator Mono SSM Lig",
    "editor.lineHeight": 25,
    "editor.fontSize": 15,
    "editor.letterSpacing": 1.2
}

BEFORE:

f:id:okumuraa1:20180510211235p:plain

↓ ↓ ↓ ↓ ↓

AFTER:

f:id:okumuraa1:20180510211040p:plain

オシャレになった!!?