Bongani  Ngema

Bongani Ngema

1674928680

Vuefire: Firebase bindings for Vue.js

Vuefire

Firebase for Vue made easy!

  • Works with Vue >=2.7 and Vue 3
  • Supports Composition and Options API
  • Supports Vuex, Pinia, and anything that gives you a Vue ref()
  • Built for Firebase 9 for optimal tree shaking
  • Automatically listen for changes in nested references

Status

  • VueFire is currently stable
  • Nuxt VueFire is in Preview

Roadmap

You can follow the progress and future plans on the Roadmap issue.

Installation

VueFire requires the firebase package to be installed as well as vuefire:

npm install vuefire firebase

Usage

Related

📚 Documentation

Download Details:

Author: Vuejs
Source Code: https://github.com/vuejs/vuefire 
License: MIT license

#firebase #database #vue #realtime #vuex 

Vuefire: Firebase bindings for Vue.js
Lawrence  Lesch

Lawrence Lesch

1674884580

TypeScript/ES7 Decorators to Create Vuex Modules Declaratively

Vuex-module-decorators

Typescript/ES7 Decorators to make Vuex modules a breeze

Installation

npm install -D vuex-module-decorators

Babel 6/7

NOTE This is not necessary for vue-cli@3 projects, since @vue/babel-preset-app already includes this plugin

  • You need to install babel-plugin-transform-decorators

TypeScript

  • set experimentalDecorators to true
  • For reduced code with decorators, set importHelpers: true in tsconfig.json
  • (only for TypeScript 2) set emitHelpers: true in tsconfig.json

Configuration

Using with 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']
}

Usage

The conventional old & boring way

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
  }
})

Hello Decorators !

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
  }
}

async MutationAction === magic

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
  }
}

Automatic getter detection

@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
  }
}

Putting into the store

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
  }
})

Module re-use, use with NuxtJS

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
  }
}

Dynamic Modules

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 {

...

Accessing modules with NuxtJS

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
}

Using the decorators with ServerSideRender

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

Example

// 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')
    }
}

Configuration

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/

Patrons

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 😇 ❤️

CHANGELOG

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

Examples

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 -


Download Details:

Author: Championswimmer
Source Code: https://github.com/championswimmer/vuex-module-decorators 
License: MIT license

#typescript #javascript #vuej #vuex 

TypeScript/ES7 Decorators to Create Vuex Modules Declaratively

Built Complete Vue 3/Vuex Application | Build Recipe and Meal Search Application using Vue.js

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 

Subscribe: https://www.youtube.com/@TheCodeholic/featured 

#vue #vuej #vuex 

Built Complete Vue 3/Vuex Application | Build Recipe and Meal Search Application using Vue.js
Reid  Rohan

Reid Rohan

1667107740

A modern vue admin. It is based on Vue3, vite & TypeScript. It's fast!

Vue vben admin

Introduction

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.

Feature

  • State of The Art Development:Use front-end front-end technology development such as Vue3/vite2
  • TypeScript: Application-level JavaScript language
  • Theming: Configurable themes
  • International:Built-in complete internationalization program
  • Mock Server Built-in mock data scheme
  • Authority Built-in complete dynamic routing permission generation scheme.
  • Component Multiple commonly used components are encapsulated twice

Preview

Test account: vben/123456

VbenAdmin Logo VbenAdmin Logo VbenAdmin Logo

Use Gitpod

Open the project in Gitpod (free online dev environment for GitHub) and start coding immediately.

Open in Gitpod

Documentation

Document

Preparation

  • node and git - Project development environment
  • Vite - Familiar with vite features
  • Vue3 - Familiar with Vue basic syntax
  • TypeScript - Familiar with the basic syntax of TypeScript
  • Es6+ - Familiar with es6 basic syntax
  • Vue-Router-Next - Familiar with the basic use of vue-router
  • Ant-Design-Vue - ui basic use
  • Mock.js - mockjs basic syntax

Install and use

  • Get the project code
git clone https://github.com/anncwb/vue-vben-admin.git
  • Installation dependencies
cd vue-vben-admin

pnpm install
  • run
pnpm serve
  • build
pnpm build

Change Log

CHANGELOG

Project

How to contribute

You are very welcome to join!Raise an issue Or submit a Pull Request。

Pull Request:

  1. Fork code!
  2. Create your own branch: git checkout -b feat/xxxx
  3. Submit your changes: git commit -am 'feat(function): add xxxxx'
  4. Push your branch: git push origin feat/xxxx
  5. submitpull request

Git Contribution submission specification

reference vue specification (Angular)

  • feat Add new features
  • fix Fix the problem/BUG
  • style The code style is related and does not affect the running result
  • perf Optimization/performance improvement
  • refactor Refactor
  • revert Undo edit
  • test Test related
  • docs Documentation/notes
  • chore Dependency update/scaffolding configuration modification etc.
  • workflow Workflow improvements
  • ci Continuous integration
  • types Type definition file changes
  • wip In development

Related warehouse

If these plugins are helpful to you, you can give a star support

Browser support

The Chrome 80+ browser is recommended for local development

Support modern browsers, not IE

Edge
IE
Edge
Edge
Firefox
Firefox
Chrome
Chrome
Safari
Safari
not supportlast 2 versionslast 2 versionslast 2 versionslast 2 versions

Maintainer

@Vben

Discord

English | 中文

Download Details:

Author: vbenjs
Source Code: https://github.com/vbenjs/vue-vben-admin 
License: MIT license

#typescript #javascript #vuex #vue

A modern vue admin. It is based on Vue3, vite & TypeScript. It's fast!
藤本  結衣

藤本 結衣

1660393320

Jest を使用した Vuex モジュールの単体テスト

中規模から大規模の SPA を構築している場合、Vue コンポーネントの状態をより適切に処理したい状況に遭遇する可能性があります。

どのアプリケーションでも、複数のコンポーネントが同じ状態に依存しています。異なるコンポーネントからの複数のアクションが同じ状態を変更したいと考えてみましょう。これらの課題を克服するために、Vuexはアプリケーション全体で状態を維持するのに役立ちます。

この記事では、TypeScript で Vuex モジュールを実装し、Jest を使用してユニット テストを行う方法を説明します。このチュートリアルの完全なコードは、vuex-test GitHub リポジトリで入手できます。気軽にフォークしてください。始めましょう!

Vuexとは?

Vuex は、Vue アプリケーションの状態管理パターンおよびライブラリであり、アプリケーションで集中状態管理を使用できるようにし、Flux のようなアーキテクチャを活用するのに役立ちます。Vuex ストアには、次の4 つのコア コンセプトが含まれています。

  1. ゲッター
  2. 突然変異
  3. 行動

状態オブジェクトには、すべてのアプリケーション レベルの状態を含め、ストアに保持するデータが含まれており、信頼できる唯一の情報源として機能します。状態で定義されるプロパティは、文字列、数値、オブジェクト、配列など、任意のデータ型にすることができます。

アイテムのリストを数えたり、コレクションをフィルタリングしたり、他のモジュールやコンポーネントで同じ一連の派生状態を使用したりするなど、ストアの状態に基づいて派生状態が必要な場合は、getter を定義できます。

一方、突然変異は、状態を変更できる唯一の方法です。ミューテーションは常に同期的であり、ペイロードはオプションです。コミット、つまり、MUTATION_NAMEまたはを介し​​てミューテーションを呼び出すことができますpayload。アクションからミューテーションを呼び出すことを常にお勧めします。

アクションは、非同期操作を実行し、ミューテーションをコミットできます。アクション ハンドラーは、ストア インスタンスで同じメソッドまたはプロパティのセットを公開するコンテキスト オブジェクトを受け取ります。

とを使用context.getterscontext.stateて状態を取得し、context.commitミューテーションを呼び出すことができます。action-nameとを使用してアクション ハンドラーを呼び出すことができますpayload。これらは、ストア内の他のアクションから呼び出されます。

Vuex モジュール図

Vuex アーキテクチャ

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
  • completedTodosgetter: 完了した 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/ 

#jest #vuex 

Jest を使用した Vuex モジュールの単体テスト
曾 俊

曾 俊

1660310669

使用 Jest 对 Vuex 模块进行单元测试

如果您正在构建一个中型到大型的 SPA,您很可能会遇到想要更好地处理 Vue 组件状态的情况。

在任何应用程序中,多个组件都依赖于同一个状态。让我们假设来自不同组件的多个动作想要改变相同的状态。为了克服这些挑战,Vuex帮助我们维护整个应用程序的状态。

在本文中,我将指导您在TypeScript 中实现一个 Vuex 模块,然后使用 Jest 对其进行单元测试。本教程的完整代码可在vuex-test GitHub 存储库中获得;随意分叉它。让我们开始吧!

什么是 Vuex?

Vuex 是Vue 应用程序的状态管理模式和库,允许您在应用程序中使用集中状态管理,帮助您利用类似 Flux 的架构。Vuex store包含四个核心概念:

  1. 状态
  2. 吸气剂
  3. 突变
  4. 行动

状态对象包含您希望在存储中拥有的数据,包括您的所有应用程序级状态,作为唯一的事实来源。状态中定义的属性可以是任何数据类型,包括字符串、数字、对象或数组。

如果您想根据存储状态获得派生状态,例如,计算项目列表、过滤集合或在其他模块或组件中使用相同的派生状态集,您可以定义 getters

另一方面,突变是我们改变状态的唯一方法。突变总是同步的,有效载荷是可选的。您可以通过提交,即MUTATION_NAMEpayload. 始终建议从动作中调用突变。

动作可以执行异步操作并提交突变。动作处理程序接收一个上下文对象,该对象在存储实例上公开相同的方法或属性集。

您可以使用context.gettersandcontext.state来获取状态并context.commit调用突变。action-name您可以使用和调用动作处理程序payload,它们是从商店中的其他动作调用的。

Vuex 模块图

Vuex 架构

创建一个 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为假
  • completedTodosgetter:仅获取已完成的待办事项

初始化测试

我们将使用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突变。这同样适用于startedanderror突变:

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/

 #jest #vuex 

使用 Jest 对 Vuex 模块进行单元测试
Léon  Peltier

Léon Peltier

1660306812

Test Unitaire Des Modules Vuex Avec Jest

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!

Qu'est-ce que Vuex ?

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 :

  1. État
  2. Getters
  3. mutation
  4. Actions

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_NAMEou 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.getterset context.statepour obtenir l'état et context.commitappeler des mutations. Vous pouvez appeler des gestionnaires d'action à l'aide de action-nameet payload, et ils sont appelés à partir d'autres actions du magasin.

Schéma des modules Vuex

Architecture Vuex

Créer un module 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 fonction
  • actions.ts: Responsable de toutes les opérations asynchrones
  • index.ts: L'implémentation du module
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);
        }
  }

}

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 mutations
  • ON_FETCH_TODOS_STARTEDmutation : met à jour l' loadingattribut d'état
  • ON_FETCH_TODOS_SUCCESSmutation : met à jour le todostableau d'état
  • ON_FETCH_TODOS_FAILEDmutation : Réinitialise todoset met à jour loadingcomme faux
  • completedTodosgetter : Obtient uniquement les éléments à faire qui sont terminés

Initialiser les tests

Nous 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. localVueest 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();
    });
});

Actions de test

Dans le todosmodule, nous avons créé l' fetchTodosaction, 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();
});

Tester les getters

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);
    });

Tester les mutations

Comme nous le savons déjà, les mutations sont le seul moyen de changer l'état. Nous pouvons tester la ON_FETCH_TODOS_SUCCESSmutation en envoyant des tâches fictives et en validant si l'état est modifié.

L'extrait de code ci-dessous est pour la  successmutation. Il en va de même pour les mutations startedet :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);
    });

Conclusion

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/

 #jest #vuex 

Test Unitaire Des Modules Vuex Avec Jest
Mélanie  Faria

Mélanie Faria

1660306440

Testes Unitários De Módulos Vuex Com Jest

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!

O que é Vuex?

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:

  1. Estado
  2. Getters
  3. Mutações
  4. Ações

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_NAMEou 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.getterse context.statepara obter o estado e context.commitchamar mutações. Você pode chamar manipuladores de ação usando action-namee payload, e eles são chamados de outras ações dentro da loja.

Diagrama de Módulos Vuex

Arquitetura Vuex

Criar um módulo 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ções
  • actions.ts: Responsável por todas as operações assíncronas
  • index.ts: A implementação do módulo
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);
        }
  }

}

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ções
  • ON_FETCH_TODOS_STARTEDmutação: atualiza o loadingatributo de estado
  • ON_FETCH_TODOS_SUCCESSmutação: atualiza a todosmatriz de estado
  • ON_FETCH_TODOS_FAILEDmutação: redefine o todose atualiza loadingcomo falso
  • completedTodosgetter: Obtém apenas os itens de tarefas que foram concluídos

Inicializar testes

Usaremos 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();
    });
});

Ações de teste

No todosmódulo, criamos a fetchTodosaçã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();
});

Testando getters

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);
    });

Testando mutações

Como já sabemos, as mutações são a única maneira de mudar o estado. Podemos testar a ON_FETCH_TODOS_SUCCESSmutação enviando tarefas simuladas e validando se o estado foi modificado.

O trecho de código abaixo é para a  successmutação. O mesmo se aplica para as mutações startede 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);
    });

Conclusão

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/

 #jest #vuex 

Testes Unitários De Módulos Vuex Com Jest

Unidad De Prueba De Módulos Vuex Con Jest

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!

¿Qué es Vuex?

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:

  1. Estado
  2. captadores
  3. Mutaciones
  4. Comportamiento

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_NAMEo 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.gettersy context.statepara obtener el estado y context.commitpara llamar mutaciones. Puede llamar a los controladores de acciones usando action-namey payload, y se llaman desde otras acciones dentro de la tienda.

Diagrama de módulos Vuex

arquitectura vuex

Crear un módulo 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 funciones
  • actions.ts: Responsable de todas las operaciones asíncronas
  • index.ts: La implementación del módulo
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);
        }
  }

}

El fragmento de código anterior contiene la siguiente implementación:

  • fetchTodos Action: Obtiene los elementos pendientes de la API REST y confirma las mutaciones
  • ON_FETCH_TODOS_STARTEDmutación: Actualiza el loadingatributo de estado
  • ON_FETCH_TODOS_SUCCESSmutación: actualiza la todosmatriz de estado
  • ON_FETCH_TODOS_FAILEDmutación: restablece todosy actualiza loadingcomo falso
  • completedTodoscaptador: obtiene solo las tareas pendientes que se han completado

Inicializar pruebas

Usaremos 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. localVuees 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();
    });
});

Acciones de prueba

En el todosmódulo, creamos la fetchTodosacció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();
});

prueba de captadores

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);
    });

Probando mutaciones

Como ya sabemos, las mutaciones son la única forma de cambiar el estado. Podemos probar la ON_FETCH_TODOS_SUCCESSmutación enviando tareas pendientes simuladas y validando si el estado se modifica.

El fragmento de código a continuación es para la  successmutación. Lo mismo se aplica para las mutaciones startedy 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);
    });

Conclusión

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/

 #jest #vuex 

Unidad De Prueba De Módulos Vuex Con Jest
Hong  Nhung

Hong Nhung

1660302960

Kiểm Tra đơn Vị Mô-đun Vuex Với Jest

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à gì?

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:

  1. Tiểu bang
  2. Getters
  3. Đột biến
  4. Hành động

Đố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_NAMEhoặ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.getterscontext.stateđể có được trạng thái và context.commitgọ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-namepayloadvà chúng được gọi từ các hành động khác trong cửa hàng.

Sơ đồ mô-đun Vuex

Kiến trúc Vuex

Tạo mô-đun 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àm
  • actions.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ô-đun
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);
        }
  }

}

Đ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ến
  • ON_FETCH_TODOS_STARTEDđột biến: Cập nhật loadingthuộc tính trạng thái
  • ON_FETCH_TODOS_SUCCESSđột biến: Cập nhật todosmảng trạng thái
  • ON_FETCH_TODOS_FAILEDđột biến: Đặt lại todosvà cập nhật loadinglà sai
  • completedTodosgetter: Chỉ nhận các mục việc cần làm đã hoàn thành

Khởi tạo các bài kiểm tra

Chú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. localVuelà 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();
    });
});

Kiểm tra các hành động

Trong todosmô-đun, chúng tôi đã tạo fetchTodoshà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();
});

Kiểm tra getters

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 completedTodosnà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);
    });

Kiểm tra đột biến

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 startederror:

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);
    });

Sự kết luận

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/

 #jest #vuex 

Kiểm Tra đơn Vị Mô-đun Vuex Với Jest

Unit Testing Vuex Modules with Jest

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/

#jest #vuex 

Unit Testing Vuex Modules with Jest
Duyen Hoang

Duyen Hoang

1657180680

Cách thiết lập VueJS, VueX và VueRouter trong ứng dụng Laravel

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 watchphp artisan serveđể kiểm tra nó. Hy vọng nó có thể giúp bạn.

Nguồn:  https://www.codecheef.org

#php #laravel #vue #vuejs #vuex #vuerouter #sass 

Cách thiết lập VueJS, VueX và VueRouter trong ứng dụng Laravel

Как настроить VueJS, VueX и VueRouter в приложении Laravel

В этом руководстве по 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

#php #laravel #vue #vuejs #vuex #vuerouter #sass 

Как настроить VueJS, VueX и VueRouter в приложении Laravel
Jarrod  Douglas

Jarrod Douglas

1657126380

Comment configurer VueJS, VueX et VueRouter dans l'application Laravel

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 watchet php artisan servetestez-le. J'espère que ça peut t'aider.

Source :  https://www.codecheef.org

#php #laravel #vue #vuejs #vuex #vuerouter #sass 

Comment configurer VueJS, VueX et VueRouter dans l'application Laravel
Wayne  Richards

Wayne Richards

1657122660

Cómo configurar VueJS, VueX y VueRouter en la aplicación Laravel

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 watchy php artisan serveprueba. Espero que te ayude.

Fuente:  https://www.codecheef.org

#php #laravel #vue #vuej #vuex #vuerouter #sass 

Cómo configurar VueJS, VueX y VueRouter en la aplicación Laravel