1674928680
Firebase for Vue made easy!
ref()
You can follow the progress and future plans on the Roadmap issue.
VueFire requires the firebase
package to be installed as well as vuefire
:
npm install vuefire firebase
Author: Vuejs
Source Code: https://github.com/vuejs/vuefire
License: MIT license
1674884580
Typescript/ES7 Decorators to make Vuex modules a breeze
npm install -D vuex-module-decorators
NOTE This is not necessary for
vue-cli@3
projects, since@vue/babel-preset-app
already includes this plugin
babel-plugin-transform-decorators
experimentalDecorators
to trueimportHelpers: true
in tsconfig.json
emitHelpers: true
in tsconfig.json
target: es5
NOTE Since version
0.9.3
we distribute as ES5, so this section is applicable only to v0.9.2 and below
This package generates code in es2015
format. If your Vue project targets ES6 or ES2015 then you need not do anything. But in case your project uses es5
target (to support old browsers), then you need to tell Vue CLI / Babel to transpile this package.
// in your vue.config.js
module.exports = {
/* ... other settings */
transpileDependencies: ['vuex-module-decorators']
}
Remember how vuex modules used to be made ?
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
Well not anymore. Now you get better syntax. Inspired by vue-class-component
import { Module, VuexModule, Mutation, Action } from 'vuex-module-decorators'
@Module
export default class Counter2 extends VuexModule {
count = 0
@Mutation
increment(delta: number) {
this.count += delta
}
@Mutation
decrement(delta: number) {
this.count -= delta
}
// action 'incr' commits mutation 'increment' when done with return value as payload
@Action({ commit: 'increment' })
incr() {
return 5
}
// action 'decr' commits mutation 'decrement' when done with return value as payload
@Action({ commit: 'decrement' })
decr() {
return 5
}
}
Want to see something even better ?
import { Module, VuexModule, MutationAction } from 'vuex-module-decorators'
import { ConferencesEntity, EventsEntity } from '@/models/definitions'
@Module
export default class HGAPIModule extends VuexModule {
conferences: Array<ConferencesEntity> = []
events: Array<EventsEntity> = []
// 'events' and 'conferences' are replaced by returned object
// whose shape must be `{events: [...], conferences: [...] }`
@MutationAction({ mutate: ['events', 'conferences'] })
async fetchAll() {
const response: Response = await getJSON('https://hasgeek.github.io/events/api/events.json')
return response
}
}
@Module
class MyModule extends VuexModule {
wheels = 2
@Mutation
incrWheels(extra) {
this.wheels += extra
}
get axles() {
return this.wheels / 2
}
}
this is turned into the equivalent
const module = {
state: { wheels: 2 },
mutations: {
incrWheels(state, extra) {
state.wheels += extra
}
},
getters: {
axles: (state) => state.wheels / 2
}
}
Use the modules just like you would earlier
import Vue from 'nativescript-vue'
import Vuex, { Module } from 'vuex'
import counter from './modules/Counter2'
import hgapi from './modules/HGAPIModule'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {},
modules: {
counter,
hgapi
}
})
If you need to support module reuse or to use modules with NuxtJS, you can have a state factory function generated instead of a static state object instance by using stateFactory
option to @Module
, like so:
@Module({ stateFactory: true })
class MyModule extends VuexModule {
wheels = 2
@Mutation
incrWheels(extra) {
this.wheels += extra
}
get axles() {
return this.wheels / 2
}
}
this is turned into the equivalent
const module = {
state() {
return { wheels: 2 }
},
mutations: {
incrWheels(state, extra) {
state.wheels += extra
}
},
getters: {
axles: (state) => state.wheels / 2
}
}
Vuex allows us to register modules into store at runtime after store is constructed. We can do the following to create dynamic modules
interface StoreType {
mm: MyModule
}
// Declare empty store first
const store = new Vuex.Store<StoreType>({})
// Create module later in your code (it will register itself automatically)
// In the decorator we pass the store object into which module is injected
// NOTE: When you set dynamic true, make sure you give module a name
@Module({ dynamic: true, store: store, name: 'mm' })
class MyModule extends VuexModule {
count = 0
@Mutation
incrCount(delta) {
this.count += delta
}
}
If you would like to preserve the state e.g when loading in the state from vuex-persist
...
-- @Module({ dynamic: true, store: store, name: 'mm' })
++ @Module({ dynamic: true, store: store, name: 'mm', preserveState: true })
class MyModule extends VuexModule {
...
Or when it doesn't have a initial state and you load the state from the localStorage
...
-- @Module({ dynamic: true, store: store, name: 'mm' })
++ @Module({ dynamic: true, store: store, name: 'mm', preserveState: localStorage.getItem('vuex') !== null })
class MyModule extends VuexModule {
...
There are many possible ways to construct your modules. Here is one way for drop-in use with NuxtJS (you simply need to add your modules to ~/utils/store-accessor.ts
and then just import the modules from ~/store
):
~/store/index.ts
:
import { Store } from 'vuex'
import { initialiseStores } from '~/utils/store-accessor'
const initializer = (store: Store<any>) => initialiseStores(store)
export const plugins = [initializer]
export * from '~/utils/store-accessor'
~/utils/store-accessor.ts
:
import { Store } from 'vuex'
import { getModule } from 'vuex-module-decorators'
import example from '~/store/example'
let exampleStore: example
function initialiseStores(store: Store<any>): void {
exampleStore = getModule(example, store)
}
export { initialiseStores, exampleStore }
Now you can access stores in a type-safe way by doing the following from a component or page - no extra initialization required.
import { exampleStore } from '~/store'
...
someMethod() {
return exampleStore.exampleGetter
}
When SSR is involved the store is recreated on each request. Every time the module is accessed using getModule
function the current store instance must be provided and the module must be manually registered to the root store modules
// store/modules/MyStoreModule.ts
import { Module, VuexModule, Mutation } from 'vuex-module-decorators'
@Module({
name: 'modules/MyStoreModule',
namespaced: true,
stateFactory: true,
})
export default class MyStoreModule extends VuexModule {
public test: string = 'initial'
@Mutation
public setTest(val: string) {
this.test = val
}
}
// store/index.ts
import Vuex from 'vuex'
import MyStoreModule from '~/store/modules/MyStoreModule'
export function createStore() {
return new Vuex.Store({
modules: {
MyStoreModule,
}
})
}
// components/Random.tsx
import { Component, Vue } from 'vue-property-decorator';
import { getModule } from 'vuex-module-decorators';
import MyStoreModule from '~/store/modules/MyStoreModule'
@Component
export default class extends Vue {
public created() {
const MyModuleInstance = getModule(MyStoreModule, this.$store);
// Do stuff with module
MyModuleInstance.setTest('random')
}
}
There is a global configuration object that can be used to set options across the whole module:
import { config } from 'vuex-module-decorators'
// Set rawError to true by default on all @Action decorators
config.rawError = true
Detailed Guide: https://championswimmer.in/vuex-module-decorators/
While I have a day job and I really maintain open source libraries for fun, any sponsors are extremely graciously thanked for their contributions, and goes a long way 😇 ❤️
There are major type-checking changes (could be breaking) in v0.9.7
There are major usage improvements (non backwards compatible) in 0.8.0
Please check CHANGELOG
Read the rest of the README to figure out how to use, or if you readily want to jump into a production codebase and see how this is used, you can check out -
Author: Championswimmer
Source Code: https://github.com/championswimmer/vuex-module-decorators
License: MIT license
1673420357
In this video we will use free third party API and build recipe and meal search application using Vue.js.
By building this application we will learn how to interact with API, how to define parent and child routes in Vue.js, How to define layouts, how to create scalable file and folder structure, how to use Vue composition API and many other important things.
For building this Interface we will use Tailwind css.
Timecodes
--------------------
00:00:00 - Intro & Demo
00:02:21 - What you will learn?
00:03:11 - Create Vue.js app
00:07:20 - Add Tailwindcss
00:09:15 - Add Vue Router and configure routes
00:14:40 - Install Vuex and create store
00:21:06 - Create Home Page
00:31:20 - Install axios
00:33:30 - Build the actual application, components, layouts, API requests
02:40:30 - Refactor code and UI
02:51:13 - Outro
⭐ Project Source code - https://github.com/thecodeholic/vue-meals-app
👉 API we'll use - https://www.themealdb.com/api.php
1667107740
Vue Vben Admin is a free and open source middle and back-end template. Using the latest vue3
, vite2
, TypeScript
and other mainstream technology development, the out-of-the-box middle and back-end front-end solutions can also be used for learning reference.
Test account: vben/123456
Open the project in Gitpod (free online dev environment for GitHub) and start coding immediately.
TypeScript
git clone https://github.com/anncwb/vue-vben-admin.git
cd vue-vben-admin
pnpm install
pnpm serve
pnpm build
You are very welcome to join!Raise an issue Or submit a Pull Request。
Pull Request:
git checkout -b feat/xxxx
git commit -am 'feat(function): add xxxxx'
git push origin feat/xxxx
pull request
reference vue specification (Angular)
feat
Add new featuresfix
Fix the problem/BUGstyle
The code style is related and does not affect the running resultperf
Optimization/performance improvementrefactor
Refactorrevert
Undo edittest
Test relateddocs
Documentation/noteschore
Dependency update/scaffolding configuration modification etc.workflow
Workflow improvementsci
Continuous integrationtypes
Type definition file changeswip
In developmentIf these plugins are helpful to you, you can give a star support
The Chrome 80+
browser is recommended for local development
Support modern browsers, not IE
Author: vbenjs
Source Code: https://github.com/vbenjs/vue-vben-admin
License: MIT license
1660393320
中規模から大規模の SPA を構築している場合、Vue コンポーネントの状態をより適切に処理したい状況に遭遇する可能性があります。
どのアプリケーションでも、複数のコンポーネントが同じ状態に依存しています。異なるコンポーネントからの複数のアクションが同じ状態を変更したいと考えてみましょう。これらの課題を克服するために、Vuexはアプリケーション全体で状態を維持するのに役立ちます。
この記事では、TypeScript で Vuex モジュールを実装し、Jest を使用してユニット テストを行う方法を説明します。このチュートリアルの完全なコードは、vuex-test GitHub リポジトリで入手できます。気軽にフォークしてください。始めましょう!
Vuex は、Vue アプリケーションの状態管理パターンおよびライブラリであり、アプリケーションで集中状態管理を使用できるようにし、Flux のようなアーキテクチャを活用するのに役立ちます。Vuex ストアには、次の4 つのコア コンセプトが含まれています。
状態オブジェクトには、すべてのアプリケーション レベルの状態を含め、ストアに保持するデータが含まれており、信頼できる唯一の情報源として機能します。状態で定義されるプロパティは、文字列、数値、オブジェクト、配列など、任意のデータ型にすることができます。
アイテムのリストを数えたり、コレクションをフィルタリングしたり、他のモジュールやコンポーネントで同じ一連の派生状態を使用したりするなど、ストアの状態に基づいて派生状態が必要な場合は、getter を定義できます。
一方、突然変異は、状態を変更できる唯一の方法です。ミューテーションは常に同期的であり、ペイロードはオプションです。コミット、つまり、MUTATION_NAME
またはを介してミューテーションを呼び出すことができますpayload
。アクションからミューテーションを呼び出すことを常にお勧めします。
アクションは、非同期操作を実行し、ミューテーションをコミットできます。アクション ハンドラーは、ストア インスタンスで同じメソッドまたはプロパティのセットを公開するコンテキスト オブジェクトを受け取ります。
とを使用context.getters
しcontext.state
て状態を取得し、context.commit
ミューテーションを呼び出すことができます。action-name
とを使用してアクション ハンドラーを呼び出すことができますpayload
。これらは、ストア内の他のアクションから呼び出されます。
Vuex アーキテクチャ
アプリケーションのサイズが大きくなると、ストアが肥大化する可能性があります。これを防ぐために、Vuex ではストアをモジュールに分割できます。各モジュールには、独自の状態、ゲッター、ミューテーション、およびアクションを含めることができます。
例として、To Do リストを管理するアプリケーションを作成してみましょう。まず、To Do 操作用の新しいモジュールを作成します。このモジュールは、すべての To Do アイテムを取得し、必要に応じて状態を更新します。
私たちの目標は、中規模から大規模なアプリケーション用のモジュールを構築することです。したがって、ミューテーション タイプ、関数と呼ばれるアクション、およびモジュールの実装を別々のファイルに分割することをお勧めします。
mutation-types.ts
: すべての関数名が含まれますactions.ts
: すべての非同期操作を担当index.ts
: モジュールの実装import { IToDo } from '@/types/todo';
import {Module, VuexModule, Mutation, Action} from 'vuex-module-decorators';
import TodoActions from './actions';
import * as mutationTypes from './mutation-types';
@Module({namespaced: true, name: "Todos"})
export class ToDoModule extends VuexModule {
todos:Array<IToDo> = [];
loading = false;
get completedTodos(){
return this.todos.filter((todo:IToDo)=> todo.completed);
}
@Mutation
[mutationTypes.ON_FETCH_TODOS_STARTED]() {
this.loading = true;
}
@Mutation
\[mutationTypes.ON_FETCH_TODOS_SUCCESS\](data: Array<IToDo>) {
this.loading = false;
this.todos = data;
}
@Mutation
[mutationTypes.ON_FETCH_TODOS_FAILED]() {
this.loading = false;
this.todos = [];
}
@Action({rawError: true})
public async fetchTodos():Promise<void> {
try {
this.context.commit(mutationTypes.ON_FETCH_TODOS_STARTED);
const response: Array<IToDo> = await TodoActions.fetchTodos();
this.context.commit(mutationTypes.ON_FETCH_TODOS_SUCCESS, response);
} catch (error) {
this.context.commit(mutationTypes.ON_FETCH_TODOS_FAILED);
}
}
}
上記のコード スニペットには、次の実装が含まれています。
fetchTodos Action
: REST API から To Do アイテムを取得し、ミューテーションをコミットします。ON_FETCH_TODOS_STARTED
突然変異:loading
状態属性を更新しますON_FETCH_TODOS_SUCCESS
突然変異:todos
状態配列を更新しますON_FETCH_TODOS_FAILED
突然変異: をリセットし、false としてtodos
更新しますloading
completedTodos
getter: 完了した ToDo 項目のみを取得します単体テストには Jest フレームワークを使用します。Jest は、npm や Yarn などのノードベースのパッケージ マネージャーで簡単にインストールできる JavaScript テスト フレームワークです。Jest を使用する利点はほとんどありません。たとえば、Jest テストは並列で実行され、組み込みのコード カバレッジが含まれ、分離されたテスト、モック、およびスナップショット テストがサポートされます。
ストアを作成し、Vuex を Vue にアタッチし、ストアを登録することで、テストを初期化できます。localVue
グローバル Vue コンストラクターに影響を与えずに変更できる、スコープ付きの Vue コンストラクターです。以下のコード スニペットはストアを初期化します。
describe('Todos Module', function() {
let store: any;
let todosInstance: ToDoModule;
beforeEach(function() {
localVue.use(Vuex);
store = new Vuex.Store({});
registerStoreModules(store);
todosInstance = getModule(ToDoModule, store);
});
it('should exists', function() {
expect(todosInstance).toBeDefined();
});
});
todos
モジュールでは、REST API からデータをフェッチし、ミューテーションを使用して状態を埋めるアクションを作成しましたfetchTodos
。REST API は外部呼び出しであるため、Jest 関数を使用してそれをモックし、それが呼び出されて状態が更新されているかどうかを検証できます。
it('fetchTodos action should fill todos state', async function() {
// arrange
const todosMocked = todos as Array<IToDo>;
// act
jest.spyOn(TodoActions, 'fetchTodos').mockImplementation(
(): Promise<Array<IToDo>> => {
return Promise.resolve(todosMocked);
}
);
await todosInstance.fetchTodos();
// assert
expect(todosInstance.todos.length >0).toEqual(true);
expect(TodoActions.fetchTodos).toHaveBeenCalled();
});
ゲッター関数は単に状態オブジェクトを返します。completedTodos
この例では、完了した To-Do 項目を返すゲッター関数 が 1 つあります。
it('completedTodos getter should return only completed todos', async function() {
// arrange
const completedTodos = todosInstance.completedTodos;
// assert
expect(completedTodos.every((todo:IToDo)=> todo.completed)).toEqual(true);
});
すでに知っているように、ミューテーションは状態を変更する唯一の方法です。ON_FETCH_TODOS_SUCCESS
モック ToDo タスクを送信し、状態が変更されているかどうかを検証することで、ミューテーションをテストできます。
以下のコード スニペットは success
ミューテーション用です。started
同じことがおよびerror
ミューテーションにも当てはまります。
it('ON_FETCH_TODOS_SUCCESS mutation should update given todos', function() {
// arrange
const todosTest = [
{
userId: 13,
id: 12,
title: "Move to new city",
completed: false
},
{
userId: 15,
id: 21,
title: "Finish a novel",
completed: true
},
];
// act
todosInstance.ON_FETCH_TODOS_SUCCESS(todosTest);
// assert
expect(todosInstance.todos.length).toEqual(2);
expect(todosInstance.todos).toEqual(todosTest);
});
このチュートリアルでは、TypeScript と Jest を使用して Vuex モジュールを作成し、ユニット テストすることで、Vuex について学びました。状態、ゲッター、ミューテーション、アクションを含む、Vuex ストアの 4 つの主要な概念について説明しました。Vuex の集中状態管理により、アプリケーションを簡素化し、Flux のようなアーキテクチャを活用できます。
何か新しいことを学んでいただければ幸いです。ご不明な点がありましたら、コメントを残してください。ハッピーコーディング!
ソース: https://blog.logrocket.com/unit-testing-vuex-modules-jest/
1660310669
如果您正在构建一个中型到大型的 SPA,您很可能会遇到想要更好地处理 Vue 组件状态的情况。
在任何应用程序中,多个组件都依赖于同一个状态。让我们假设来自不同组件的多个动作想要改变相同的状态。为了克服这些挑战,Vuex帮助我们维护整个应用程序的状态。
在本文中,我将指导您在TypeScript 中实现一个 Vuex 模块,然后使用 Jest 对其进行单元测试。本教程的完整代码可在vuex-test GitHub 存储库中获得;随意分叉它。让我们开始吧!
Vuex 是Vue 应用程序的状态管理模式和库,允许您在应用程序中使用集中状态管理,帮助您利用类似 Flux 的架构。Vuex store包含四个核心概念:
状态对象包含您希望在存储中拥有的数据,包括您的所有应用程序级状态,作为唯一的事实来源。状态中定义的属性可以是任何数据类型,包括字符串、数字、对象或数组。
如果您想根据存储状态获得派生状态,例如,计算项目列表、过滤集合或在其他模块或组件中使用相同的派生状态集,您可以定义 getters。
另一方面,突变是我们改变状态的唯一方法。突变总是同步的,有效载荷是可选的。您可以通过提交,即MUTATION_NAME
或payload
. 始终建议从动作中调用突变。
动作可以执行异步操作并提交突变。动作处理程序接收一个上下文对象,该对象在存储实例上公开相同的方法或属性集。
您可以使用context.getters
andcontext.state
来获取状态并context.commit
调用突变。action-name
您可以使用和调用动作处理程序payload
,它们是从商店中的其他动作调用的。
Vuex 架构
随着应用程序大小的增加,您的商店可能会变得臃肿。为了防止这种情况,Vuex 允许您将 store 拆分为 modules。每个模块都可以包含自己的状态、getter、突变和动作。
例如,让我们创建一个用于管理待办事项列表的应用程序。首先,新建一个待办事项模块,负责获取所有待办事项并根据需要更新状态。
我们的目标是为中大型应用程序构建模块,因此,最好将突变类型、称为函数的操作和模块实现拆分到单独的文件中:
mutation-types.ts
: 包含所有函数名actions.ts
: 负责所有异步操作index.ts
: 模块实现import { IToDo } from '@/types/todo';
import {Module, VuexModule, Mutation, Action} from 'vuex-module-decorators';
import TodoActions from './actions';
import * as mutationTypes from './mutation-types';
@Module({namespaced: true, name: "Todos"})
export class ToDoModule extends VuexModule {
todos:Array<IToDo> = [];
loading = false;
get completedTodos(){
return this.todos.filter((todo:IToDo)=> todo.completed);
}
@Mutation
[mutationTypes.ON_FETCH_TODOS_STARTED]() {
this.loading = true;
}
@Mutation
\[mutationTypes.ON_FETCH_TODOS_SUCCESS\](data: Array<IToDo>) {
this.loading = false;
this.todos = data;
}
@Mutation
[mutationTypes.ON_FETCH_TODOS_FAILED]() {
this.loading = false;
this.todos = [];
}
@Action({rawError: true})
public async fetchTodos():Promise<void> {
try {
this.context.commit(mutationTypes.ON_FETCH_TODOS_STARTED);
const response: Array<IToDo> = await TodoActions.fetchTodos();
this.context.commit(mutationTypes.ON_FETCH_TODOS_SUCCESS, response);
} catch (error) {
this.context.commit(mutationTypes.ON_FETCH_TODOS_FAILED);
}
}
}
上面的代码片段包含以下实现:
fetchTodos Action
:从 REST API 中获取待办事项并提交变更ON_FETCH_TODOS_STARTED
突变:更新loading
状态属性ON_FETCH_TODOS_SUCCESS
突变:更新todos
状态数组ON_FETCH_TODOS_FAILED
突变:重置todos
和更新loading
为假completedTodos
getter:仅获取已完成的待办事项我们将使用Jest 框架进行单元测试;Jest 只是一个 JavaScript 测试框架,可以使用任何基于节点的包管理器(如 npm 或 Yarn)轻松安装。使用 Jest 的优势很少,例如,Jest 测试并行运行,包括内置代码覆盖,并支持隔离测试、模拟和快照测试。
您可以通过创建商店、将 Vuex 附加到 Vue 并注册商店来初始化测试。localVue
是作用域的 Vue 构造函数,我们可以在不影响全局 Vue 构造函数的情况下对其进行更改。下面的代码片段将初始化商店:
describe('Todos Module', function() {
let store: any;
let todosInstance: ToDoModule;
beforeEach(function() {
localVue.use(Vuex);
store = new Vuex.Store({});
registerStoreModules(store);
todosInstance = getModule(ToDoModule, store);
});
it('should exists', function() {
expect(todosInstance).toBeDefined();
});
});
在todos
模块中,我们创建了fetchTodos
从 REST API 获取数据并使用突变填充状态的操作。由于 REST API 是一个外部调用,我们可以使用 Jest 函数模拟它,然后验证它是否被调用以及状态是否正在更新:
it('fetchTodos action should fill todos state', async function() {
// arrange
const todosMocked = todos as Array<IToDo>;
// act
jest.spyOn(TodoActions, 'fetchTodos').mockImplementation(
(): Promise<Array<IToDo>> => {
return Promise.resolve(todosMocked);
}
);
await todosInstance.fetchTodos();
// assert
expect(todosInstance.todos.length >0).toEqual(true);
expect(TodoActions.fetchTodos).toHaveBeenCalled();
});
Getter 函数只返回状态对象。在我们的示例中,我们有一个 getter 函数,completedTodos
它应该返回已完成的待办事项:
it('completedTodos getter should return only completed todos', async function() {
// arrange
const completedTodos = todosInstance.completedTodos;
// assert
expect(completedTodos.every((todo:IToDo)=> todo.completed)).toEqual(true);
});
正如我们已经知道的,突变是改变状态的唯一方法。我们可以ON_FETCH_TODOS_SUCCESS
通过发送模拟待办任务并验证状态是否被修改来测试突变。
下面的代码片段用于 success
突变。这同样适用于started
anderror
突变:
it('ON_FETCH_TODOS_SUCCESS mutation should update given todos', function() {
// arrange
const todosTest = [
{
userId: 13,
id: 12,
title: "Move to new city",
completed: false
},
{
userId: 15,
id: 21,
title: "Finish a novel",
completed: true
},
];
// act
todosInstance.ON_FETCH_TODOS_SUCCESS(todosTest);
// assert
expect(todosInstance.todos.length).toEqual(2);
expect(todosInstance.todos).toEqual(todosTest);
});
在本教程中,我们通过使用 TypeScript 和 Jest 创建和单元测试 Vuex 模块来了解 Vuex。我们介绍了 Vuex 存储的四个核心概念,包括状态、getter、突变和动作。借助 Vuex 的集中状态管理,您可以简化应用程序并利用类似 Flux 的架构。
我希望你学到了一些新东西,如果你有任何问题,一定要发表评论。快乐编码!
来源:https ://blog.logrocket.com/unit-testing-vuex-modules-jest/
1660306812
Si vous construisez un SPA de moyenne à grande échelle, il y a de fortes chances que vous rencontriez des situations où vous souhaitez mieux gérer l'état de vos composants Vue.
Dans toute application, plusieurs composants dépendent du même élément d'état. Imaginons que plusieurs actions de différents composants voudraient faire muter le même état. Pour surmonter ces défis, Vuex nous aide à maintenir l'état de l'application.
Dans cet article, je vais vous guider dans l'implémentation d'un module Vuex dans TypeScript, puis le tester unitairement à l'aide de Jest . Le code complet de ce didacticiel est disponible dans le référentiel GitHub de vuex-test ; n'hésitez pas à le bifurquer. Commençons!
Vuex est un modèle de gestion d'état et une bibliothèque pour les applications Vue qui vous permet d'utiliser la gestion d'état centralisée dans vos applications, vous aidant à tirer parti de l'architecture de type Flux. Le magasin Vuex contient quatre concepts de base :
L' objet d'état contient les données que vous souhaitez avoir dans le magasin, y compris tout votre état au niveau de l'application, servant de source unique de vérité. Les propriétés définies dans l'état peuvent être n'importe quel type de données, y compris une chaîne, un nombre, un objet ou un tableau.
Si vous souhaitez avoir un état dérivé basé sur l'état du magasin, par exemple, compter la liste des éléments, filtrer la collection ou utiliser le même ensemble d'états dérivés dans d'autres modules ou composants, vous pouvez définir des getters .
D'un autre côté, les mutations sont le seul moyen de changer l'état. Les mutations sont toujours synchrones et la charge utile est facultative. Vous pouvez appeler une mutation via le commit, c'est-à-dire MUTATION_NAME
ou payload
. Il est toujours recommandé d'appeler des mutations à partir d'actions.
Les actions peuvent effectuer des opérations asynchrones et valider les mutations. Les gestionnaires d'action reçoivent un objet de contexte qui expose le même ensemble de méthodes ou de propriétés sur l'instance de magasin.
Vous pouvez utiliser context.getters
et context.state
pour obtenir l'état et context.commit
appeler des mutations. Vous pouvez appeler des gestionnaires d'action à l'aide de action-name
et payload
, et ils sont appelés à partir d'autres actions du magasin.
Architecture Vuex
À mesure que la taille de votre application augmente, votre magasin peut devenir gonflé. Pour éviter cela, Vuex vous permet de diviser le magasin en modules . Chaque module peut contenir son propre état, getters, mutations et actions.
A titre d'exemple, créons une application pour gérer une liste de tâches. Tout d'abord, créez un nouveau module pour les opérations à faire, qui est responsable de l'obtention de tous les éléments à faire et de la mise à jour de l'état si nécessaire.
Notre objectif est de construire le module pour des applications à moyenne et grande échelle, par conséquent, il est préférable de diviser les types de mutation, les actions appelées fonctions et l'implémentation du module dans des fichiers séparés :
mutation-types.ts
: Contient tous les noms de fonctionactions.ts
: Responsable de toutes les opérations asynchronesindex.ts
: L'implémentation du moduleimport { IToDo } from '@/types/todo';
import {Module, VuexModule, Mutation, Action} from 'vuex-module-decorators';
import TodoActions from './actions';
import * as mutationTypes from './mutation-types';
@Module({namespaced: true, name: "Todos"})
export class ToDoModule extends VuexModule {
todos:Array<IToDo> = [];
loading = false;
get completedTodos(){
return this.todos.filter((todo:IToDo)=> todo.completed);
}
@Mutation
[mutationTypes.ON_FETCH_TODOS_STARTED]() {
this.loading = true;
}
@Mutation
\[mutationTypes.ON_FETCH_TODOS_SUCCESS\](data: Array<IToDo>) {
this.loading = false;
this.todos = data;
}
@Mutation
[mutationTypes.ON_FETCH_TODOS_FAILED]() {
this.loading = false;
this.todos = [];
}
@Action({rawError: true})
public async fetchTodos():Promise<void> {
try {
this.context.commit(mutationTypes.ON_FETCH_TODOS_STARTED);
const response: Array<IToDo> = await TodoActions.fetchTodos();
this.context.commit(mutationTypes.ON_FETCH_TODOS_SUCCESS, response);
} catch (error) {
this.context.commit(mutationTypes.ON_FETCH_TODOS_FAILED);
}
}
}
L'extrait de code ci-dessus contient l'implémentation suivante :
fetchTodos Action
: Récupère les éléments à faire de l'API REST et valide les mutationsON_FETCH_TODOS_STARTED
mutation : met à jour l' loading
attribut d'étatON_FETCH_TODOS_SUCCESS
mutation : met à jour le todos
tableau d'étatON_FETCH_TODOS_FAILED
mutation : Réinitialise todos
et met à jour loading
comme fauxcompletedTodos
getter : Obtient uniquement les éléments à faire qui sont terminésNous utiliserons le framework Jest pour les tests unitaires ; Jest est simplement un framework de test JavaScript qui peut être facilement installé avec n'importe quel gestionnaire de packages basé sur un nœud, comme npm ou Yarn. L'utilisation de Jest présente peu d'avantages, par exemple, les tests Jest s'exécutent en parallèle, incluent une couverture de code intégrée et prennent en charge les tests isolés, les simulations et les tests instantanés.
Vous pouvez initialiser le test en créant un magasin, en attachant Vuex à Vue et en enregistrant le magasin. localVue
est le constructeur Vue scoped que nous pouvons modifier sans affecter le constructeur Vue global. L'extrait de code ci-dessous initialisera le magasin :
describe('Todos Module', function() {
let store: any;
let todosInstance: ToDoModule;
beforeEach(function() {
localVue.use(Vuex);
store = new Vuex.Store({});
registerStoreModules(store);
todosInstance = getModule(ToDoModule, store);
});
it('should exists', function() {
expect(todosInstance).toBeDefined();
});
});
Dans le todos
module, nous avons créé l' fetchTodos
action, qui récupère les données d'une API REST et remplit l'état à l'aide de mutations. Étant donné que l'API REST est un appel externe, nous pouvons la simuler à l'aide d'une fonction Jest, puis valider si elle est appelée et si l'état est mis à jour :
it('fetchTodos action should fill todos state', async function() {
// arrange
const todosMocked = todos as Array<IToDo>;
// act
jest.spyOn(TodoActions, 'fetchTodos').mockImplementation(
(): Promise<Array<IToDo>> => {
return Promise.resolve(todosMocked);
}
);
await todosInstance.fetchTodos();
// assert
expect(todosInstance.todos.length >0).toEqual(true);
expect(TodoActions.fetchTodos).toHaveBeenCalled();
});
Les fonctions getter renvoient simplement l'objet d'état. Dans notre exemple, nous avons une fonction getter, completedTodos
, qui doit renvoyer les tâches à faire terminées :
it('completedTodos getter should return only completed todos', async function() {
// arrange
const completedTodos = todosInstance.completedTodos;
// assert
expect(completedTodos.every((todo:IToDo)=> todo.completed)).toEqual(true);
});
Comme nous le savons déjà, les mutations sont le seul moyen de changer l'état. Nous pouvons tester la ON_FETCH_TODOS_SUCCESS
mutation en envoyant des tâches fictives et en validant si l'état est modifié.
L'extrait de code ci-dessous est pour la success
mutation. Il en va de même pour les mutations started
et :error
it('ON_FETCH_TODOS_SUCCESS mutation should update given todos', function() {
// arrange
const todosTest = [
{
userId: 13,
id: 12,
title: "Move to new city",
completed: false
},
{
userId: 15,
id: 21,
title: "Finish a novel",
completed: true
},
];
// act
todosInstance.ON_FETCH_TODOS_SUCCESS(todosTest);
// assert
expect(todosInstance.todos.length).toEqual(2);
expect(todosInstance.todos).toEqual(todosTest);
});
Dans ce didacticiel, nous avons découvert Vuex en créant et en testant un module Vuex avec TypeScript et Jest. Nous avons couvert les quatre concepts de base d'un magasin Vuex, y compris l'état, les getters, les mutations et les actions. Avec la gestion d'état centralisée de Vuex, vous pouvez simplifier votre application et tirer parti de l'architecture de type Flux.
J'espère que vous avez appris quelque chose de nouveau, et assurez-vous de laisser un commentaire si vous avez des questions. Bon codage !
Source : https://blog.logrocket.com/unit-testing-vuex-modules-jest/
1660306440
Se você estiver construindo um SPA de médio a grande porte, é provável que você se depare com situações em que deseja lidar melhor com o estado de seus componentes Vue.
Em qualquer aplicação, vários componentes dependem do mesmo estado. Vamos imaginar que várias ações de diferentes componentes gostariam de alterar o mesmo estado. Para superar esses desafios, o Vuex nos ajuda a manter o estado em todo o aplicativo.
Neste artigo, orientarei você na implementação de um módulo Vuex no TypeScript e, em seguida, no teste de unidade usando Jest . O código completo deste tutorial está disponível no repositório GitHub vuex-test ; sinta-se livre para bifurcá-lo. Vamos começar!
Vuex é um padrão e biblioteca de gerenciamento de estado para aplicativos Vue que permite usar o gerenciamento de estado centralizado em seus aplicativos, ajudando você a aproveitar a arquitetura semelhante ao Flux. A loja Vuex contém quatro conceitos principais:
O objeto de estado contém os dados que você deseja ter no armazenamento, incluindo todo o estado no nível do aplicativo, servindo como a única fonte de verdade. As propriedades definidas no estado podem ser qualquer tipo de dados, incluindo uma string, número, objeto ou array.
Se você quiser ter um estado derivado baseado no estado da loja, por exemplo, contando a lista de itens, filtrando a coleção ou usando o mesmo conjunto de estado derivado em outros módulos ou componentes, você pode definir getters .
Por outro lado, as mutações são a única maneira de mudar o estado. As mutações são sempre síncronas e a carga útil é opcional. Você pode chamar uma mutação por meio do commit, ou seja, MUTATION_NAME
ou payload
. É sempre recomendado chamar mutações de ações.
As ações podem realizar operações assíncronas e confirmar as mutações. Os manipuladores de ação recebem um objeto de contexto que expõe o mesmo conjunto de métodos ou propriedades na instância de armazenamento.
Você pode usar context.getters
e context.state
para obter o estado e context.commit
chamar mutações. Você pode chamar manipuladores de ação usando action-name
e payload
, e eles são chamados de outras ações dentro da loja.
Arquitetura Vuex
À medida que o tamanho do seu aplicativo aumenta, sua loja pode ficar inchada. Para evitar isso, o Vuex permite dividir a loja em módulos . Cada módulo pode conter seu próprio estado, getters, mutações e ações.
Como exemplo, vamos criar um aplicativo para gerenciar uma lista de tarefas. Primeiro, crie um novo módulo para operações de pendências, que é responsável por obter todas as pendências e atualizar o estado conforme necessário.
Nosso objetivo é construir o módulo para aplicações de médio a grande porte, portanto, é melhor dividir os tipos de mutação, ações chamadas funções e a implementação do módulo em arquivos separados:
mutation-types.ts
: Contém todos os nomes de funçõesactions.ts
: Responsável por todas as operações assíncronasindex.ts
: A implementação do móduloimport { IToDo } from '@/types/todo';
import {Module, VuexModule, Mutation, Action} from 'vuex-module-decorators';
import TodoActions from './actions';
import * as mutationTypes from './mutation-types';
@Module({namespaced: true, name: "Todos"})
export class ToDoModule extends VuexModule {
todos:Array<IToDo> = [];
loading = false;
get completedTodos(){
return this.todos.filter((todo:IToDo)=> todo.completed);
}
@Mutation
[mutationTypes.ON_FETCH_TODOS_STARTED]() {
this.loading = true;
}
@Mutation
\[mutationTypes.ON_FETCH_TODOS_SUCCESS\](data: Array<IToDo>) {
this.loading = false;
this.todos = data;
}
@Mutation
[mutationTypes.ON_FETCH_TODOS_FAILED]() {
this.loading = false;
this.todos = [];
}
@Action({rawError: true})
public async fetchTodos():Promise<void> {
try {
this.context.commit(mutationTypes.ON_FETCH_TODOS_STARTED);
const response: Array<IToDo> = await TodoActions.fetchTodos();
this.context.commit(mutationTypes.ON_FETCH_TODOS_SUCCESS, response);
} catch (error) {
this.context.commit(mutationTypes.ON_FETCH_TODOS_FAILED);
}
}
}
O snippet de código acima contém a seguinte implementação:
fetchTodos Action
: busca os itens de tarefas da API REST e confirma as mutaçõesON_FETCH_TODOS_STARTED
mutação: atualiza o loading
atributo de estadoON_FETCH_TODOS_SUCCESS
mutação: atualiza a todos
matriz de estadoON_FETCH_TODOS_FAILED
mutação: redefine o todos
e atualiza loading
como falsocompletedTodos
getter: Obtém apenas os itens de tarefas que foram concluídosUsaremos o framework Jest para testes unitários ; Jest é simplesmente uma estrutura de teste JavaScript que pode ser facilmente instalada com qualquer gerenciador de pacotes baseado em nó, como npm ou Yarn. Há poucas vantagens de usar o Jest, por exemplo, os testes do Jest são executados em paralelo, incluem cobertura de código integrada e dão suporte a testes isolados, simulações e testes de instantâneos.
Você pode inicializar o teste criando uma loja, anexando Vuex ao Vue e registrando a loja. localVue
é o construtor Vue com escopo que podemos alterar sem afetar o construtor Vue global. O snippet de código abaixo inicializará a loja:
describe('Todos Module', function() {
let store: any;
let todosInstance: ToDoModule;
beforeEach(function() {
localVue.use(Vuex);
store = new Vuex.Store({});
registerStoreModules(store);
todosInstance = getModule(ToDoModule, store);
});
it('should exists', function() {
expect(todosInstance).toBeDefined();
});
});
No todos
módulo, criamos a fetchTodos
ação, que busca os dados de uma API REST e preenche o estado usando mutações. Como a API REST é uma chamada externa, podemos zombar dela usando uma função Jest e validar se ela está sendo chamada e o estado está sendo atualizado:
it('fetchTodos action should fill todos state', async function() {
// arrange
const todosMocked = todos as Array<IToDo>;
// act
jest.spyOn(TodoActions, 'fetchTodos').mockImplementation(
(): Promise<Array<IToDo>> => {
return Promise.resolve(todosMocked);
}
);
await todosInstance.fetchTodos();
// assert
expect(todosInstance.todos.length >0).toEqual(true);
expect(TodoActions.fetchTodos).toHaveBeenCalled();
});
As funções getter simplesmente retornam o objeto de estado. Em nosso exemplo, temos uma função getter, completedTodos
, que deve retornar os itens de pendências concluídos:
it('completedTodos getter should return only completed todos', async function() {
// arrange
const completedTodos = todosInstance.completedTodos;
// assert
expect(completedTodos.every((todo:IToDo)=> todo.completed)).toEqual(true);
});
Como já sabemos, as mutações são a única maneira de mudar o estado. Podemos testar a ON_FETCH_TODOS_SUCCESS
mutação enviando tarefas simuladas e validando se o estado foi modificado.
O trecho de código abaixo é para a success
mutação. O mesmo se aplica para as mutações started
e também:error
it('ON_FETCH_TODOS_SUCCESS mutation should update given todos', function() {
// arrange
const todosTest = [
{
userId: 13,
id: 12,
title: "Move to new city",
completed: false
},
{
userId: 15,
id: 21,
title: "Finish a novel",
completed: true
},
];
// act
todosInstance.ON_FETCH_TODOS_SUCCESS(todosTest);
// assert
expect(todosInstance.todos.length).toEqual(2);
expect(todosInstance.todos).toEqual(todosTest);
});
Neste tutorial, aprendemos sobre o Vuex criando e testando a unidade de um módulo Vuex com TypeScript e Jest. Cobrimos os quatro conceitos principais de uma loja Vuex, incluindo estado, getters, mutações e ações. Com o gerenciamento de estado centralizado do Vuex, você pode simplificar seu aplicativo e aproveitar a arquitetura semelhante ao Flux.
Espero que você tenha aprendido algo novo, e não se esqueça de deixar um comentário se tiver alguma dúvida. Boa codificação!
Fonte: https://blog.logrocket.com/unit-testing-vuex-modules-jest/
1660303082
Si está construyendo un SPA de mediana a gran escala, es probable que se encuentre con situaciones en las que desee manejar mejor el estado de sus componentes de Vue.
En cualquier aplicación, varios componentes dependen del mismo estado. Imaginemos que varias acciones de diferentes componentes quisieran mutar el mismo estado. Para superar estos desafíos, Vuex nos ayuda a mantener el estado en toda la aplicación.
En este artículo, lo guiaré a través de la implementación de un módulo Vuex en TypeScript, luego lo probaré unitariamente usando Jest . El código completo de este tutorial está disponible en el repositorio de GitHub de vuex-test ; siéntete libre de bifurcarlo. ¡Empecemos!
Vuex es un patrón de gestión de estado y una biblioteca para aplicaciones Vue que le permite utilizar la gestión de estado centralizada en sus aplicaciones, ayudándole a aprovechar la arquitectura similar a Flux. La tienda Vuex contiene cuatro conceptos básicos:
El objeto de estado contiene los datos que desea tener en el almacén, incluido todo el estado de su aplicación, y actúa como la única fuente de verdad. Las propiedades definidas en el estado pueden ser de cualquier tipo de datos, incluida una cadena, un número, un objeto o una matriz.
Si desea tener un estado derivado basado en el estado de la tienda, por ejemplo, contar la lista de elementos, filtrar la colección o usar el mismo conjunto de estados derivados en otros módulos o componentes, puede definir captadores .
Por otro lado, las mutaciones son la única forma en que podemos cambiar el estado. Las mutaciones siempre son síncronas y la carga útil es opcional. Puede llamar a una mutación a través de la confirmación, es decir, MUTATION_NAME
o payload
. Siempre se recomienda llamar mutaciones desde acciones.
Las acciones pueden realizar operaciones asincrónicas y cometer las mutaciones. Los controladores de acciones reciben un objeto de contexto que expone el mismo conjunto de métodos o propiedades en la instancia de la tienda.
Puede usar context.getters
y context.state
para obtener el estado y context.commit
para llamar mutaciones. Puede llamar a los controladores de acciones usando action-name
y payload
, y se llaman desde otras acciones dentro de la tienda.
arquitectura vuex
A medida que aumenta el tamaño de su aplicación, su tienda puede inflarse. Para evitar esto, Vuex te permite dividir la tienda en módulos . Cada módulo puede contener su propio estado, captadores, mutaciones y acciones.
Como ejemplo, vamos a crear una aplicación para administrar una lista de tareas pendientes. Primero, cree un nuevo módulo para las operaciones pendientes, que es responsable de obtener todos los elementos pendientes y actualizar el estado según sea necesario.
Nuestro objetivo es construir el módulo para aplicaciones de mediana a gran escala, por lo tanto, es mejor dividir los tipos de mutación, las acciones llamadas funciones y la implementación del módulo en archivos separados:
mutation-types.ts
: Contiene todos los nombres de funcionesactions.ts
: Responsable de todas las operaciones asíncronasindex.ts
: La implementación del móduloimport { IToDo } from '@/types/todo';
import {Module, VuexModule, Mutation, Action} from 'vuex-module-decorators';
import TodoActions from './actions';
import * as mutationTypes from './mutation-types';
@Module({namespaced: true, name: "Todos"})
export class ToDoModule extends VuexModule {
todos:Array<IToDo> = [];
loading = false;
get completedTodos(){
return this.todos.filter((todo:IToDo)=> todo.completed);
}
@Mutation
[mutationTypes.ON_FETCH_TODOS_STARTED]() {
this.loading = true;
}
@Mutation
\[mutationTypes.ON_FETCH_TODOS_SUCCESS\](data: Array<IToDo>) {
this.loading = false;
this.todos = data;
}
@Mutation
[mutationTypes.ON_FETCH_TODOS_FAILED]() {
this.loading = false;
this.todos = [];
}
@Action({rawError: true})
public async fetchTodos():Promise<void> {
try {
this.context.commit(mutationTypes.ON_FETCH_TODOS_STARTED);
const response: Array<IToDo> = await TodoActions.fetchTodos();
this.context.commit(mutationTypes.ON_FETCH_TODOS_SUCCESS, response);
} catch (error) {
this.context.commit(mutationTypes.ON_FETCH_TODOS_FAILED);
}
}
}
El fragmento de código anterior contiene la siguiente implementación:
fetchTodos Action
: Obtiene los elementos pendientes de la API REST y confirma las mutacionesON_FETCH_TODOS_STARTED
mutación: Actualiza el loading
atributo de estadoON_FETCH_TODOS_SUCCESS
mutación: actualiza la todos
matriz de estadoON_FETCH_TODOS_FAILED
mutación: restablece todos
y actualiza loading
como falsocompletedTodos
captador: obtiene solo las tareas pendientes que se han completadoUsaremos el marco Jest para pruebas unitarias ; Jest es simplemente un marco de prueba de JavaScript que se puede instalar fácilmente con cualquier administrador de paquetes basado en nodos, como npm o Yarn. Hay pocas ventajas de usar Jest, por ejemplo, las pruebas de Jest se ejecutan en paralelo, incluyen cobertura de código integrada y admiten pruebas aisladas, simulacros y pruebas de instantáneas.
Puede inicializar la prueba creando una tienda, adjuntando Vuex a Vue y registrando la tienda. localVue
es el constructor de Vue con ámbito que podemos cambiar sin afectar al constructor global de Vue. El fragmento de código a continuación inicializará la tienda:
describe('Todos Module', function() {
let store: any;
let todosInstance: ToDoModule;
beforeEach(function() {
localVue.use(Vuex);
store = new Vuex.Store({});
registerStoreModules(store);
todosInstance = getModule(ToDoModule, store);
});
it('should exists', function() {
expect(todosInstance).toBeDefined();
});
});
En el todos
módulo, creamos la fetchTodos
acción, que obtiene datos de una API REST y completa el estado mediante mutaciones. Dado que la API REST es una llamada externa, podemos simularla usando una función Jest, luego validar si se está llamando y el estado se está actualizando:
it('fetchTodos action should fill todos state', async function() {
// arrange
const todosMocked = todos as Array<IToDo>;
// act
jest.spyOn(TodoActions, 'fetchTodos').mockImplementation(
(): Promise<Array<IToDo>> => {
return Promise.resolve(todosMocked);
}
);
await todosInstance.fetchTodos();
// assert
expect(todosInstance.todos.length >0).toEqual(true);
expect(TodoActions.fetchTodos).toHaveBeenCalled();
});
Las funciones getter simplemente devuelven el objeto de estado. En nuestro ejemplo, tenemos una función captadora completedTodos
, que debería devolver los elementos pendientes que se completaron:
it('completedTodos getter should return only completed todos', async function() {
// arrange
const completedTodos = todosInstance.completedTodos;
// assert
expect(completedTodos.every((todo:IToDo)=> todo.completed)).toEqual(true);
});
Como ya sabemos, las mutaciones son la única forma de cambiar el estado. Podemos probar la ON_FETCH_TODOS_SUCCESS
mutación enviando tareas pendientes simuladas y validando si el estado se modifica.
El fragmento de código a continuación es para la success
mutación. Lo mismo se aplica para las mutaciones started
y también:error
it('ON_FETCH_TODOS_SUCCESS mutation should update given todos', function() {
// arrange
const todosTest = [
{
userId: 13,
id: 12,
title: "Move to new city",
completed: false
},
{
userId: 15,
id: 21,
title: "Finish a novel",
completed: true
},
];
// act
todosInstance.ON_FETCH_TODOS_SUCCESS(todosTest);
// assert
expect(todosInstance.todos.length).toEqual(2);
expect(todosInstance.todos).toEqual(todosTest);
});
En este tutorial, aprendimos sobre Vuex al crear y probar un módulo de Vuex con TypeScript y Jest. Cubrimos los cuatro conceptos básicos de una tienda Vuex, incluidos el estado, los captadores, las mutaciones y las acciones. Con la administración de estado centralizada de Vuex, puede simplificar su aplicación y aprovechar la arquitectura similar a Flux.
Espero que hayas aprendido algo nuevo, y asegúrate de dejar un comentario si tienes alguna pregunta. ¡Feliz codificación!
Fuente: https://blog.logrocket.com/unit-testing-vuex-modules-jest/
1660302960
Nếu bạn đang xây dựng một SPA quy mô vừa đến lớn, rất có thể bạn sẽ gặp phải những tình huống mà bạn muốn xử lý tốt hơn trạng thái của các thành phần Vue của mình.
Trong bất kỳ ứng dụng nào, nhiều thành phần phụ thuộc vào cùng một trạng thái. Hãy tưởng tượng rằng nhiều hành động từ các thành phần khác nhau muốn thay đổi cùng một trạng thái. Để vượt qua những thách thức này, Vuex giúp chúng tôi duy trì trạng thái trên toàn ứng dụng.
Trong bài viết này, tôi sẽ hướng dẫn bạn triển khai mô-đun Vuex trong TypeScript, sau đó đơn vị kiểm tra nó bằng Jest . Mã hoàn chỉnh cho hướng dẫn này có sẵn tại kho lưu trữ GitHub vuex-test ; cảm thấy tự do để phân nhánh nó. Bắt đầu nào!
Vuex là một mẫu và thư viện quản lý trạng thái cho các ứng dụng Vue cho phép bạn sử dụng quản lý trạng thái tập trung trong các ứng dụng của mình, giúp bạn tận dụng lợi thế của kiến trúc giống như Flux. Cửa hàng Vuex chứa bốn khái niệm cốt lõi:
Đối tượng trạng thái chứa dữ liệu bạn muốn có trong cửa hàng, bao gồm tất cả trạng thái cấp ứng dụng của bạn, đóng vai trò là nguồn chân lý duy nhất. Các thuộc tính được xác định trong trạng thái có thể là bất kỳ kiểu dữ liệu nào, bao gồm một chuỗi, số, đối tượng hoặc mảng.
Nếu bạn muốn có một trạng thái dẫn xuất dựa trên trạng thái lưu trữ, ví dụ: đếm danh sách các mục, lọc bộ sưu tập hoặc sử dụng cùng một nhóm trạng thái dẫn xuất trong các mô-đun hoặc thành phần khác, bạn có thể xác định getters .
Mặt khác, đột biến là cách duy nhất chúng ta có thể thay đổi trạng thái. Các đột biến luôn đồng bộ và tải trọng là tùy chọn. Bạn có thể gọi một đột biến thông qua cam kết, tức là, MUTATION_NAME
hoặc payload
. Nó luôn được khuyến khích để gọi các đột biến từ các hành động.
Các hành động có thể thực hiện các hoạt động không đồng bộ và thực hiện các đột biến. Trình xử lý hành động nhận được một đối tượng ngữ cảnh hiển thị cùng một tập hợp các phương thức hoặc thuộc tính trên phiên bản store.
Bạn có thể sử dụng context.getters
và context.state
để có được trạng thái và context.commit
gọi các đột biến. Bạn có thể gọi các trình xử lý hành động bằng cách sử dụng action-name
và payload
và chúng được gọi từ các hành động khác trong cửa hàng.
Kiến trúc Vuex
Khi kích thước ứng dụng của bạn tăng lên, cửa hàng của bạn có thể trở nên cồng kềnh. Để ngăn chặn điều này, Vuex cho phép bạn chia cửa hàng thành các mô-đun . Mỗi mô-đun có thể chứa trạng thái, nhận diện, đột biến và hành động của riêng nó.
Ví dụ, hãy tạo một ứng dụng để quản lý danh sách việc cần làm. Đầu tiên, hãy tạo một mô-đun mới cho các hoạt động cần làm, mô-đun này chịu trách nhiệm nhận tất cả các mục cần làm và cập nhật trạng thái khi cần thiết.
Mục tiêu của chúng tôi là xây dựng mô-đun cho các ứng dụng quy mô vừa đến lớn, do đó, tốt hơn là nên chia các loại đột biến, hành động được gọi là chức năng và triển khai mô-đun thành các tệp riêng biệt:
mutation-types.ts
: Chứa tất cả các tên hàmactions.ts
: Chịu trách nhiệm cho tất cả các hoạt động không đồng bộindex.ts
: Triển khai mô-đunimport { IToDo } from '@/types/todo';
import {Module, VuexModule, Mutation, Action} from 'vuex-module-decorators';
import TodoActions from './actions';
import * as mutationTypes from './mutation-types';
@Module({namespaced: true, name: "Todos"})
export class ToDoModule extends VuexModule {
todos:Array<IToDo> = [];
loading = false;
get completedTodos(){
return this.todos.filter((todo:IToDo)=> todo.completed);
}
@Mutation
[mutationTypes.ON_FETCH_TODOS_STARTED]() {
this.loading = true;
}
@Mutation
\[mutationTypes.ON_FETCH_TODOS_SUCCESS\](data: Array<IToDo>) {
this.loading = false;
this.todos = data;
}
@Mutation
[mutationTypes.ON_FETCH_TODOS_FAILED]() {
this.loading = false;
this.todos = [];
}
@Action({rawError: true})
public async fetchTodos():Promise<void> {
try {
this.context.commit(mutationTypes.ON_FETCH_TODOS_STARTED);
const response: Array<IToDo> = await TodoActions.fetchTodos();
this.context.commit(mutationTypes.ON_FETCH_TODOS_SUCCESS, response);
} catch (error) {
this.context.commit(mutationTypes.ON_FETCH_TODOS_FAILED);
}
}
}
Đoạn mã ở trên chứa cách triển khai sau:
fetchTodos Action
: Tìm nạp các mục việc cần làm từ API REST và thực hiện các đột biếnON_FETCH_TODOS_STARTED
đột biến: Cập nhật loading
thuộc tính trạng tháiON_FETCH_TODOS_SUCCESS
đột biến: Cập nhật todos
mảng trạng tháiON_FETCH_TODOS_FAILED
đột biến: Đặt lại todos
và cập nhật loading
là saicompletedTodos
getter: Chỉ nhận các mục việc cần làm đã hoàn thànhChúng tôi sẽ sử dụng khuôn khổ Jest để thử nghiệm đơn vị ; Jest chỉ đơn giản là một khung kiểm tra JavaScript có thể dễ dàng cài đặt với bất kỳ trình quản lý gói dựa trên nút nào, như npm hoặc Yarn. Có một số lợi ích khi sử dụng Jest, ví dụ, các bài kiểm tra Jest chạy song song, bao gồm khả năng phủ mã tích hợp và hỗ trợ các bài kiểm tra riêng biệt, kiểm tra mô phỏng và ảnh chụp nhanh.
Bạn có thể khởi tạo thử nghiệm bằng cách tạo cửa hàng, gắn Vuex vào Vue và đăng ký cửa hàng. localVue
là hàm tạo Vue phạm vi mà chúng ta có thể thay đổi mà không ảnh hưởng đến hàm tạo Vue toàn cục. Đoạn mã dưới đây sẽ khởi tạo cửa hàng:
describe('Todos Module', function() {
let store: any;
let todosInstance: ToDoModule;
beforeEach(function() {
localVue.use(Vuex);
store = new Vuex.Store({});
registerStoreModules(store);
todosInstance = getModule(ToDoModule, store);
});
it('should exists', function() {
expect(todosInstance).toBeDefined();
});
});
Trong todos
mô-đun, chúng tôi đã tạo fetchTodos
hành động tìm nạp dữ liệu từ API REST và lấp đầy trạng thái bằng cách sử dụng các đột biến. Vì REST API là một lệnh gọi bên ngoài, chúng ta có thể mô phỏng nó bằng cách sử dụng hàm Jest, sau đó xác thực xem nó có đang được gọi hay không và trạng thái đang được cập nhật:
it('fetchTodos action should fill todos state', async function() {
// arrange
const todosMocked = todos as Array<IToDo>;
// act
jest.spyOn(TodoActions, 'fetchTodos').mockImplementation(
(): Promise<Array<IToDo>> => {
return Promise.resolve(todosMocked);
}
);
await todosInstance.fetchTodos();
// assert
expect(todosInstance.todos.length >0).toEqual(true);
expect(TodoActions.fetchTodos).toHaveBeenCalled();
});
Các hàm Getter chỉ đơn giản là trả về đối tượng trạng thái. Trong ví dụ của chúng tôi, chúng tôi có một hàm getter, hàm completedTodos
này sẽ trả về các mục việc cần làm đã hoàn thành:
it('completedTodos getter should return only completed todos', async function() {
// arrange
const completedTodos = todosInstance.completedTodos;
// assert
expect(completedTodos.every((todo:IToDo)=> todo.completed)).toEqual(true);
});
Như chúng ta đã biết, đột biến là cách duy nhất để thay đổi trạng thái. Chúng tôi có thể kiểm tra sự ON_FETCH_TODOS_SUCCESS
đột biến bằng cách gửi các nhiệm vụ cần làm giả và xác nhận xem trạng thái có được sửa đổi hay không.
Đoạn mã dưới đây dành cho success
đột biến. Điều tương tự cũng áp dụng cho các đột biến started
và error
:
it('ON_FETCH_TODOS_SUCCESS mutation should update given todos', function() {
// arrange
const todosTest = [
{
userId: 13,
id: 12,
title: "Move to new city",
completed: false
},
{
userId: 15,
id: 21,
title: "Finish a novel",
completed: true
},
];
// act
todosInstance.ON_FETCH_TODOS_SUCCESS(todosTest);
// assert
expect(todosInstance.todos.length).toEqual(2);
expect(todosInstance.todos).toEqual(todosTest);
});
Trong hướng dẫn này, chúng ta đã tìm hiểu về Vuex bằng cách tạo và thử nghiệm đơn vị mô-đun Vuex với TypeScript và Jest. Chúng tôi đã đề cập đến bốn khái niệm cốt lõi của cửa hàng Vuex, bao gồm trạng thái, getters, đột biến và hành động. Với quản lý trạng thái tập trung của Vuex, bạn có thể đơn giản hóa ứng dụng của mình và tận dụng lợi thế của kiến trúc giống Flux.
Tôi hy vọng bạn đã học được điều gì đó mới và hãy để lại bình luận nếu bạn có bất kỳ câu hỏi nào. Chúc bạn viết mã vui vẻ!
Nguồn: https://blog.logrocket.com/unit-testing-vuex-modules-jest/
1660296329
If you’re building a medium to large-scale SPA, chances are you’ll run into situations where you want to better handle the state of your Vue components.
In any application, multiple components depend on the same piece of state. Let’s imagine that multiple actions from different components would like to mutate the same state. To overcome these challenges, Vuex helps us to maintain state across the application.
In this article, I’ll guide you through implementing a Vuex module in TypeScript, then unit testing it using Jest. The complete code for this tutorial is available at the vuex-test GitHub repository; feel free to fork it. Let’s get started!
See more at: https://blog.logrocket.com/unit-testing-vuex-modules-jest/
1657180680
Trong hướng dẫn laravel vue js này, tôi sẽ chỉ cho bạn một ví dụ thiết lập hoàn chỉnh về cách thiết lập vue js, vuex và vue router trong ứng dụng Laravel. Sử dụng thiết lập bộ định tuyến vue js, vuex và vue này, bạn sẽ biết cách tạo một ứng dụng trang duy nhất bằng laravel và vue js.
Tôi sẽ hướng dẫn bạn từng bước để bạn có thể hiểu được. Tôi sẽ đưa ra một ví dụ hoàn chỉnh về hướng dẫn laravel vuex và cũng có thể cài đặt vuex trong ứng dụng laravel. Sau đó, chúng tôi sẽ cài đặt bộ định tuyến vue trong Laravel.
Vì vậy, trong ví dụ này, chúng ta sẽ cài đặt vue js trong laravel, sau đó chúng ta sẽ cài đặt vuex trong laravel, sau đó chúng ta sẽ cài đặt vue router trong laravel. Sau đó, chúng tôi sẽ chỉ cho bạn một ví dụ đơn giản về cách sử dụng vuex trong laravel bằng cách tạo bộ đếm bằng vuex.
Setp 1: Tải xuống Laravel
Trước hết, hãy tải xuống một dự án Laravel mới bằng lệnh sau:
laravel new laravel-vue
Bước 2: Cài đặt các gói bắt buộc
Chúng tôi cần cài đặt một số gói bắt buộc dưới dạng phụ thuộc của nhà phát triển.
npm i
Sau đó chạy
yarn add -D vue vue-template-compiler vue-router vuex sass sass-loader
or using npm
npm install --save-dev vue vue-template-compiler vue-router vuex sass sass-loader
Bây giờ, hãy tạo một cấu trúc thư mục như sau:
resources/
-assets/
--css
--js/
---Components/
----Pages/
-----Home.vue
-----About.vue
----Header/
-----Navbar.vue
---Mixins
---Router/
----index.js
----routes.js
---Store/
----index.js
---Styles/
----app.scss
App.vue
app.js
bootstrap.js
Bước 3: Tạo bộ định tuyến Vue
Chúng tôi đã cài đặt bộ định tuyến vue. Bây giờ chúng ta phải tạo các tuyến đường cho ứng dụng trang đơn của chúng ta trong laravel vue js. Vì vậy, hãy cập nhật tệp sau:
resources/assets/js/Router/routes.js
const routes = [
{
path: '/',
component: () => import('../Components/Pages/Home.vue'),
name: 'home'
},
{
path: '/about',
component: () => import('../Components/Pages/About.vue'),
name: 'about'
}
]
export default routes;
Tiếp theo, chúng tôi sẽ thiết lập một thể hiện Vue Router trong tệp index.js (bên trong thư mục Router) và xuất thể hiện đó.
resources/assets/js/Router/index.js
import VueRouter from 'vue-router';
import routes from './routes';
const router = new VueRouter({
mode: 'history',
routes,
});
export default router;
Bước 4: Thiết lập Vuex
Trong bước này, chúng ta phải thiết lập vuex trong laravel. Vì vậy, hãy làm những việc sau:
resources/assets/js/Store/index.js
import Vue from 'vue';
import Vuex from 'vuex'
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
count: 0,
},
mutations: {
INCREMENT(state) {
state.count++
},
},
actions: {}
})
export default store;
Bây giờ hãy mở app.js và cập nhật nó như:
resources/assets/js/app.js
require('./bootstrap')
import Vue from 'vue'
import VueRouter from 'vue-router';
import router from './Router/index'
import store from './Store/index';
import App from './App.vue'
Vue.use(VueRouter)
const app = new Vue({
el: '#app',
router,
store,
components: {App}
});
Bước 5: Thiết lập bộ định tuyến Vue
Bây giờ trong bước này, chúng ta phải thiết lập bộ định tuyến vue. Tại thời điểm này, chúng tôi có thể thiết lập tất cả các thành phần cần thiết. App.vue là thành phần nhập giống như bạn sẽ thấy trong thiết lập phiên bản Vue của chúng tôi, vì vậy chúng tôi sẽ có thành phần router-view ở đây.
resources/assets/js/App.vue
<template lang="">
<div class="app">
<Navbar></Navbar>
<router-view></router-view>
</div>
</template>
<script>
import './Styles/app.scss'
export default {
name: 'app',
components: {
Navbar: () => import('./Components/Header/Navbar.vue')
}
}
</script>
Và cập nhật thành phần Navbar như: Nó sẽ giống như sau:
resources/assets/js/Components/Header/Navbar.vue
<template lang="">
<nav class="navBar">
<ul class="navBar_link">
<li><router-link :to="{name:'home'}">Home</router-link></li>
<li><router-link :to="{name:'about'}">About</router-link></li>
</ul>
</nav>
</template>
<script>
export default {
name: 'navbar'
}
</script>
<style lang="">
</style>
Bây giờ cập nhật tất cả các trang như:
resources/assets/js/Components/Pages/About.vue
<template lang="">
<div>
<h1>About</h1>
</div>
</template>
<script>
export default {
name: 'about'
}
</script>
<style lang="">
</style>
Bây giờ cập nhật trang chủ như:
resources/assets/js/Components/Pages/Home.vue
<template lang="">
<div>
{{ count }}
<h1>Home</h1>
<button class="button" @click="$store.commit('INCREMENT')">INCREMENT </button>
</div>
</template>
<script>
import {mapState} from 'vuex'
export default {
name: 'home',
computed: {
...mapState({
count: state => state.count
})
}
}
</script>
<style lang="">
</style>
Bước 6: Thiết lập Laravel
Chúng tôi sẽ cập nhật tệp welcome.blade.php bên trong resources/views
. Cập nhật nó như:
resources/views/welcome.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
<link rel="stylesheet" href="{{ mix('css/app.css') }}">
</head>
<body>
<div id="id">
<app></app>
</div>
<script src="{{ mix('js/app.js') }}"></script>
</body>
</html>
Cuối cùng, chúng tôi sẽ cập nhật tệp web.php như:
routes/web.php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/{any?}', function () {
return view('welcome');
});
Bây giờ gần như chúng tôi đã sẵn sàng để đi. Cập nhật webpack.mix.js như:
webpack.mix.js
const mix = require('laravel-mix');
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel application. By default, we are compiling the Sass
| file for the application as well as bundling up all the JS files.
|
*/
mix.js('resources/assets/js/app.js', 'public/js')
.vue()
.sass('resources/assets/sass/app.scss', 'public/css');
Bây giờ chạy npm run watch
và php artisan serve
để kiểm tra nó. Hy vọng nó có thể giúp bạn.
Nguồn: https://www.codecheef.org
1657133820
В этом руководстве по laravel vue js я покажу вам полный пример настройки того, как настроить vue js, vuex и vue router в приложении Laravel. Используя эту настройку vue js, vuex и vue router, вы узнаете, как создать одностраничное приложение с использованием laravel и vue js.
Я буду вести вас шаг за шагом, чтобы вы могли понять. Я приведу полный пример руководства по laravel vuex, а также установлю vuex в приложении laravel. После этого мы установим vue router в Laravel.
Итак, в этом примере мы установим vue js в laravel, затем мы установим vuex в laravel, затем мы установим vue router в laravel. После этого мы покажем вам простой пример того, как использовать vuex в laravel, создав счетчик с помощью vuex.
Шаг 1: Загрузите Laravel
Прежде всего, загрузите свежий проект Laravel с помощью следующей команды:
laravel new laravel-vue
Шаг 2. Установите необходимые пакеты
Нам нужно установить некоторые необходимые пакеты в качестве зависимостей для разработчиков.
npm i
Затем запустите
yarn add -D vue vue-template-compiler vue-router vuex sass sass-loader
or using npm
npm install --save-dev vue vue-template-compiler vue-router vuex sass sass-loader
Теперь создайте такую структуру папок:
resources/
-assets/
--css
--js/
---Components/
----Pages/
-----Home.vue
-----About.vue
----Header/
-----Navbar.vue
---Mixins
---Router/
----index.js
----routes.js
---Store/
----index.js
---Styles/
----app.scss
App.vue
app.js
bootstrap.js
Шаг 3: Создайте маршрутизатор Vue
Мы установили vue router. Теперь нам нужно создать маршруты для нашего одностраничного приложения в laravel vue js. Поэтому обновите следующий файл:
resources/assets/js/Router/routes.js
const routes = [
{
path: '/',
component: () => import('../Components/Pages/Home.vue'),
name: 'home'
},
{
path: '/about',
component: () => import('../Components/Pages/About.vue'),
name: 'about'
}
]
export default routes;
Далее мы настроим экземпляр Vue Router в файле index.js (внутри папки Router) и экспортируем экземпляр.
resources/assets/js/Router/index.js
import VueRouter from 'vue-router';
import routes from './routes';
const router = new VueRouter({
mode: 'history',
routes,
});
export default router;
Шаг 4: Настройте Vuex
На этом этапе нам нужно настроить vuex в laravel. Итак, сделайте следующее:
resources/assets/js/Store/index.js
import Vue from 'vue';
import Vuex from 'vuex'
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
count: 0,
},
mutations: {
INCREMENT(state) {
state.count++
},
},
actions: {}
})
export default store;
Теперь откройте app.js и обновите его, например:
resources/assets/js/app.js
require('./bootstrap')
import Vue from 'vue'
import VueRouter from 'vue-router';
import router from './Router/index'
import store from './Store/index';
import App from './App.vue'
Vue.use(VueRouter)
const app = new Vue({
el: '#app',
router,
store,
components: {App}
});
Шаг 5: Настройте маршрутизатор Vue
Теперь на этом этапе нам нужно настроить vue router. На этом этапе мы можем настроить все необходимые компоненты. App.vue — это компонент входа, который вы увидите в нашей настройке экземпляра Vue, поэтому здесь у нас будет компонент router-view .
resources/assets/js/App.vue
<template lang="">
<div class="app">
<Navbar></Navbar>
<router-view></router-view>
</div>
</template>
<script>
import './Styles/app.scss'
export default {
name: 'app',
components: {
Navbar: () => import('./Components/Header/Navbar.vue')
}
}
</script>
И обновите компонент Navbar следующим образом: Это будет выглядеть примерно так:
resources/assets/js/Components/Header/Navbar.vue
<template lang="">
<nav class="navBar">
<ul class="navBar_link">
<li><router-link :to="{name:'home'}">Home</router-link></li>
<li><router-link :to="{name:'about'}">About</router-link></li>
</ul>
</nav>
</template>
<script>
export default {
name: 'navbar'
}
</script>
<style lang="">
</style>
Теперь обновите все страницы, например:
resources/assets/js/Components/Pages/About.vue
<template lang="">
<div>
<h1>About</h1>
</div>
</template>
<script>
export default {
name: 'about'
}
</script>
<style lang="">
</style>
Теперь обновите домашнюю страницу, например:
resources/assets/js/Components/Pages/Home.vue
<template lang="">
<div>
{{ count }}
<h1>Home</h1>
<button class="button" @click="$store.commit('INCREMENT')">INCREMENT </button>
</div>
</template>
<script>
import {mapState} from 'vuex'
export default {
name: 'home',
computed: {
...mapState({
count: state => state.count
})
}
}
</script>
<style lang="">
</style>
Шаг 6: Настройте Laravel
Мы обновим файл welcome.blade.php внутри resources/views
. Обновите его как:
resources/views/welcome.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
<link rel="stylesheet" href="{{ mix('css/app.css') }}">
</head>
<body>
<div id="id">
<app></app>
</div>
<script src="{{ mix('js/app.js') }}"></script>
</body>
</html>
Наконец, мы обновим файл web.php следующим образом:
routes/web.php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/{any?}', function () {
return view('welcome');
});
Теперь мы почти готовы к работе. Обновите webpack.mix.js, например:
webpack.mix.js
const mix = require('laravel-mix');
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel application. By default, we are compiling the Sass
| file for the application as well as bundling up all the JS files.
|
*/
mix.js('resources/assets/js/app.js', 'public/js')
.vue()
.sass('resources/assets/sass/app.scss', 'public/css');
Теперь запустите npm run watch
и php artisan serve
протестируйте его. Надеюсь, это поможет вам.
Источник: https://www.codecheef.org
1657126380
Dans ce didacticiel laravel vue js, je vais vous montrer un exemple de configuration complet de la configuration de vue js, vuex et vue router dans l'application Laravel. À l'aide de cette configuration vue js, vuex et vue router, vous saurez comment créer une application d'une seule page à l'aide de laravel et vue js.
Je vais vous guider étape par étape afin que vous puissiez comprendre. Je vais donner un exemple complet de tutoriel laravel vuex et installer également vuex dans l'application laravel. Après cela, nous installerons le routeur vue dans Laravel.
Donc dans cet exemple, nous installerons vue js dans laravel, puis nous installerons vuex dans laravel puis nous installerons vue router dans laravel. Après cela, nous vous montrerons un exemple simple d'utilisation de vuex dans laravel en créant un compteur à l'aide de vuex.
Étape 1 : Télécharger Laravel
Tout d'abord, téléchargez un nouveau projet Laravel avec la commande suivante :
laravel new laravel-vue
Étape 2 : Installer les packages requis
Nous devons installer certains packages requis en tant que dépendances de développement.
npm i
Puis cours
yarn add -D vue vue-template-compiler vue-router vuex sass sass-loader
or using npm
npm install --save-dev vue vue-template-compiler vue-router vuex sass sass-loader
Créez maintenant une structure de dossiers comme celle-ci :
resources/
-assets/
--css
--js/
---Components/
----Pages/
-----Home.vue
-----About.vue
----Header/
-----Navbar.vue
---Mixins
---Router/
----index.js
----routes.js
---Store/
----index.js
---Styles/
----app.scss
App.vue
app.js
bootstrap.js
Étape 3 : Créer un routeur Vue
Nous avons installé le routeur vue. Nous devons maintenant créer des itinéraires pour notre application à page unique dans laravel vue js. Mettez donc à jour le fichier suivant :
resources/assets/js/Router/routes.js
const routes = [
{
path: '/',
component: () => import('../Components/Pages/Home.vue'),
name: 'home'
},
{
path: '/about',
component: () => import('../Components/Pages/About.vue'),
name: 'about'
}
]
export default routes;
Ensuite, nous allons configurer une instance Vue Router dans le fichier index.js (dans le dossier Router) et exporter l'instance.
resources/assets/js/Router/index.js
import VueRouter from 'vue-router';
import routes from './routes';
const router = new VueRouter({
mode: 'history',
routes,
});
export default router;
Étape 4 : Configurer Vuex
Dans cette étape, nous devons configurer vuex dans laravel. Alors faites les choses suivantes :
resources/assets/js/Store/index.js
import Vue from 'vue';
import Vuex from 'vuex'
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
count: 0,
},
mutations: {
INCREMENT(state) {
state.count++
},
},
actions: {}
})
export default store;
Maintenant, ouvrez app.js et mettez-le à jour comme :
resources/assets/js/app.js
require('./bootstrap')
import Vue from 'vue'
import VueRouter from 'vue-router';
import router from './Router/index'
import store from './Store/index';
import App from './App.vue'
Vue.use(VueRouter)
const app = new Vue({
el: '#app',
router,
store,
components: {App}
});
Étape 5 : Configuration du routeur Vue
Maintenant, dans cette étape, nous devons configurer le routeur vue. À ce stade, nous pouvons configurer tous les composants requis. L'App.vue est le composant d'entrée comme vous le verrez dans notre configuration d'instance Vue, à cause de cela, nous aurons le composant router-view ici.
resources/assets/js/App.vue
<template lang="">
<div class="app">
<Navbar></Navbar>
<router-view></router-view>
</div>
</template>
<script>
import './Styles/app.scss'
export default {
name: 'app',
components: {
Navbar: () => import('./Components/Header/Navbar.vue')
}
}
</script>
Et mettez à jour le composant Navbar comme suit : Il ressemblera à ceci :
resources/assets/js/Components/Header/Navbar.vue
<template lang="">
<nav class="navBar">
<ul class="navBar_link">
<li><router-link :to="{name:'home'}">Home</router-link></li>
<li><router-link :to="{name:'about'}">About</router-link></li>
</ul>
</nav>
</template>
<script>
export default {
name: 'navbar'
}
</script>
<style lang="">
</style>
Maintenant, mettez à jour toutes les pages comme :
resources/assets/js/Components/Pages/About.vue
<template lang="">
<div>
<h1>About</h1>
</div>
</template>
<script>
export default {
name: 'about'
}
</script>
<style lang="">
</style>
Maintenant, mettez à jour la page d'accueil comme :
resources/assets/js/Components/Pages/Home.vue
<template lang="">
<div>
{{ count }}
<h1>Home</h1>
<button class="button" @click="$store.commit('INCREMENT')">INCREMENT </button>
</div>
</template>
<script>
import {mapState} from 'vuex'
export default {
name: 'home',
computed: {
...mapState({
count: state => state.count
})
}
}
</script>
<style lang="">
</style>
Étape 6 : Configurer Laravel
Nous mettrons à jour le fichier welcome.blade.php dans resources/views
. Mettez-le à jour comme :
resources/views/welcome.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
<link rel="stylesheet" href="{{ mix('css/app.css') }}">
</head>
<body>
<div id="id">
<app></app>
</div>
<script src="{{ mix('js/app.js') }}"></script>
</body>
</html>
Enfin, nous mettrons à jour le fichier web.php comme :
routes/web.php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/{any?}', function () {
return view('welcome');
});
Maintenant presque nous sommes prêts à partir. Mettez à jour webpack.mix.js comme :
webpack.mix.js
const mix = require('laravel-mix');
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel application. By default, we are compiling the Sass
| file for the application as well as bundling up all the JS files.
|
*/
mix.js('resources/assets/js/app.js', 'public/js')
.vue()
.sass('resources/assets/sass/app.scss', 'public/css');
Maintenant, exécutez npm run watch
et php artisan serve
testez-le. J'espère que ça peut t'aider.
Source : https://www.codecheef.org
1657122660
En este tutorial de laravel vue js, le mostraré un ejemplo de configuración completo de cómo configurar el enrutador vue js, vuex y vue en la aplicación Laravel. Usando esta configuración de enrutador vue js, vuex y vue, sabrá cómo crear una aplicación de una sola página usando laravel y vue js.
Te guiaré paso a paso para que puedas entender. Daré un ejemplo completo del tutorial de laravel vuex y también instalaré vuex en la aplicación laravel. Después de eso, instalaremos el enrutador vue en Laravel.
Entonces, en este ejemplo, instalaremos vue js en laravel, luego instalaremos vuex en laravel y luego instalaremos vue router en laravel. Después de eso, le mostraremos un ejemplo simple de cómo usar vuex en laravel creando un contador usando vuex.
Paso 1: Descargar Laravel
En primer lugar, descargue un nuevo proyecto de Laravel con el siguiente comando:
laravel new laravel-vue
Paso 2: Instale los paquetes necesarios
Necesitamos instalar algunos paquetes requeridos como dependencias de desarrollo.
npm i
Entonces corre
yarn add -D vue vue-template-compiler vue-router vuex sass sass-loader
or using npm
npm install --save-dev vue vue-template-compiler vue-router vuex sass sass-loader
Ahora crea una estructura de carpetas como esa:
resources/
-assets/
--css
--js/
---Components/
----Pages/
-----Home.vue
-----About.vue
----Header/
-----Navbar.vue
---Mixins
---Router/
----index.js
----routes.js
---Store/
----index.js
---Styles/
----app.scss
App.vue
app.js
bootstrap.js
Paso 3: Crear enrutador Vue
Hemos instalado el enrutador vue. Ahora tenemos que crear rutas para nuestra aplicación de una sola página en laravel vue js. Así que actualice el siguiente archivo:
resources/assets/js/Router/routes.js
const routes = [
{
path: '/',
component: () => import('../Components/Pages/Home.vue'),
name: 'home'
},
{
path: '/about',
component: () => import('../Components/Pages/About.vue'),
name: 'about'
}
]
export default routes;
A continuación, configuraremos una instancia de Vue Router en el archivo index.js (dentro de la carpeta del enrutador) y exportaremos la instancia.
resources/assets/js/Router/index.js
import VueRouter from 'vue-router';
import routes from './routes';
const router = new VueRouter({
mode: 'history',
routes,
});
export default router;
Paso 4: configurar Vuex
En este paso, tenemos que configurar vuex en laravel. Así que haz lo siguiente:
resources/assets/js/Store/index.js
import Vue from 'vue';
import Vuex from 'vuex'
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
count: 0,
},
mutations: {
INCREMENT(state) {
state.count++
},
},
actions: {}
})
export default store;
Ahora abra app.js y actualícelo como:
resources/assets/js/app.js
require('./bootstrap')
import Vue from 'vue'
import VueRouter from 'vue-router';
import router from './Router/index'
import store from './Store/index';
import App from './App.vue'
Vue.use(VueRouter)
const app = new Vue({
el: '#app',
router,
store,
components: {App}
});
Paso 5: Configurar el enrutador Vue
Ahora, en este paso, tenemos que configurar el enrutador vue. En este punto, podemos configurar todos los componentes necesarios. App.vue es el componente de entrada como verá en nuestra configuración de instancia de Vue, por eso tendremos el componente de vista de enrutador aquí.
resources/assets/js/App.vue
<template lang="">
<div class="app">
<Navbar></Navbar>
<router-view></router-view>
</div>
</template>
<script>
import './Styles/app.scss'
export default {
name: 'app',
components: {
Navbar: () => import('./Components/Header/Navbar.vue')
}
}
</script>
Y actualice el componente Navbar como: Se verá así:
resources/assets/js/Components/Header/Navbar.vue
<template lang="">
<nav class="navBar">
<ul class="navBar_link">
<li><router-link :to="{name:'home'}">Home</router-link></li>
<li><router-link :to="{name:'about'}">About</router-link></li>
</ul>
</nav>
</template>
<script>
export default {
name: 'navbar'
}
</script>
<style lang="">
</style>
Ahora actualice todas las páginas como:
resources/assets/js/Components/Pages/About.vue
<template lang="">
<div>
<h1>About</h1>
</div>
</template>
<script>
export default {
name: 'about'
}
</script>
<style lang="">
</style>
Ahora actualice la página de inicio como:
resources/assets/js/Components/Pages/Home.vue
<template lang="">
<div>
{{ count }}
<h1>Home</h1>
<button class="button" @click="$store.commit('INCREMENT')">INCREMENT </button>
</div>
</template>
<script>
import {mapState} from 'vuex'
export default {
name: 'home',
computed: {
...mapState({
count: state => state.count
})
}
}
</script>
<style lang="">
</style>
Paso 6: Configurar Laravel
Actualizaremos el archivo welcome.blade.php dentro de resources/views
. Actualízalo como:
resources/views/welcome.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
<link rel="stylesheet" href="{{ mix('css/app.css') }}">
</head>
<body>
<div id="id">
<app></app>
</div>
<script src="{{ mix('js/app.js') }}"></script>
</body>
</html>
Finalmente, actualizaremos el archivo web.php como:
routes/web.php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/{any?}', function () {
return view('welcome');
});
Ahora casi estamos listos para irnos. Actualice webpack.mix.js como:
webpack.mix.js
const mix = require('laravel-mix');
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel application. By default, we are compiling the Sass
| file for the application as well as bundling up all the JS files.
|
*/
mix.js('resources/assets/js/app.js', 'public/js')
.vue()
.sass('resources/assets/sass/app.scss', 'public/css');
Ahora ejecuta npm run watch
y php artisan serve
prueba. Espero que te ayude.
Fuente: https://www.codecheef.org