A starter kit for VueJs Applications
This repository is a modular abstraction to build a VueJS web application based on Redux paradigm using Vuex. You can use it to quickly scaffold your Vue web application projects and development environments.
This seed should clarify how to wire up all the modules of your application, even when we understand that in some cases there must be some changes needed by the structure to fit your needs correctly
Vue-Base makes use of the latest tools to improve your workflow, and enables you to create future ready applications:
- Vuex based architecture
- Webpack 3 build configuration depending on enviroment
- Development & Production server using express and webpack-dev-server
- Hot Reload/Live Reload support for Js & Css using Webpack HMR
- ES6 transpilation using Babel
- PostCSS processing with isomorphic support.
- CssModules based
- Code Linting using Eslint
- Standard Javascript Standard Style
- SSR - Server Side Rendering ...coming soon :)
To get you started, you need to meet the prerequisites, and then follow the installation instructions.
Vue-Base makes use a number of NodeJS tools to initialize and test Vue-Base. You must have node.js 6.2.0 at least, and its package manager (npm) installed. You can get it from nodejs.org.
You can clone our Git repository:
$ git clone https://github.com/atSistemas/vue-base.git
This method requires Git to be installed on your computer. You can get it from here.
Setting up Vue-Base is as easy as running:
$ yarn install
This command will install all the required dependencies and start your development server, which takes care of all the changes you make to your code and runs all the awesome stuff that ends with your code automagically transpiled and running on your browser.
Please note that yarn install
is only required on your first start, or in case of updated dependencies.
Once all the dependencies are installed, you can run $ yarn start
to initialize your development server using webpack-dev-server express middleware.
The dev server uses HMR (Hot module replacement) that injects updated modules into the bundle in runtime. It's like LiveReload
Vue-base is based on Redux paradigm so you can find all the typical entities of an Redux project like reducers , store, actions , etc.
There are four main folders:
server
contains Vue-Base development & production server based in express with Universal/Isomorphic support and custom middlewares like Gzip.
server
api/ //Api mocks
lib/ //Universal rendering files
middleware/ //enviroment middleware
statics/ //definition of statics path
templates/ //universal templates
server //Server
routing //Routing middleware
webpack
contains Vue-Base Webpack configuration separated by enviroment that allows to use different plugins and loaders in each target enviroment.
webpack
webpack.common.config/ //Common config
webpack.dev.config/ //Development config
webpack.prod.config/ //Production config
webpack.test.config/ //Testing config
webpack.dll.config/ //Dll config
src/base/
contains Vue-Base platform bootstrapping code.
base
client/ //client bootstrap
conf/ //Configuration files and Yeoman templates
reducers/ //reducer index
routes/ //routes index
shared/ // shared base folder
regenerators/ //index regenerators
CreateReducer //Custom reducer creator
ENV //Env handler
Errors //Errors handler
FetchData //Isomorfic data handler
FileSystem //Filesystem manager
JsDomSetup //JsDom Configuration FileSystem
Regenerate // Regenerate indexes
store/ //Store configuration
types/ //Action request Types
wp-plugins/ //Custom webpack plugins
...
src/app/
is the place where to put your application source code.
Vue-Base uses a "featured based" distribution, so all the necessary code for each page/features is located in its own folder inside containers folder as in src/app/containers/myContainer
A container is a Vue component who contains other components, Redux entities, functions and store subscriptions. Each container is self-contained and represents a feature like "clients" or "products" and it contains all the necessary stuff.
app/
containers/
myContainer/
actionTypes/ //action types definition
actions/ //action creators
components/ //container components
getters/ //container getters
mutations/ //containers mutations
reducers/ //container reducers
services/ //container services
myContainer.container.vue //container component
...
Vuex is a state management pattern + library for Vue.js applications. It serves as a centralized store for all the components in an application, with rules ensuring that the state can only be mutated in a predictable fashion. It also integrates with Vue's official devtools extension to provide advanced features such as zero-config time-travel debugging and state snapshot export / import.
Vuex is inspired by Flux, Redux and The Elm Architecture. Unlike the other patterns, Vuex is also a library implementation tailored specifically for Vue.js to take advantage of its granular reactivity system for efficient updates.
- State
- Getters
- Mutations
- Actions
- Modules
Vuex uses a single state tree - that is, this single object contains all your application level state and serves as the "single source of truth". This also means usually you will have only one store for each application. A single state tree makes it straightforward to locate a specific piece of state, and allows us to easily take snapshots of the current app state for debugging purposes.
You can think of them as computed properties for stores. Like computed properties, a getter's result is cached based on its dependencies, and will only re-evaluate when some of its dependencies have changed.
The only way to actually change state in a Vuex store is by committing a mutation. Vuex mutations are very similar to events: each mutation has a string type and a handler. The handler function is where we perform actual state modifications, and it will receive the state as the first argument:
import WeatherActionTypes from '../action-types'
export const mutations = {
[WeatherActionTypes.SET_STATION] (state, stations) {
state.stations = stations
}
}
You cannot directly call a mutation handler. Think of it more like event registration: "When a mutation with type increment is triggered, call this handler." To invoke a mutation handler, you need to call store.commit with its type:
export const getStations = ({ commit }) => (
services.getStations()
.then(stations =>
commit(WeatherActionTypes.SET_STATION, stations))
)
Actions are similar to mutations, the differences being that:
- Instead of mutating the state, actions commit mutations.
- Actions can contain arbitrary asynchronous operations.
import WeatherActionTypes from '../action-types'
import { services } from '../services'
export const actions = {
getStations ({ commit }) {
services.getStations()
.then(stations => commit(
WeatherActionTypes.SET_STATION,
stations && stations.list))
}
}
ActionTypes it's a representation using constants of your possible actions:
import { createActionType } from 'base'
export default createActionType([
'SET_STATION'
])
Modules describe how the state of your application changes in response to a new Action. Modules are similar to reducer concept.
import { getters } from '../getters'
import { actions } from '../actions'
import { mutations } from '../mutations'
const state = {
stations: [],
forecasts: [],
}
export default {
state,
getters,
actions,
mutations
}
- From parent to child component We use props to pass data from parent to child components. Props are custom attributes you can register on a component. When a value is passed to a prop attribute, it becomes a property on that component instance.
Vue.component('blog-post', {
props: ['title'],
...
})
Once a prop is registered, you can pass data to it as a custom attribute, like this:
<blog-post title="Welcome to VueBase"></blog-post>
- From child to parent componentt We use events to communicate with our direct parent component. We can use the v-on directive to listen to DOM events and run some JavaScript when they’re triggered. From a child method we can do something like:
this.$emit('myEvent', params)
To capture this event, we only have to register v-on directive when we define the child component in the html of our parent component like:
<my-child-component v-on:my-event="doSomething"></my-child-component>
doSomething can be a method registered on our parent component which can do anything we want to do.
Vue components have the following methods during his life:
- beforeCreate()
- created()
- beforeMount()
- mounted()
- beforeUpdate()
- update()
- beforeDestroy()
- destroy()
The next picture, shows a visual representation of this lifecycle methods:
In-template expressions are very convenient, but they are meant for simple operations. Putting too much logic in your templates can make them bloated and hard to maintain
avoid
<div id="example">
{{ message.split('').reverse().join('') }}
</div>
do
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// a computed getter
reversedMessage: function () {
// `this` points to the vm instance
return this.message.split('').reverse().join('')
}
}
})
While computed properties are more appropriate in most cases, there are times when a custom watcher is necessary. That’s why Vue provides a more generic way to react to data changes through the watch option. This is most useful when you want to perform asynchronous or expensive operations in response to changing data.
You can generate a complete distribution source ready for production enviroments.
$ yarn build:prod
will create a minified version for your application, ready for production.
$ yarn start:prod
will run production enviroment of your application serving content from dist directory.
You can write your tests normally using Mocha and Chai for assertions.
$ yarn test
will perform your unit testing, or yarn test:coverage
to run your tests and display a code coverage report.
Vue base uses Nyc for code coverage and you can generate reports in console or icov/html format.
$ yarn test
will perform your code coverage, generating an html report located in coverage/ folder.
Anyone and everyone is welcome to contribute, however, if you decide to get involved, please take a moment to review the guidelines:
Vue-Base is available under the MIT license.