機能表示方法を説明(スケルトン、スタイル) 実行方法を説明(データ取得、ステータス更新) ストアを直接使用いいえ それは データソースですprops ストアの状態を聞く データを変更するpropsからコールバック関数を呼び出す ストアにアクションをディスパッチする 来自 Redux 文档 https://user-gold-cdn.xitu.io/2018/5/2/1631f590aa5512b7
用 容器组件/展示组件 模式改造上面的例子
针对最初的例子,如何快速按照这种模式来划分组件呢?我们主要针对 CommentList.vue 进行拆分,首先是基本的概要设计:
概要设计
展示组件
components/CommentListNew.vue 这是一个新的评论展示组件,用于展示评论 comments: Array prop 接收以 { id, author, body } 形式显示的 comment 项数组。 fetch() 接收更新评论数据的方法 展示组件只定义外观并不关心数据来源和如何改变。传入什么就渲染什么。
comments、fetch 等这些 props 并不关心背后是否是由 Vuex 提供的,你可以使用 Vuex,或者其他状态管理库,甚至是一个 EventBus,都可以复用这些展示组件。
同时,可以利用 props 的类型和验证来约束传入的内容,比如验证传入的 comments 是否是一个含有指定字段的对象,这在之前混合组件的情况是下是没有的,提高了代码的健壮性。
容器组件
containers/CommentListContainer.vue 将 CommentListNew 组件连接到 store 容器组件可以将 store 对应的 state 或者 action 等封装传入展示组件。
编码实现
Talk is cheap, show me the code! components/CommentListNew.vue
这个文件不再依赖 store,改为从 props 传递。
值得注意到是 comments 和 fetch 分别定义了 type 、default 和 validator,用以定义和验证 props。
<template>
<ul>
<li v-for="comment in comments"
:key="comment.id"
>
{{comment.body}}—{{comment.author}}
</li>
</ul>
</template>
<script>
export default {
name: 'CommentListNew',
props: {
comments: {
type: Array,
default () {
return []
},
validator (comments) {
return comments.every(comment =>
'body' in comment &&
'author' in comment &&
'id' in comment
)
}
},
fetch: {
type: Function,
default: () => {}
}
},
mounted () {
this.fetch()
}
}
</script> ログイン後にコピー
containers/CommentListContainer.vue
容器组件的职责
通过 computed 来获取到状态更新,传递给展示组件
通过 methods 定义回调函数,回调函数内部调用 store 的 dispatch 方法,传递给展示组件
<template>
<CommentList
:comments="comments"
:fetch="fetchComments"
></CommentList>
</template>
<script>
import CommentList from '@/components/CommentListNew'
export default {
name: 'CommentListContainer',
components: {
CommentList
},
computed: {
comments () {
return this.$store.state.comments
}
},
methods: {
fetchComments () {
return this.$store.dispatch('fetchComments')
}
}
}
</script> ログイン後にコピー
使用 @xunlei/vuex-connector 实现容器组件
上面演示的容器组件的代码非常简单,实际上如果直接投入生产环境,会产生一些问题。
手动实现容器组件存在的不足
代码比较繁琐
在上面的例子中,每次传递一个 state 都要定义一个 computed,每传递一个 mutation 或者 action 都需要定一个方法,而且还要注意这个方法的参数要透传过去,同时还要处理返回值,比如异步的 action 需要返回 promise 的时候,定义的这个 method 也得把 action 的返回值返回出去。
无法透传其他 props 给展示组件
比如展示组件新增了一个 prop 叫做 type,可以传递一个评论的类型,用来区分是热门还是最新,如果用上面的容器实现方式,首先需要在容器组件这层新增一个 prop 叫做 type 接受外部传来的参数,然后在展示组件内部同样定义一个 叫做 type 的 prop,然后才能传递下去。
需要透传的 prop 必须定义两遍,增加了维护的成本。
<CommentListContainer type="热门"></CommentListContainer>
<CommentList
:fetch="fetchComments"
:comments="comments"
:type="type"
></CommentList> ログイン後にコピー
容器组件无法统一进行优化
每一个手动实现的容器组件实质上代码逻辑非常近似,但是没有经过同一层封装,如果目前实现的容器组件存在一些性能优化的地方,需要每个容器组件都进行统一的修改。
无法控制展示组件不去获取 store
因为容器组件是通过 this.$store 获取 store 的,展示组件内部实质上也可以直接跟 store 通信,如果没有约束,很难统一要求展示组件不得直接和 store 通信。
使用 @xunlei/vuex-connector
@xunlei/vuex-connector 借鉴了 react redux 的 connect 方法,在 vuex 基础上进行的开发。
有以下几个特点:
代码非常简洁
下面是上面例子中手动实现的容器组件的改造版本:
comonents/ConnectCommentListContainer.vue
<script>
import CommentListNew from '@/components/CommentListNew'
import { connector } from '@/store'
export default connector.connect({
mapStateToProps: {
comments: (state) => state.comments
},
mapActionToProps: {
fetch: 'fetchComments'
}
})(CommentListNew)
</script> ログイン後にコピー
通过 connector 的 connnect 方法,传入要映射的配置,支持 mapStateToProps, mapGettersToProps, mapDispatchToProps, mapCommitToProps 这四种,每一种都是只要配置一个简单的 map 函数,或者字符串即可。
然后在返回的函数中传入要连接的展示组件,是不是非常的简洁,同时借鉴了 redux 优雅的函数式风格。
问题来了,connector 是什么?
connector 实际上是一个能获取到 store 实例的连接器,可以在初始化 vuex store 的时候进行初始化。
import Vue from 'vue';
import Vuex from 'vuex';
import VuexConnector from '@xunlei/vuex-connector';
Vue.use(Vuex);
const store = new Vuex.Store({
// your store
});
export const connector = new VuexConnector(store);
export default store; ログイン後にコピー
一个 Vue 程序实际上只需要初始化一次即可。
支持透传其他 props 给展示组件
VuexConnector 实现的时候采用了函数式组件( functional: true )
函数式组件是无状态 (没有响应式数据),无实例 (没有 this 上下文)。
在作为包装组件时函数式组件非常有用,比如,当你需要做这些时:
程序化地在多个组件中选择一个
在将 children, props, data 传递给子组件之前操作它们。
另外,函数式组件只是一个函数,所以渲染开销也低很多。然而,对持久化实例的缺乏也意味着函数式组件不会出现在 Vue devtools 的组件树里。
因此需要透传的 props 可以直接透传,需要通过 map 方式从 store 里进行获取的 props 直接会根据配置生成。
统一封装方便后续统一优化
VuexConnector.connect 方法将本来需要重复做的事情进行了抽象,也带来了后期进行统一优化和升级的便利。
可以控制展示组件无法直接与 store 通信
VuexConnector 不依赖 this.$store,而是依赖初始化传入的 store 实例,容器组件可以用 connect 将展示组件与 store 进行连接。
由于不依赖 this.$store,我们在程序入口 new Vue 的时候,就不需要传入 store 实例了。
比如,之前我们是通过下面的方式进行初始化:
import Vue from 'vue';
import App from './App';
import store from './store';
new Vue({
el: '#app',
components: {App},
template: '<App/>',
store,
}); ログイン後にコピー
使用了 VuexConnector 之后,在最初 new Vue 的时候就不需要也最好不要传递 store 了,这样就避免了 this.$store 泛滥导致代码耦合的问题。
引入容器组件/展示组件模式带来的好处
可复用性
容器组件/展示组件的划分,采用了单一职责原则的设计模式,容器组件专门负责和 store 通信,展示组件只负责展示,解除了组件的耦合,可以带来更好的可复用性。
健壮性
由于展示组件和容器组件是通过 prop 这种接口来连接,可以利用 props 的校验来增强代码的可靠性,混合的组件就没有这种好处。
另外对 props 的校验可以采取一下几种方式:
Vue 组件 props 验证
可以验证 props 的类型,默认可以校验是否是以下类型:
String
Number
Boolean
Function
Object
Array
Symbol
如果你的 props 是类的一个实例,type 也可以是一个自定义构造器函数,使用 instanceof 检测。
如果还是不满足需求,可以自定义验证函数:
// 自定义验证函数
propF: {
validator: function (value) {
return value > 10
}
} ログイン後にコピー
TypeScript 类型系统
Vue 组件 props 验证对于对象或者其他复杂的类型校验还是不太友好,所以很多人也推荐大家的 props 尽量采取简单类型,不过如果你有在用 TypeScript 开发 Vue 应用,可以利用 TypeScript 静态类型检查来声明你的 props 。
@Component
export default class Hello extends Vue {
@Prop
info: IHelloInfo; // 这里可以用你自定义的 interface
} ログイン後にコピー
可测试性
由于组件做的事情更少了,使得测试也会变得容易。
容器组件不用关心 UI 的展示,只关心数据和更新。
展示组件只是呈现传入的 props ,写单元测试的时候也非常容易 mock 数据层。
引入容器组件/展示组件模式带来的限制
学习和开发成本
因为容器组件/展示组件的拆分,初期会增加一些学习成本,不过当你看完这篇文章,基本上也就入门了。
在开发的时候,由于需要封装一个容器,包装一些数据和接口给展示组件,会增加一些工作量, @xunlei/vuex-connector 通过配置的方式可以减轻不少你的工作量。
另外,在展示组件内对 props 的声明也会带来少量的工作。
总体来说,引入容器组件/展示组件模式投入产出比还是比较值得的。
相关推荐:
Vue利用canvas实现移动端手写板的方法
以上がVue にコンテナ コンポーネントと表示コンポーネントを導入する React に関する詳細なチュートリアルの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
React フロントエンドとバックエンドの分離ガイド: フロントエンドとバックエンドの分離と独立したデプロイメントを実現する方法
Sep 28, 2023 am 10:48 AM
React フロントエンドとバックエンドの分離ガイド: フロントエンドとバックエンドの分離と独立したデプロイメントを実現する方法、特定のコード例が必要です 今日の Web 開発環境では、フロントエンドとバックエンドの分離がトレンドになっています。フロントエンド コードとバックエンド コードを分離することで、開発作業がより柔軟かつ効率的になり、チームのコラボレーションが促進されます。この記事では、React を使用してフロントエンドとバックエンドの分離を実現し、それによって分離と独立したデプロイの目標を達成する方法を紹介します。まず、フロントエンドとバックエンドの分離とは何かを理解する必要があります。従来の Web 開発モデルでは、フロントエンドとバックエンドが結合されています。
React と Flask を使用してシンプルで使いやすい Web アプリケーションを構築する方法
Sep 27, 2023 am 11:09 AM
React と Flask を使用してシンプルで使いやすい Web アプリケーションを構築する方法 はじめに: インターネットの発展に伴い、Web アプリケーションのニーズはますます多様化および複雑化しています。使いやすさとパフォーマンスに対するユーザーの要件を満たすために、最新のテクノロジー スタックを使用してネットワーク アプリケーションを構築することがますます重要になっています。 React と Flask は、フロントエンドおよびバックエンド開発用の 2 つの非常に人気のあるフレームワークであり、うまく連携してシンプルで使いやすい Web アプリケーションを構築します。この記事では、React と Flask を活用する方法について詳しく説明します。
Windows 10 旧バージョンコンポーネント DirectPlay のインストール方法
Dec 28, 2023 pm 03:43 PM
win10で一部のゲームをプレイすると、画面がフリーズしたり画面がぼやけるなどの不具合が多くのユーザーに発生しますが、現時点ではダイレクトプレイ機能をオンにすることで問題を解決でき、機能の操作方法も非常に簡単です。 win10 の古いコンポーネントである Directplay をインストールする方法 1. 検索ボックスに「コントロール パネル」と入力して開きます 2. 表示方法として大きなアイコンを選択します 3. 「プログラムと機能」を見つけます 4. 左側をクリックして有効にするか、 Win 機能をオフにする 5. ここで古いバージョンを選択します チェックボックスをオンにするだけです
React と RabbitMQ を使用して信頼性の高いメッセージング アプリを構築する方法
Sep 28, 2023 pm 08:24 PM
React と RabbitMQ を使用して信頼性の高いメッセージング アプリケーションを構築する方法 はじめに: 最新のアプリケーションは、リアルタイム更新やデータ同期などの機能を実現するために、信頼性の高いメッセージングをサポートする必要があります。 React はユーザー インターフェイスを構築するための人気のある JavaScript ライブラリであり、RabbitMQ は信頼性の高いメッセージング ミドルウェアです。この記事では、React と RabbitMQ を組み合わせて信頼性の高いメッセージング アプリケーションを構築する方法を紹介し、具体的なコード例を示します。 RabbitMQ の概要:
React Router ユーザーガイド: フロントエンドルーティング制御の実装方法
Sep 29, 2023 pm 05:45 PM
ReactRouter ユーザーガイド: フロントエンドルーティング制御の実装方法 シングルページアプリケーションの人気に伴い、フロントエンドルーティングは無視できない重要な部分になりました。 React エコシステムで最も人気のあるルーティング ライブラリとして、ReactRouter は豊富な機能と使いやすい API を提供し、フロントエンド ルーティングの実装を非常にシンプルかつ柔軟にします。この記事では、ReactRouter の使用方法と具体的なコード例を紹介します。 ReactRouter を最初にインストールするには、次のものが必要です
React と Apache Kafka を使用してリアルタイム データ処理アプリケーションを構築する方法
Sep 27, 2023 pm 02:25 PM
React と Apache Kafka を使用してリアルタイム データ処理アプリケーションを構築する方法 はじめに: ビッグ データとリアルタイム データ処理の台頭により、リアルタイム データ処理アプリケーションの構築が多くの開発者の追求となっています。人気のあるフロントエンド フレームワークである React と、高性能分散メッセージング システムである Apache Kafka を組み合わせることで、リアルタイム データ処理アプリケーションを構築できます。この記事では、React と Apache Kafka を使用してリアルタイム データ処理アプリケーションを構築する方法を紹介します。
PHP、Vue、React: 最適なフロントエンド フレームワークを選択するには?
Mar 15, 2024 pm 05:48 PM
PHP、Vue、React: 最適なフロントエンド フレームワークを選択するには?インターネット技術の継続的な発展に伴い、フロントエンド フレームワークは Web 開発において重要な役割を果たしています。 PHP、Vue、React は 3 つの代表的なフロントエンド フレームワークであり、それぞれに独自の特徴と利点があります。使用するフロントエンド フレームワークを選択するとき、開発者はプロジェクトのニーズ、チームのスキル、個人の好みに基づいて情報に基づいた決定を下す必要があります。この記事では、PHP、Vue、React の 3 つのフロントエンド フレームワークの特徴と用途を比較します。
Angular コンポーネントとその表示プロパティ: 非ブロックのデフォルト値について
Mar 15, 2024 pm 04:51 PM
Angular フレームワークのコンポーネントのデフォルトの表示動作は、ブロックレベルの要素ではありません。この設計の選択により、コンポーネント スタイルのカプセル化が促進され、開発者が各コンポーネントの表示方法を意識的に定義することが促進されます。 CSS プロパティの表示を明示的に設定することで、Angular コンポーネントの表示を完全に制御して、目的のレイアウトと応答性を実現できます。
See all articles