docs(daily-email): add post

diff --git a/ansible/ansible.cfg b/ansible/ansible.cfg
deleted file mode 100644
index cc79c59..0000000
--- a/ansible/ansible.cfg
+++ /dev/null
@@ -1,2 +0,0 @@
-[defaults]
-inventory = ./hosts.ini
diff --git a/ansible/deploy.yml b/ansible/deploy.yml
deleted file mode 100644
index ea5647a..0000000
--- a/ansible/deploy.yml
+++ /dev/null
@@ -1,14 +0,0 @@
----
-- hosts: web
-  gather_facts: false
-
-  tasks:
-    - name: Update the code
-      git:
-        repo: https://github.com/opdavies/oliverdavies.uk
-        dest: ~/oliverdavies.uk
-
-    - name: Pull the latest images and re-generate the site.
-      shell: ./run run-production
-      args:
-        chdir: ~/oliverdavies.uk
diff --git a/ansible/hosts.ini b/ansible/hosts.ini
deleted file mode 100644
index 01a3341..0000000
--- a/ansible/hosts.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[web]
-18.132.197.147
-
-[web:vars]
-ansible_user=ubuntu
diff --git a/website/source/_daily_emails/2022-09-30.md b/website/source/_daily_emails/2022-09-30.md
new file mode 100644
index 0000000..f5a63eb
--- /dev/null
+++ b/website/source/_daily_emails/2022-09-30.md
@@ -0,0 +1,83 @@
+---
+title: "Store Wars: different state management in Vue.js"
+date: "2022-09-30"
+permalink: "/archive/2022/09/30/store-wars-vuejs"
+tags: ["vue"]
+---
+
+I'm currently working on a Vue.js application that I started building in Vue 2 before starting to use the Composition API, and then moved it to Vue 3.
+
+In the original version, I was using Vuex for state management within the application, and interacting with Vuex directly within my Vue components - calling `getters` and `dispatch` to retrieve and update data.
+
+As part of moving to Vue 3, I wanted to evaluate any new options, like Pinia which is now the default state management library for Vue.
+
+But because I was integrating with Vuex directly, switching to an alternative would mean changing code within my components.
+
+## Defining a Store interface
+
+This is a situation that often occurs in back-end development - where you may need to switch to a different type of database or a different payment provider in an eCommerce application.
+
+In that situation, you need a generic interface that can be used by different implementations. Because they have consistent methods, one implementation can be replaced with another or multiple can be added at the same time. This is called the Strategy design pattern, and related to the open-closed principle in SOLID.
+
+This is what I did by adding a `Store` interface:
+
+```javascript
+export default interface Store {
+  actions: {
+    addRow(): void;
+    init(): void;
+    removeRow(index: Number): void;
+  };
+
+  state: {
+    isLoading: boolean;
+    selection: {
+      items: [];
+    };
+  };
+}
+```
+
+Any store that I want to work with needs to have these defined actions and state values, so I can use them within my components knowing that they will always be available.
+
+## Creating a native Vue store
+
+This is one implementation of the `Store` interface, using just Vue's `reactive` function from the Composition API:
+
+```javascript
+let state = reactive({
+  isLoading: false,
+  selection: {
+    items: [],
+  },
+});
+
+let actions = {
+  addRow(): void {
+    state.selection.items.push({
+      // ...
+    });
+  },
+
+  init(): void {
+    state.isLoading = true;
+
+    // ...
+  },
+
+  removeRow(index: number): void {
+    state.selection.items.splice(index, 1);
+  },
+};
+
+const vueStore: Store = {
+  actions,
+  state: readonly(state),
+};
+
+export default vueStore;
+```
+
+If I needed to add a Pinia version or another library, I can create another implementation that complies with same interface.
+
+Each implementation being responsible for any specifics for that library - extracting that logic from the component code making it more flexible and reusable.
This commit is contained in:
Oliver Davies 2022-10-01 22:54:10 +01:00
parent 3c7db24f1c
commit f99561e66a
4 changed files with 83 additions and 21 deletions

View file

@ -1,2 +0,0 @@
[defaults]
inventory = ./hosts.ini

View file

@ -1,14 +0,0 @@
---
- hosts: web
gather_facts: false
tasks:
- name: Update the code
git:
repo: https://github.com/opdavies/oliverdavies.uk
dest: ~/oliverdavies.uk
- name: Pull the latest images and re-generate the site.
shell: ./run run-production
args:
chdir: ~/oliverdavies.uk

View file

@ -1,5 +0,0 @@
[web]
18.132.197.147
[web:vars]
ansible_user=ubuntu

View file

@ -0,0 +1,83 @@
---
title: "Store Wars: different state management in Vue.js"
date: "2022-09-30"
permalink: "/archive/2022/09/30/store-wars-vuejs"
tags: ["vue"]
---
I'm currently working on a Vue.js application that I started building in Vue 2 before starting to use the Composition API, and then moved it to Vue 3.
In the original version, I was using Vuex for state management within the application, and interacting with Vuex directly within my Vue components - calling `getters` and `dispatch` to retrieve and update data.
As part of moving to Vue 3, I wanted to evaluate any new options, like Pinia which is now the default state management library for Vue.
But because I was integrating with Vuex directly, switching to an alternative would mean changing code within my components.
## Defining a Store interface
This is a situation that often occurs in back-end development - where you may need to switch to a different type of database or a different payment provider in an eCommerce application.
In that situation, you need a generic interface that can be used by different implementations. Because they have consistent methods, one implementation can be replaced with another or multiple can be added at the same time. This is called the Strategy design pattern, and related to the open-closed principle in SOLID.
This is what I did by adding a `Store` interface:
```javascript
export default interface Store {
actions: {
addRow(): void;
init(): void;
removeRow(index: Number): void;
};
state: {
isLoading: boolean;
selection: {
items: [];
};
};
}
```
Any store that I want to work with needs to have these defined actions and state values, so I can use them within my components knowing that they will always be available.
## Creating a native Vue store
This is one implementation of the `Store` interface, using just Vue's `reactive` function from the Composition API:
```javascript
let state = reactive({
isLoading: false,
selection: {
items: [],
},
});
let actions = {
addRow(): void {
state.selection.items.push({
// ...
});
},
init(): void {
state.isLoading = true;
// ...
},
removeRow(index: number): void {
state.selection.items.splice(index, 1);
},
};
const vueStore: Store = {
actions,
state: readonly(state),
};
export default vueStore;
```
If I needed to add a Pinia version or another library, I can create another implementation that complies with same interface.
Each implementation being responsible for any specifics for that library - extracting that logic from the component code making it more flexible and reusable.