├── 0_installation.md ├── 1_introduction.md ├── 2_ajax.md ├── 3_building_the_front_end.md ├── 4_core_concepts.md ├── 5_interacting_with_backend.md ├── LICENSE └── README.md /0_installation.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | Technically speaking, you do not have to install Vue. You can just include Vue in a ` 33 | 34 | 35 |
36 | {{ message }} 37 |
38 | 46 | 47 | 48 | ``` 49 | 50 | Save the file and open it in your browser. You can open it by right click -> open with -> Firefox/Chrome 51 | 52 | ## Another way to use Vue 53 | 54 | This book is focused for those who are new to front end development in general. A working knowledge of Javascript is presumed, if you don't have that working knowledge, at least you should be able to follow up with the Javascript by doing internet searches and all. 55 | 56 | If you are comfortable with using build systems with Node.js, you can use multiple tools like webpack and browserify. Unfortunately, I do not know much of either of those, this book aims to teach the absolute basics of building a Vue app. The future chapters may contain a chapter on how to use webpack, but as of now it is not planned. Please refer to the [official docs](https://vuejs.org) for more details on the advance usage of the framework. 57 | -------------------------------------------------------------------------------- /1_introduction.md: -------------------------------------------------------------------------------- 1 | # Interactive web applications 2 | The Internet has come a long way since the first website http://cern.ch was created. Earlier, it used to be a platform for sharing research between scientists, which was later adapted for building one of the most tranformative means of communication and a platform which opened the world up to a large range of possibilities. 3 | 4 | With the large scale possibilities, the user expectations have sky rocketed, back in the early 2000s even Google's webpages were having barely any interactivity, when they started using auto-complete it was a _big_ deal. But now, users just expect auto complete and a host of other features which make the webapp interactive, what we mean by interactive is that the user should not need to refresh the page for updating the content. The content should be updated automatically. 5 | 6 | There are two aspects to this interactivity, 7 | 8 | 1. Websockets: This comes into picture when you want to keep _all_ the open tabs in sync. Let's say the same user has logged into your webapp using three different browsers, you'd use websockets to keep all those pages updated. 9 | 2. AJAX: When you login to a todo manager, it doesn't refresh the page, but just updates the state of the website depending on the action you took (i.e. login), it will then show you the pending tasks. 10 | 11 | # What is Vue? 12 | 13 | Vue is a library for writing such applications. Vue is technically a library focused on the View layer of the classic MVC model, along with [supporting libraries](https://github.com/vuejs/awesome-vue#libraries--plugins), one can easily build a interactive webapp. Vue provides tools for simplifying the development but you do not have to use any of those to get started, speaking from experience, I've always found it better to start without using any tool "vanilla" and later, when we realize _why_ the tools were created, then we can start using them. 14 | 15 | Let's continue the example in the end of the installation chapter. 16 | 17 | ## Loading Vue 18 | For using Vue, we first have to load it. Since it is a JS library, all we have to do to use Vue is to load it using a script tag, like we include jQuery and other libraries. ``. 19 | 20 | Do note that Vue loads _after_ the html page has loaded (this is the reason if it takes a lot of time to fetch data or do computation, the user would see your `{{code}}` because in that case it'd take Vue some time to initialize the state of the app and render the data. 21 | 22 | That's why we place it at the end of the body tag when including the file as a script tag. If we do not include it at the bottom of the page, then it'd be loaded _before_ the html is loaded and it might not work properly. When we include the file in the script tag, a global variable by the name of `Vue` is created. We use this variable to create the new app or components. 23 | 24 | file: `chapter1/0basic_example.html` 25 | 26 | 27 | 28 | 29 | 30 |
31 | {{ message }} 32 |
33 | 34 | 42 | 43 | 44 | 45 | This is the simplest possible Vue app. We are rendering the variable `message` in the `
` tag. If you have had previous experience in template rendering then it might sound trivial, since all rendering engines do this work. But here, things are different. Vue has done a lot of work under the hood. It hasn't _just_ rendered `message`, the variable is "reactive". If the value of `message` changes, then the html would be automatically updated by Vue. The advantage of this feature is that wheneve the value of `message` variable changes, it'd get reflected in our HTML _without_ us having to render the variable again. Vue does all the heavy lifting. All we are left with is creation of variables and maintaining the state of the app _correctly_ using the variables. 46 | 47 | To verify our claim, open the web inspecter in your browser, on Firefox do a right click on the page and click "inspect element". It shall open the web inspector. Press the escape key and the console would pop up. Set the message to any value you'd like like this, `app.message='oh my Dod, it did change.'` 48 | 49 | You'd see that the html was changed. During runtime, Vue uses a diffing algorithm to make optimal changes to the DOM. It uses shadow DOM to render html, it is a feature which would come into all browsers eventually. 50 | 51 | > Note: Firefox has a developer edition (https://www.mozilla.org/en-US/firefox/developer) of it's browser which is tailored for web developers 52 | 53 | ## Syntax 54 | 55 | Since Vue works on data, it uses a special syntax to render the data, by default it is `{{ }}`, but we can change it to whatever syntax we want. The way to do it is 56 | 57 | var app = new Vue({ 58 | el: '#app', 59 | data: { 60 | message : 'good morning' 61 | }, 62 | delimiters: ['${', '}'] 63 | # this makes our syntax as ${} 64 | }) 65 | 66 | Change of rendering syntax is necessary while using Vue with languages which also use `{{ }}` for template rendering like [Go](http://golang.org) 67 | 68 | ## Obligatory theory 69 | 70 | We first created a Vue instance. The syntax is 71 | 72 | var app = new Vue({ 73 | // options 74 | }) 75 | 76 | We pass the options object while intializing Vue's root instance for our app. 77 | 78 | It contains the 79 | 80 | 1. `el`: element which the app is going to be bound. The Vue app exists **only** in this tag. 81 | 1. `data`: the data of our app. Every variable which we are going to use in the template needs to be defined here. 82 | 1. `lifecycle callbacks`: There are many of these, we will get to them later. Creating an object in Vue is a process, there are lifecycle callbacks involved like mounted (when the componenet is ready and inserted in the DOM). 83 | 84 | Each Vue instance proxies all the properties found in its `data` object. 85 | 86 | var data = { a: 1 } 87 | var vm = new Vue({ 88 | data: data 89 | }) 90 | 91 | vm.a === data.a // -> true 92 | 93 | // setting the property also affects original data 94 | vm.a = 2 95 | data.a // -> 2 96 | 97 | // ... and vice-versa 98 | data.a = 3 99 | vm.a // -> 3 100 | 101 | It should be noted that only these proxied properties are reactive. If you attach a new property to the instance after it has been created, it will not trigger any view updates. We will discuss the reactivity system in detail later. 102 | 103 | In addition to data properties, Vue instances expose a number of useful instance properties and methods. These properties and methods are prefixed with $ to differentiate them from proxied data properties. 104 | 105 | For example: 106 | 107 | var data = { a: 1 } 108 | var vm = new Vue({ 109 | el: '#example', 110 | data: data 111 | }) 112 | 113 | vm.$data === data // -> true 114 | vm.$el === document.getElementById('example') // -> true 115 | 116 | // $watch is an instance method 117 | vm.$watch('a', function (newVal, oldVal) { 118 | // this callback will be called when `vm.a` changes 119 | }) 120 | 121 | 122 | ## Expressions 123 | 124 | So far we’ve only been binding to simple property keys in our templates. But Vue actually supports the full power of JavaScript expressions inside all data bindings: 125 | 126 | {{ number + 1 }} 127 | 128 | {{ ok ? 'YES' : 'NO' }} 129 | 130 | {{ message.split('').reverse().join('') }} 131 | 132 |
133 | 134 | These expressions will be evaluated as JavaScript in the data scope of the owner Vue instance. One restriction is that each binding can only contain one single expression, so the following will NOT work: 135 | 136 | 137 | 138 | {{ var a = 1 }} 139 | 140 | 141 | 142 | {{ if (ok) { return message } }} 143 | 144 | > Template expressions are sandboxed and only have access to a whitelist of globals such as Math and Date. You should not attempt to access user defined globals in template expressions. 145 | 146 | ## A todo list manager. 147 | 148 | Our requirement is simple, we need to add/update/delete items in our todo list. 149 | 150 | We start small. 151 | 152 | file: `1basic-todo.html` 153 | 154 |
155 |
    156 |
  1. {{todo}}
  2. 157 |
  3. {{todo}}
  4. 158 |
  5. {{todo}}
  6. 159 |
160 |
161 | 162 | 170 | 171 | 172 | ####Note 173 | In the interest of saving space, we will showing just snippets. It is the same and it needs to be present for your app to work. 174 | 175 | 176 | **Tip**: When we have an example, please create a new html file and save it according to whatever convention you want and open it in a browser to verify what you have learned. 177 | 178 | When we open this in a browser, you will see "do something" being displayed thrice. We do not want the same message to be displayed! We want different messages and eventually we want to add our own todos. 179 | 180 | ####Note 181 | For variables to be reactive, we need to define them in the data field. For components data is a function and not a variable. We will get to that later. 182 | 183 | file: `2basic-todo-2.html` 184 | 185 | Earlier we had one variable `todo`, but since we want to display multiple messages, we need to define an array. Update the data field by the following: 186 | 187 | data: { 188 | todos: [ 189 | { text: "do something!"}, 190 | { text: "now do something!"}, 191 | { text: "now do something else!"} 192 | ] 193 | } 194 | 195 | Doing this bounds the `todos` array to the current `Vue` instance named `app4`. This creates the array of tasks which will be showed on the html page. For that to happen, we need to change the HTML page as well. 196 | 197 | Instead of `
  • {{todo}}
  • `, we will have to now display an array. Vue provides us with a `for` construct. 198 | 199 | ### v-for 200 | v-for has two syntaxes, `v-for="item in items"` or `v-for="(item, index)" in items`. 201 | The first one is just a loop over arrays, the second one loops over the array _and_ has the index of each element during the for loop itself. 202 | 203 | We are going to need the index for our delete function, hence we use the second iteration of `v-for`. 204 | 205 |
  • {{ todo.text }}
  • 206 | 207 | Anything that starts with `v-` is a directive. It is evaluated by Vue. If something is wrong, it will complain in the JS console which we checked few lines back. 208 | 209 | > **Always open the JS console while writing a vue app** 210 | 211 | When the loop evaluates, `todo` will take one value at a time till it reaches the end of todos, the index will do the same about the position of the value in the `todos` array. 212 | 213 | ## Getting User Input 214 | 215 | We now want to be able to add todo items in our list. 216 | 217 | file: `3basic-todo-3.html` 218 | 219 | For adding a new element to the existing html, we need to use a new directive called `v-model`. 220 | 221 | ### v-model 222 | v-model is used to double bind the value of an input tag to a Javascript variable. We define the variable in the `data` field of our Vue instance. Suppose we are having the input tag which takes the title of the task, we write `v-model="todo.title"` in the input tag. This will sync the input tag's data _and_ the value of the `todo.title` variable. 223 | 224 | We first need to define the `todo` variable for this double binding to work, please note that we can't do double data binding on our todos array. It will be the data store, and `todo` is going to be like our RAM. 225 | 226 | ### Methods 227 | 228 | Methods are functions which are going to be valid for that Vue instance. Currently we require the method to add a todo. For starters it should not be doing everything, we are going incrementally. Let's first ensure that we get the user data correctly, once we have the data in our `todo` variable, then we can do anything with it. 229 | 230 | We add the definition of `todo` and the methods as stated below: 231 | 232 | data: { 233 | todo: {title: '', text:''}, 234 | todos: [ 235 | {title: 'Learn JS' , text: "What is JS?"}, 236 | {title:'Learn vue', text: "Vue has nice docs!"}, 237 | {title:'Build something', text: "what to build?"} 238 | ] 239 | }, 240 | methods: { 241 | AddTodo: function (item) { 242 | alert(item.text + " " + item.title) 243 | } 244 | } 245 | 246 | There are two changes which need to be done to the html part of the page. First is where we take input and second is where we display todos. 247 | 248 | 249 | 250 | 251 | 252 |
      253 |
    1. 254 | {{ todo.title }} : {{ todo.text }} 255 |
    2. 256 |
    257 | 258 | For adding a new item to our todo list, we need to do the following things: 259 | 260 | 1. Get the input from the tag (this is done automatically by two way data binding using v-model) 261 | 1. Add the input to our `todos` 262 | 1. Render them in our ol tag 263 | 264 | ## v-on 265 | This directive handles events. When we do a v-on:click="AddMethod", it'll run AddMethod when the element is clicked. 266 | 267 | We are nearly done in our app. We have taken input from the user, we render the array correctly. We have the event handling mechanism ready. Just the missing link is to do something with the data which we are practically dumping with sending just an alert. We need to call our method which will add todo in our todos array. We do that by event handling i.e. the `v-on` directive. The `AddTodo` method is bound to our Vue instance, it won't be available outside the `
    ` tag. 268 | 269 | In our `AddTodo` method we change the alert line to `this.todos.push(this.todo)`. It will add the `todo` to our `todos` array. 270 | 271 | > It is important to use `this.` to refer to `todos` because scoping is a big issue here and Vue won't be able to find out what todo you are referring to. 272 | 273 | ## No HTML change 274 | If you were paying attention, then you would have noted that we didn't manually change the HTML. We just changed the rendering and made changes to the JS portion. Vue will handle everything by itself. 275 | 276 | ## Add feature to assign task 277 | 278 | `file: 4basic-todo-4.html` 279 | 280 | We now have a new requirement, we need to add the feature to assign tasks to someone. 281 | 282 | We first need to add `assign` as a part of the `todo` object `todo: {title: '', text:'', assign:''},` 283 | 284 | Then we need to add a new `` with the v-model as `todo.assign`. It'll do two way binding of the input field and `todo.assign`. 285 | 286 | Lastly, we need to display the new variable while rendering. Just adding a new `{{ todo.assign }}` would be enough. 287 | 288 | Save and open the page in a browser. There is one catch, not all tasks have an assign field. There is a way to handle this in Vue. It is by using the `v-if` directive. 289 | 290 | ## v-if 291 | v-if directive will show the HTML tag only if there is a value in the object assigned to it. 292 | 293 | ## v-else-if 294 | This is a new tag in Vue2.1, it allows a proper if-else statement which we are so familiar with from other languages to be used in Vue templates. 295 | 296 | ## The template tag 297 | 298 | In our example, there is another catch, we are rendering the content just by doing `{{}}`. This begs the question as to where to place the `v-if`. Because `v-if` is to be used in a html tag. The `