Vue supports Flux officially through the use of Vuex. There are a lot of blog posts around the Internet explaining Flux pattern in great details, so I won’t go deep into it. Instead I will summarize the core concepts of Vuex

Vuex provides a single source of truth (single state tree) where all the changes must go through. UI components change according to changes made to state.

Each change in Vuex happens through a mutation (event). Each mutation modifies the state tree and in turn re-renders the UI accordingly.

Vuex encourages the use of constants for mutation types in order to share them with actions (more on this later). In the above mutation, the state is mutated by filtering out the message matched with id.

As mentioned before, actions are a part of the data flow. In Vuex, there is no restriction on how to mutate the data, it can be done through mutations or actions. However, actions are there to separate the mutation logic from the actual action leading to the mutation. For example, when a user clicks the button to send a message, it triggers sendMessage action which in turn triggers sentMessage mutation after calling the API to notify the UI that there is a new message. If all that happens inside a mutation, it is difficult to test and re-use.

Actions usually follow the same pattern, call the API then commit a mutation based on the data received. However, since this is a chat app receiving data in real-time, there need to be some actions specifically for handling events from faye. For example, when sending a message, the API triggers a faye event

I usually divide components into 2 categories, presentational and container components. They are also known as stateless and stateful components. Presentational components are responsible for rendering the actual UI, they are often nested inside of another container component. Data is passed down to presentational components by the parent (container) component. Presentational components usually communicate with their parent through the use of events.

There are 4 presentational components in this chat app

CurrentUser renders the info about the current user or a button to log in

There is only 1 container component Main which does all the API calls and manages the state tree. In reality, there might be many container components, each handles one route/path or whatever unit you use to define a single page in the application.

A component defines an UI element, it can be as simple as an input or as complicated as a list of messages.

A component in Vue is just a normal Javascript object with proper attributes to define the behaviour of the component. Vue borrows the same props concept from React to indicate data passed to the component by its parent. There is also data which is somewhat similar to state in React world. However, when accessing data, Vue doesn’t have any distinction between external data and internal data, everything can be accessed through the component instance (this). It’s convenient for developing but might come and bite me later on when I accidentally change props

The style of defining a component in Vue is definitely my favourite. Everything is in one file

There is one simple rule: “props down, events up”, this is true for most frameworks I have a chance to work with (Angular, React, Vue). Events here can mean an actual event fired and forgotten or a function call (in the case of React)

In MessageInput, I have this method to emit an event with the message typed by the user. This method is triggered when the user presses “Enter” (@keyup.enter="sendMessage")

At the root, there is App component which loads chat messages and current user data from the API. And at the root path /, Main component is rendered. It receives a store instance created during the initialization, from store, Main gets messages and current user data, then passes it down to MessageList and CurrentUser respectively.

MessageInput emits send-message event everytime the user presses “Enter” or the button to send the message. Main listens to this event and dispatch sendMessage action when it happens. The action then sends POST /api/messages request to the API to create a new message and commit SENT_MESSAGE mutation upon success.

MessageList just renders whatever messages it receives, each message is a Message component. This component also emits delete-message event when the user wants to delete a message. This event propagates all the way to Main (through MessageList). In Main, upon receiving this event, it calls deleteMessage action which sends a DELETE /api/messages/:id request to the API. When it finishes, it commits a DELETED_MESSAGE mutation to update the state tree.

That is pretty much everything for this simple chat app. I skip error handling to make everything simpler to follow since this is just a demo application for me to learn Vue.

There are a lot to talk about Vue, this blog post probably won’t/can’t cover everything. But my impression about Vue is extremely positive, everything just works, no complicated setup (actually vue-cli does all the hard works for me)