Vue シングルファイルコンポーネントの実装

Vue シングルファイルコンポーネントの実装

最近、vue について読みました。これまで基本的に見落としていた単一ファイル コンポーネントを見つけました。 Vue.js の単一ファイル コンポーネントを使用すると、コンポーネントのすべてのコンテンツを 1 つのファイルで定義できます。つまり、ページまたはコンポーネントをバンドルしたい場合は、Vue のこの単一ファイル コンポーネントでそれを行うことができます。 Vue の公式 Web サイトには、「多くの Vue プロジェクトでは、app.component を使用してグローバル コンポーネントを定義し、app.mount('#app') を使用して各ページのコンテナー要素を指定します」と記載されています。ここでのコンポーネントは比較的単純ですが、このアプローチはより複雑なプロジェクトでは機能しません。理由は次のとおりです。

  • グローバル定義では、各コンポーネント内の名前が繰り返されないように強制します。
  • 文字列テンプレートには構文の強調表示がなく、HTML に複数行がある場合は見苦しい \ が必要になります。
  • CSS がサポートされていないということは、HTML と JavaScript がコンポーネント化されるときに CSS が明らかに省略されることを意味します。
  • ビルドステップなし HTMLとES5 JavaScriptに制限されますが、Pugなどのプリプロセッサは制限されません
  • (旧称 Jade) と Babel。

これらすべては、.vue 拡張子を持つ単一ファイル コンポーネントと、webpack や Browserify などのビルド ツールを使用することで解決できます。
では、Vue プロジェクトで単一ファイル コンポーネントを作成するにはどうすればよいでしょうか?

建てる

npm インストール -D @vue/compiler-sfc

上記のコードをコンソールに入力すると、フォルダーと別の json ファイルが表示されます。次のように:

ここに画像の説明を挿入

単一ファイル コンポーネントを構築する場合は、自分でファイルを作成する必要があります。同時に、webpack についてある程度理解している必要があります。
たとえば、必要な依存関係のいくつかを自分でインストールします。たとえば、css-loader、css プリコンパイル プロセッサなどです。プロジェクトでは vue ファイルを解析する必要があるため、vue-loader が必要です。

これらのファイルは実際には vue のシンプルなバージョンです。たとえば、hello.vueファイルの簡単なバージョンは次のようになります。

ここに画像の説明を挿入

このことから、3 つの部分で構成されていることがわかります。テンプレート部分は必須であり、他の 2 つの部分、スタイルとスクリプトは無視できます。
スクリプトを使用すると、ページ js を Vue と完全に統合することができ、スタイルではプリプロセッサを使用して簡潔でより機能的なコンポーネントを構築できます。 (この単一ファイルコンポーネントは、元のフロントエンド開発のHTMLドキュメントと非常によく似ています。独自のスタイルタグとスクリプトタグがありますが、プレゼンテーション層ではテンプレートタグを使用します。シンプルな方法のため、強力な階層化コンポーネント(content/template:、presentation:

ここに画像の説明を挿入

異なるモジュールを分割することを好む人もいますが、これは Vue のドキュメントで「関心の分離」と呼ばれています。問題ありません。これらのドキュメントを分割し、CSS と JS を別のファイルに分離してから、コンポーネントにインポートできます。次のように:

<!-- my-component.vue -->
<テンプレート>
  <div>これは事前にコンパイルされます</div>
</テンプレート>
<script src="./my-component.js"></script>
<style src="./my-component.css"></style>

プロジェクトディレクトリは次のとおりです。

ここに画像の説明を挿入

その中には、index.html

<!DOCTYPE html>
<html lang="ja">
  <ヘッド>
    <メタ文字セット="utf-8" />
    <title>SFC を使用した Vue のシンプルな Todo アプリ</title>
    <リンク
      rel="スタイルシート"
      href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css" rel="外部nofollow" rel="外部nofollow" 
    />
    <link rel="スタイルシート" href="/dist/main.css" rel="外部 nofollow" rel="外部 nofollow" />
  </head>
  <本文>
    <div id="アプリ"></div>
    <script src="/dist/main.js"></script>
  </本文>
</html>

パッケージ.json

{
    「プライベート」:true、
    「スクリプト」: {
      "dev": "webpack-dev-server",
      "ビルド": "webpack --env.prod"
    },
    「依存関係」: {
      "vue": "^3.1.1"
    },
    「devDependencies」: {
      "@vue/コンパイラ-sfc": "^3.1.1",
      "css-loader": "^3.5.2",
      "ファイルローダー": "^6.0.0",
      "ミニCSS抽出プラグイン": "^0.9.0",
      "スタイラス": "^0.54.7",
      "スタイラスローダー": "^3.0.2",
      "url-loader": "^4.1.0",
      "vue-loader": "^16.0.0-alpha.3",
      "vue-style-loader": "^4.1.2",
      "ウェブパック": "^4.42.1",
      "webpack-cli": "^3.3.11",
      "webpack-dev-server": "^3.10.3"
    },
    「キーワード」: ["todo", "vue"],
    "名前": "単一ファイルコンポーネントを持つ vue-todo-list アプリ",
    「説明」: 「SFC (Single File Component) をサポートする Vue で記述されたシンプルな ToDo リスト アプリケーションです。」
  }

config.js は、

定数パス = require("パス");
const { VueLoaderPlugin } = require("vue-loader");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

モジュール.exports = (env = {}) => ({
  モード: env.prod ? "production" : "development",
  開発ツール: env.prod ? "ソースマップ" : "cheap-module-eval-source-map",
  エントリー: [
    env.prod ? false : require.resolve(`webpack-dev-server/client`),
    path.resolve(__dirname, "./src/main.js")
  ].filter(ブール値)、
  出力: {
    パス: path.resolve(__dirname, "./dist"),
    パブリックパス: "/dist/"
  },
  解決する: {
    エイリアス: {
      // これは技術的には必要ありません。バンドラのデフォルトの`vue`エントリは
      // は単純な `export * from '@vue/runtime-dom` です。しかし、これ
      // 余分な再エクスポートにより、webpack が常にモジュールを無効にする原因になります
      // 最初の HMR 更新時にページが再読み込みされます。
      vue: "@vue/runtime-dom"
    }
  },
  モジュール: {
    ルール:
      {
        テスト: /\.vue$/,
        使用: "vue-loader"
      },
      {
        テスト: /\.png$/,
        使用: {
          ローダー: "url-loader",
          オプション: { 制限: 8192 }
        }
      },
      {
        テスト: /\.css$/,
        使用: [
          {
            ローダー: MiniCssExtractPlugin.loader、
            オプション: { hmr: !env.prod }
          },
          「CSSローダー」
        ]
      },
      {
        テスト: /\.stylus$/,
        使用法: ["vue-style-loader", "css-loader", "stylus-loader"]
      },
      {
        テスト: /\.pug$/,
        ローダー: "pug-plain-loader"
      }
    ]
  },
  プラグイン: [
    新しい VueLoaderPlugin()、
    新しい MiniCssExtractPlugin({
      ファイル名: "[名前].css"
    })
  ]、
  開発サーバー: {
    インライン: true、
    ホット:本当、
    統計:「最小」、
    コンテンツベース:__dirname、
    オーバーレイ: true、
    injectClient: false、
    ホストチェックを無効にする: true
  }
});

テスト.html

<!DOCTYPE html>
<html lang="ja">
  <ヘッド>
    <メタ文字セット="utf-8" />
    <title>SFC を使用した Vue のシンプルな Todo アプリ</title>
    <リンク
      rel="スタイルシート"
      href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css" rel="外部nofollow" rel="外部nofollow" 
    />
    <link rel="スタイルシート" href="/dist/main.css" rel="外部 nofollow" rel="外部 nofollow" />
  </head>
  <本文>
    <div id="app222">テストページ</div>
    <script src="/dist/main.js"></script>
  </本文>
</html>

srcフォルダにはApp.vue、main.js、TodoItem.vueの3つのファイルがあります。

場所: App.vue

<テンプレート>
  <div class="wrapper">
    <h1>私のToDoリスト</h1>
    <form @submit.prevent="Todo を追加">
      <input type="text" name="todo-text" v-model="newTodoText" placeholder="新しい ToDo">
    </フォーム>
    <ul v-if="todos.length">
      <TodoItem v-for="todos 内の todo" :key="todo.id" :todo="todo" @remove="removeTodo"/>
    </ul>
    <p class="none" v-else>リストに何も残っていません。上記の入力に新しい ToDo を追加してください。</p>
  </div>
</テンプレート>

<スクリプト>
「./TodoItem.vue」からTodoItemをインポートします。

次のTodoId = 1 とします

const createTodo = テキスト => ({
  文章、
  ID: nextTodoId++
})

エクスポートデフォルト{
  コンポーネント:
    やることリスト
  },

  データ() {
    戻る {
      すべて:
        createTodo("Vue を学ぶ"),
        createTodo("単一ファイルコンポーネントについて学ぶ"),
        createTodo("恋に落ちる❤️")
      ]、

      新しいTodoテキスト: ""
    }
  },

  メソッド: {
    追加ToDo() {
      const トリムされたテキスト = this.newTodoText.trim()

      if (トリムされたテキスト) {
        this.todos.push(createTodo(トリムされたテキスト))
      }

      this.newTodoText = ""
    },

    削除Todo(アイテム) {
      this.todos = this.todos.filter(todo => todo !== 項目)
    }
  }
}
</スクリプト>

<style lang="スタイラス">
*、*::前、*::後 
  ボックスサイズ ボーダーボックス

html、本文
  フォント 16px/1.2 BlinkMacSystemFont、-apple-system、「Segoe UI」、Roboto、Helvetica、Arial、sans-serif
  パディング 10px

.ラッパー
  幅 75%
  マージン 0 自動

形状
  下マージン 20px

入力[type="text"]
  幅 100%
  パディング 10px
  境界線 1px 実線 #777

ウル、リ
  マージン 0
  パディング 0

p.なし
  色 #888
  フォントサイズ 小さい
</スタイル>

メイン.js

'vue' から {createApp} をインポートします。
'./App.vue' からアプリをインポートします。

createApp(App).mount('#app')

TodoItem.vue

<テンプレート>
  <li>
    <span>{{ todo.text }}</span>
    <button @click.prevent="$emit('remove', todo)">削除</button>
  </li>
</テンプレート>

<スクリプト>
エクスポートデフォルト{
  小道具: {
    やること: {
      必須: true、
      タイプ: オブジェクト
    }
  }
}
</スクリプト>


<style lang="stylus" スコープ>
李
  ディスプレイフレックス
  マージン 5px 0

  スパン
    フレックス1
  
  ボタン
    境界線 1px 実線 オレンジ
    背景オレンジ 
    色 白
    フォントサイズ 0.8rem
    パディング 2px 4px
    カーソルポインタ

    &:ホバー
      境界線の色 #ff8100
      背景 #ff8100
</スタイル>

注意<br /> webpack の使い方がわからない場合は、公式サイトの指示に従い、vue scaffolding を使用して基本的なツールをインストールすることをお勧めします。
または、私が提供した pakage.json をプロジェクトに配置し、npm install を実行して最も基本的な環境をインストールしてから、npm run dev を通じてローカル開発を行うこともできます。

実際のところ、この単一ファイル コンポーネントはすでにあまり役に立たないと思います。純粋な JS プロジェクトで、使用されているライブラリやコンポーネントが非常に古い場合を除き、Vue に精通していれば、この単一ファイル コンポーネントを使用して新しい機能を開発すると良い効果が得られます。同時に、webpack を学ぶことをお勧めします。 bable について何も知らない状態で、node を通じてプロジェクトを開始しようとします。

実際、1 つのファイルを使用して html/css/JavaScript をレイヤーで管理し、1 つのファイルに統合すると、プロジェクトがより整理され、標準化されたように見えるようになります。 jq の時代では、CSS は HTML と混在することが多く、単純なクリック イベントではそれらを分離する必要があります。このエクスペリエンスは、確かに「階層化管理」ほど明確ではありません。

参考文献:
1. https://v3.cn.vuejs.org/guide/single-file-component.html#%E5%9C%A8%E7%BA%BF%E6%BC%94%E7%A4%BA
2. https://www.cnblogs.com/houxianzhou/p/14510450.html

これで、vue シングルファイル コンポーネントの実装に関するこの記事は終了です。vue シングルファイル コンポーネントに関するより関連性の高いコンテンツについては、123WORDPRESS.COM で過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Vuejs 単一ファイルコンポーネントの例の詳細な説明
  • vuejs 単一ファイルコンポーネント.vue ファイルの使用
  • Vue 単一ファイルコンポーネントのスタイル読み込み問題を解決する
  • Vue シングルファイルコンポーネントの使い方
  • Vuejs でスタイル付きの単一ファイルコンポーネントを実装する新しい方法
  • Vue の単一ファイルコンポーネントを記述する 3 つの方法の詳細な説明
  • Vue 単一ファイル コンポーネントが $refs を取得できない問題

<<:  Linux環境でのDockerインストールチュートリアル

>>:  MySQL 8.0.15 winx64 のインストールと設定方法のグラフィックチュートリアル (Windows の場合)

推薦する

Ubuntu 18でターミナルを美しいコマンドラインプロンプトに変更する方法

VMware と Ubuntu を再インストールしましたが、コマンドラインプロンプトが単調すぎて美し...

JS を使用して HTML で回転するクリスマスツリーを実装する

<!DOCTYPE ヘムル パブリック> <html> <ヘッド&g...

MySQL ログイン エラーを解決する: 'ユーザー 'root'@'localhost' へのアクセスが拒否されました

まず、コマンドラインまたはワークベンチを使用して MySQL にログインできず、「ユーザー '...

JavaScript のカンマ式が含まれている場合について

JavaScript の if ステートメントで英語のカンマ「,」が表示されることがあります。これは...

初心者のためのWebサイト構築入門 ③ エイリアス(CNAME)レコードとURL転送

①. エイリアス(CNAME)レコードの使用方法:前回の投稿のドメイン名解決では、A レコードの解...

HTML テーブルタグチュートリアル (44): テーブルヘッダータグ

<br />ソース コード内で表の構造を明確に区別するために、HTML 言語では、表のヘ...

フォームのmethod=post/getの違い

フォームは、get と post の 2 つのデータ転送方法を提供します。どちらもデータを送信する方...

vue.config.js からプロジェクト最適化までの vue2.x 構成

目次序文vue.config.js 構成オプションパッケージサイズを縮小するためのパッケージの最適化...

React Nativeプロジェクトフレームワークの構築経験

React Native は、2015 年 4 月に Facebook によってオープンソース化され...

MySQLマスタースレーブ遅延現象と原理の詳細な分析

1. 現象早朝、オンライン テーブルにインデックスが追加されました。テーブル内のデータ量が大きすぎた...

HTML テーブル マウス ドラッグ ソート機能

効果画像: 1. ファイルをインポートする<script src="js/jquer...

JavaScript の高度なプログラミングの基本参照型

目次1. 日付2. 正規表現3. オリジナルパッケージタイプ序文:参照値(オブジェクト)は、 Dat...

HTML チュートリアル、optgroup 要素の理解

カテゴリ選択を選択します。テストの結果、IE と FF はこの要素を適切にサポートできることがわかり...

MySQL の時間設定に関する考慮事項の詳細な要約

時間は本当に存在するのでしょうか?時間は人間が考え出した概念に過ぎず、物事の変化を測る基準に過ぎない...