Differences

This shows you the differences between two versions of the page.

Link to this comparison view

se:labs:03 [2018/10/20 01:57]
avner.solomon [Tasks]
se:labs:03 [2023/10/10 01:13] (current)
emilian.radoi [Feedback]
Line 1: Line 1:
-====== Lab 03 - Frontend ​======+====== Lab 03 - Introduction to React ======
  
-=====Vue====+=====React====
  
-Vue (read as view) is a powerful fronted framework ​for creating web-app ​interfaces. ​Vue is split into multiple sub-libraries where the core is focusing on creating view elements while the plugins focus on extra functionality like [[https://​vuex.vuejs.org/​|Vuex]], for state management, [[https://​router.vuejs.org/​|Vue Router]], for managing routes ​(URLsinside an app ([[https://​classicalconditioning.github.io/​vue-router-nav/#/​third|Example]]) and much much more since Vue is primarily created on a component system that allows ​you to extend it with your own components ​or reuse components from the web.+React is a modern Javascript library ​for building user interfaces. 
 +  * React makes it easier to create modern interactive UIs. React adheres to the declarative programming paradigmyou can design views for each state of an application and React will update and render the components when the data changesThis is different than imperative programming ​(Javascript). 
 +  * Component-Based: Components are the building blocks of React, they allow you to split the UI into independent,​ reusable pieces that work in isolation. Data can be passed through ​components ​using “props”.
  
-Though we are trying to give you a crash course in Vue, it is recommended to check the official Vue page and read their articles from their own guide ([[https://vuejs.org/​v2/​guide/​|Vue 2.0 Guide]]). Anyone who aims to be using view in any project should at least read all the chapters from this page (except migration from vue 1.0). All links included in this wiki article are must reads.+{{:se:​labs:​react.png?700|}}
  
-Vue js can be used directly by including the following script in the ''<​head>''​ +=====React Virtual DOM====
-<code html> +
-<!-- development version, includes helpful console warnings --> +
-<script src="​https://​cdn.jsdelivr.net/​npm/​vue/​dist/​vue.js"></​script>​ +
-</​code>​ +
-or +
-<code html> +
-<!-- production version, optimized for size and speed --> +
-<script src="​https://​cdn.jsdelivr.net/​npm/​vue"></​script>​ +
-</​code>​+
  
-Here is a simple example ​of a Vue App+When new elements are added to the UI, a virtual DOM, which is represented as tree, is created. Each element is a node on this tree. If the state of any of these elements changes, ​new virtual DOM tree is created. This tree is then compared or “diffed” with the previous virtual DOM tree
-<code html> + 
-<​!-- ​this code goes in body --> +Once this is done, the virtual DOM calculates the best possible method to make these changes to the real DOM. This ensures that there are minimal operations on the real DOM. Hence, reducing the performance cost of updating the real DOM. 
-<div id="​app">​ + 
-  <​!-- example of linking attribute to variable --> +{{:se:labs:​react_virtual_dom.jpeg?​700|}} 
-  <p v-bind:title="​message">​ + 
-    Hover your mouse over me for a few seconds +The red circles represent the nodes that have changed. These nodes represent the UI elements that have had their state changed. The difference between the previous version of the virtual DOM tree and the current virtual DOM tree is then calculated. The whole parent subtree then gets re-rendered ​to give the updated UI. This updated tree is then batch updated to the real DOM. 
-    to see my dynamically bound title! + 
-  </​p>​ +===== JSX ===== 
-  <​!-- example of linking attribute to variable 2 ':' ​is an alias for v-bind--> +JSX is an XML-like syntax extension to ECMAScript without any defined semantics.  
-  <​p ​:title="​message">​ + 
-    Hover your mouse over me for a few seconds +React embraces the fact that rendering logic is inherently coupled with other UI logichow events are handled, how the state changes ​over time, and how the data is prepared ​for display. 
-    to see my dynamically bound title! + 
-  </​p>​ +Instead ​of artificially separating technologies by putting markup and logic in separate files, React separates concerns with loosely coupled units called “components” that contain both. 
-  <!-- example ​of content --> + 
-  <​p>​{{counter}} clicks</​p>​ +<code javascript
-  <!-- example of event handling 1--+const element ​= <h1>Hello, world!</h1>;
-  <​button v-on:click="​counter++">​Click me 1</button> +
-  <!-- example of event handling 2 '​@'​ is an alias for v-on-->​ +
-  <button @click="​counter++">​Click me 2</​button>​ +
-  <!-- example of event handling 3--> +
-  <button @click="​incremenentCounter">​Click me 3</​button>​ +
-</div>+
 </​code>​ </​code>​
 +
 +In the example below, we declare a variable called name and then use it inside JSX by wrapping it in curly braces:
 +
 +
 <code javascript>​ <code javascript>​
-//this goes inside a <​script>​ tag at the end of the <​body>​ +const name = 'Andrei'; 
-var app new Vue({ +const element = <​h1>​Hello, {name}</​h1>;​
-  el: '#app', +
-  data: { +
-    message: 'You loaded this page on ' + new Date().toLocaleString(), +
-    counter: 0 +
-  }, +
-  methods: ​{ +
-    incremenentCounter:​ function() { +
-      this.counter++ +
-    ​} +
-  } +
-})+
 </​code>​ </​code>​
  
-Though it is indeed possible to code a full app like this it is strongly recommended against. That is where [[https://​vuejs.org/​v2/​guide/​components.html|vue components]] come in place, helping you structure your own project. And even thought they can be directly defined in html too it is recommended to use node.js to build your project from .vue component files. 
  
-[[https://​vuejs.org/​v2/​guide/​single-file-components.html|Single file components]] is the core feature that will allow you to structure your code by defining new components with new HTML tags. 
  
-In order to get you started with Vue components you will need node installed and a vue project. The de facto tool for generating new vue projects is and will always be the latest version of [[https://​cli.vuejs.org/​|vue-cli]] utility (another independent part of the vuejs infrastructure).+===== Components =====
  
-In order to install vue-cli all you need to do is +User interfaces can be broken down into smaller building blocks called components.
-<code bash> +
-npm install -g @vue/cli +
-# OR +
-yarn global add @vue/cli +
-</​code>​ +
-This will install the vue command in your OS.+
  
-Once installed all you need to do is run ''​vue create my-project'' ​and follow the interactive menuAfter generating ​the projectthe 2 commands that you will mostly use withing ​the project folder will be +Components allow you to build self-contained, reusable snippets of code. If you think of components as LEGO bricks, you can take these individual bricks ​and combine them together to form larger structuresIf you need to update a piece of the UI, you can update ​the specific component or brick. 
-<code bash> +{{:​se:​labs:​react_components.png?​700|}} 
-npm run serve + 
-# OR +This modularity allows your code to be more maintainable as it grows because ​you can easily add, update, and delete components without touching ​the rest of our applicationThe nice thing about React components is that they are just JavaScript. 
-yarn serve + 
-</code+In React, components are functions or classes, we are only going to use functions. Inside your script tag, write a function called header: 
-for running a local development server on localhost:​8080 ​to interactively test you project. This page will automatically show the changes in your project+ 
-<​code ​bash+ 
-npm run buid +<​code ​javascript
-# OR +export default function StartupEngineering() { 
-yarn build+  ​return <​div>​StartupEngineering</​div>;​ 
 +}
 </​code>​ </​code>​
-for building your project. The output will be placed in ./dist folder by default inside your project 
  
-=====Vue Components====+===== Nesting ​Components ​=====
  
-As mentioned before, each component is standalone file allowing ​you to work collaboratively on developing the app. +Applications usually include more content than single component. You can nest React components inside each other like you would do with regular HTML elements.
-Let's take a look at the structure of such file+
  
-<code html> +The <Headercomponent ​is nested inside ​the <​HomePagecomponent:
-<!-- this is the default HelloWordComponent.vue from teh default vue-cli project under ./​src/​components -->+
  
-<!-- the first part from a .vue file called <​template>​ is defining the html code from your component --> 
-<​template>​ 
-  <div class="​hello">​ 
-    <​h1>​{{ msg }}</​h1>​ 
-    <p> 
-      For guide and recipes on how to configure / customize this project,<​br>​ 
-      check out the 
-      <a href="​https://​cli.vuejs.org"​ target="​_blank"​ rel="​noopener">​vue-cli documentation</​a>​. 
-    </p> 
-    <​h3>​Installed CLI Plugins</​h3>​ 
-    <ul> 
-      <​li><​a href="​https://​github.com/​vuejs/​vue-cli/​tree/​dev/​packages/​%40vue/​cli-plugin-babel"​ target="​_blank"​ rel="​noopener">​babel</​a></​li>​ 
-      <​li><​a href="​https://​github.com/​vuejs/​vue-cli/​tree/​dev/​packages/​%40vue/​cli-plugin-eslint"​ target="​_blank"​ rel="​noopener">​eslint</​a></​li>​ 
-      <​li><​a href="​https://​github.com/​vuejs/​vue-cli/​tree/​dev/​packages/​%40vue/​cli-plugin-unit-jest"​ target="​_blank"​ rel="​noopener">​unit-jest</​a></​li>​ 
-    </ul> 
-    <​h3>​Essential Links</​h3>​ 
-    <ul> 
-      <​li><​a href="​https://​vuejs.org"​ target="​_blank"​ rel="​noopener">​Core Docs</​a></​li>​ 
-      <​li><​a href="​https://​forum.vuejs.org"​ target="​_blank"​ rel="​noopener">​Forum</​a></​li>​ 
-      <​li><​a href="​https://​chat.vuejs.org"​ target="​_blank"​ rel="​noopener">​Community Chat</​a></​li>​ 
-      <​li><​a href="​https://​twitter.com/​vuejs"​ target="​_blank"​ rel="​noopener">​Twitter</​a></​li>​ 
-      <​li><​a href="​https://​news.vuejs.org"​ target="​_blank"​ rel="​noopener">​News</​a></​li>​ 
-    </ul> 
-    <​h3>​Ecosystem</​h3>​ 
-    <ul> 
-      <​li><​a href="​https://​router.vuejs.org"​ target="​_blank"​ rel="​noopener">​vue-router</​a></​li>​ 
-      <​li><​a href="​https://​vuex.vuejs.org"​ target="​_blank"​ rel="​noopener">​vuex</​a></​li>​ 
-      <​li><​a href="​https://​github.com/​vuejs/​vue-devtools#​vue-devtools"​ target="​_blank"​ rel="​noopener">​vue-devtools</​a></​li>​ 
-      <​li><​a href="​https://​vue-loader.vuejs.org"​ target="​_blank"​ rel="​noopener">​vue-loader</​a></​li>​ 
-      <​li><​a href="​https://​github.com/​vuejs/​awesome-vue"​ target="​_blank"​ rel="​noopener">​awesome-vue</​a></​li>​ 
-    </ul> 
-  </​div>​ 
-</​template>​ 
  
-<!-- the second part from the .vue file is defining the logic/code --+<​code ​javascript
-<​script>​ +function Header() ​
-export default ​+  ​return <​h1>​Startup Engineering<​/h1>;
-  ​name: '​HelloWorld',​ +
-  props: { +
-    ​// here we define properties of our own components +
-    // we will see later how this comes into play +
-    msg: String +
-  }+
 } }
-</​script>​ 
  
-<!-- the last/thrid part is the style --> +function HomePage() { 
-<!-- Add "​scoped"​ attribute to limit CSS to this component only --+  return ( 
-<style scoped> +    ​<div> 
-h3 { +      {/* Nesting ​the Header component */} 
-  ​margin: 40px 0 0;+      <Header /
 +    </div
 +  ​);
 } }
-ul { +</​code>​ 
-  ​list-style-type:​ none; +  
-  ​padding:​ 0; + 
-} +===== Props ===== 
-li + 
-  ​display: inline-block;​ +Similar to a JavaScript function, you can design components that accept custom arguments (or props) that change the component’s behavior or what is visibly shown when it’s rendered to the screen. Then, you can pass down these props from parent components to child components. Props are **read only**. 
-  ​margin:​ 0 10px; + 
-+In your HomePage component, you can pass a custom title prop to the Header component, just like you’d pass HTML attributes. Here, titleSE is a custom argument (prop). 
-a { + 
-  ​color: #42b983;+ 
 +<code javascript>​ 
 +function HomePage({titleSE}) ​
 +  ​return ( 
 +    <​div>​ 
 +      <​Header title={titleSE/> 
 +    </​div>​ 
 +  ​);
 } }
-</​style>​ 
 </​code>​ </​code>​
-An interesting feature of .vue is the ability to use other languages for each of the 3 parts than the standard. As an example here we use scss instead of css which allows nested tags, mixins, funcions and variables. The vue cli project comes by default with scss support. 
-<code css> 
-<style scoped lang="​scss">​ 
-$color: #42b983; // our variables that are supposed to be globals can be defined in another file and then just included 
-@import '​assets/​scss/​global';​ //multiple global variables defined here 
  
-li { + 
-  /* this selects every li */ + 
-  ​displayinline-block;​ + 
-  ​margin: 0 10px+===== Conditional Rendering ==== 
-  ​+ 
-    /* this selects every a inside of a li */ +We’ll create a Greeting component that displays either of these components depending on whether a user is logged in: 
-    color: $color;+ 
 +<code javascript>​ 
 +function Greeting(props) { 
 +  ​const isLoggedIn = props.isLoggedIn
 +  ​if (isLoggedIn) ​
 +    ​return <​h1>​Welcome back!</h1>;
   }   }
 +  return <​h1>​Please sign up.</​h1>;​
 } }
-</​style>​ 
 </​code>​ </​code>​
  
-Now let's see how this component will be used as part as another component. Here is the default code of the Home.vue component that you will find in src/views folder: +We can also use inline if-else operators.
-<code html> +
-<​template>​ +
-  <div class="​home">​ +
-    <img alt="​Vue logo" src="​../​assets/​logo.png">​ +
-    <!-- here we use our subcomponent and we send it a value via our custom defined property called msg --+
-    <​HelloWorld msg="​Welcome to Your Vue.js App"/>​ +
-  </​div>​ +
-</​template>​+
  
-<​script>​ +When sending props from parent to child component, we can use **object destructuring** . Destructuring really shines in React apps because it can greatly simplify how you write props.
-// @ is an alias to /src +
-import HelloWorld ​from '​@/​components/​HelloWorld.vue'​ +
-// here we import the hello world component+
  
-export default ​+<code javascript>​ 
-  ​name: 'home', // this is the name we define for the current component +function Header({ title }) 
-  components: { +  ​return <​h1>​{title ? title : 'Default title'}</h1>;
-    HelloWorld +
-  ​} +
-  /here we expose the hello world component+
 } }
-</​script>​ 
 </​code>​ </​code>​
  
-While developing with you you should always have vuejs developer extension (for chrome/​firefox) that will allow you to easily inspect your components and vuex states. 
  
-{{https://​addons.cdn.mozilla.net/​user-media/​previews/​full/​194/​194260.png}} 
  
-=====A simple counter component==== 
-We are going to try to make a counter component with initialization and that emits events to it's parent 
-<code html> 
-<​template>​ 
-  <div class="​counter">​ 
-    {{counter}} 
-  </​div>​ 
-  <​button>​Click me</​button>​ 
-</​template>​ 
  
-<script+===== Iterating through lists ===== 
-export default ​+ 
-  ​name: 'Counter', + 
-  ​props: { +It’s common to have data that you need to show as a list. You can use array methods to manipulate your data and generate UI elements that are identical in style but hold different pieces of information. 
-    ​initial: { + 
-      //allow via a property of type Number to set an initial value + 
-      ​type: Number, +<code javascript
-      ​default:​ 0 +function HomePage() ​
-    } +  ​const names = ['​POLI', ​'ASE', ​'​UNIBUC'​];​ 
-  }, + 
-  data () { +  ​return ( 
-    //in components data is a function and not a property unlike app level, this is further explained in vue guide +    ​<div> 
-    // data needs to be a function that returns our local variables +      ​<Header title="​Universities" ​/> 
-    return ​{ +      ​<ul> 
-      counter: this.initial //we intiailize coutner with our initial value default to 0 +        ​{names.map((name=> ( 
-    ​} +          <​li key={name}>{name}</li> 
-  ​}+        ))} 
-  methods: { +      </ul> 
-   //methods is property of type object that will contain multiple methods for our use +    </div> 
-   increment (+  ​);
-     ​this.counter++ +
-     ​this.$emit('​valueChanged',​ this.counter//here we emit to the parent an event called value changed +
-     ​// now the parent will be able to use v-on:​valueChanged or @valueChanged +
-     ​// the method mapped to valueChanged will recieve teh current value of the counter +
-   } +
-  ​}+
 } }
-</​script>​ 
 </​code>​ </​code>​
  
-There are many other features important in components that you should ​read on: +Keys help React identify which items have changed, ​are added, or are removed. Keys should ​be given to the elements ​inside ​the array to give the elements ​stable identity.
-  * an in-depth explanation of [[https://​vuejs.org/​v2/​guide/​components-props.html|props]] with validation and other features +
-  * [[https://​vuejs.org/​v2/​guide/​components-slots.html|slots]] (allowing you to access ​the text inside ​your component <​mycomponent>​some content</​mycomponent>​) +
-  * [[https://​vuejs.org/​v2/​guide/​computed.htm|computer properties]] that allows you to define dynamic ready only data that you can access inside your component +
-  * Watchers that run code when certain value is changed inside data or computed props+
  
-====List rendering with v-for===+The best way to pick a key is to use a string that uniquely identifies a list item among its siblings. Most often you would use IDs from your data as keys.
  
-Quite often you will need to generate a list dynamically with a for (a table, a menu, etc). +<​code ​javascript
-For this we have v-for +const universitiesItems ​universities.map((uni) ​=> 
-<​code ​html+  <li key={uni.id}
-<!-- here we will go over an array called items --> +    {uni.name}
-<!-- items [{uid:1, message:"​some message"​},​ {uid:2, message:"​some other message"​}] +
-<!-- v-for expects you to bind a key via v-bind:key or just :key --> +
-<!-- this key needs to be unique yo each element and is used by v-for to know when an update is made or a new element appeared-->​ +
-<ul id="​example-1"​+
-  <li +
-    v-for="​item in items"​ +
-    :key="item.uid" +
-  ​+
-    {{ item.message }}+
   </li>   </li>
-</​ul>​ +);
-<!-- if your array does not contain it's own keys you can use the auto generated index of v-for --> +
-<!-- index starts from 0 for the first element and keeps increasing --> +
-<ul id="​example-2">​ +
-  <li +
-    v-for="​(item,​ indexin items"​ +
-    :​key="​index"​ +
-  > +
-    {{ item.message }} +
-  </​li>​ +
-</​ul>​ +
-<!-- modifying items in data will result in dynamic changes in the interface --> +
-<!-- v-for can also iterate over objects not just arrays --> +
-<ul id="​example-3">​ +
-  <li +
-    v-for="​(value,​ key) in object"​ +
-    :​key="​key"​ +
-  > +
-    {{ key }} -- {{ value }} +
-  </​li>​ +
-</ul>+
 </​code>​ </​code>​
  
-====Input binding=== +===== Adding Interactivity with State ===== 
-In many apps you will have inputs ​and you will want this inputs ​to be linked directly ​to a variable ​in a 2-way connectionWhen the input cahnges ​the variable updates and when the variable ​changes the input updatesThis is done via v-model + 
-<code html> + 
-<​template>​ + 
-  <div+ 
-    <​input v-model="​message"​ placeholder="​edit me">​ +React has a set of functions called hooks. Hooks allow you to add additional logic such as state to your components. You can think of state as any information in your UI that changes over time, usually triggered by user interaction. 
-    <​p>​Message is: {{ message }}</​p>​ + 
-  ​</div> +You can use state to store and increment the number of times a user has clicked the like button. In fact, this is what the React hook to manage state is called: useState() 
-</template>​ + 
-<​script>​ +useState() returns an array. The first item in the array is the state value, which you can name anything. It’s recommended ​to name it something descriptive. The second item in the array is function to update the valueYou can name the update function anything, but it's common to prefix it with set followed by the name of the state variable ​you’re updating. 
-export default { +The only argument to useState() ​is the initial state. 
-  ​name: '​HelloWorld'​+ 
-  ​data () { + 
-    ​return { +<code javascript
-      message: 'some initial value'​ +function HomePage() ​
-    }+  // ... 
 +  ​const [likessetLikes] = React.useState(0);​ 
 + 
 +  ​function handleClick() { 
 +    ​setLikes(likes => likes + 1);
   }   }
 +
 +  return (
 +    <div>
 +      {/* ... */}
 +      <button onClick={handleClick}>​Likes ({likes})</​button>​
 +    </​div>​
 +  );
 } }
-</​script>​ 
 </​code>​ </​code>​
-The above code will instantly update the displayed text as you type. 
-You can use a [[https://​vuejs.org/​v2/​guide/​computed.html#​Watchers|watcher]] over the variable message to detect every update for extra functionality. 
  
-====Component lifecycle===+===== Data Binding =====
  
-In the lifecycle ​of vue apps each vue component has multiple points where you can hook your own code. +Data Binding is the process ​of connecting ​the view element or user interface, with the data which populates it.
-Refer to the following diagram to learn the hooks:+
  
-{{https://​d33wubrfki0l68.cloudfront.net/​435786c6cbd23e078c35c2b21f40e1756b2c3d30/​2098f/​images/​vuejs/​external/​component-lifecycle.png?600}}+In ReactJS, components are rendered to the user interface and the component’s logic contains the data to be displayed in the view(UI)The connection between the data to be displayed in the view and the component’s logic is called data binding in ReactJS.
  
-Note that data does not exist in the before event hook so our firs opportunity to play around with stuff is in creates 
 <code javascript>​ <code javascript>​
-export default { +export default ​function HomePage() ​
-  ​data() { +  ​const [inputField,​ setInputField] = useState(''​);
-    return { +
-      property: ​'Blank' +
-    } +
-  },+
  
-  ​computed: { +  ​function handleChange(e) { 
-    propertyComputed() { +      ​setInputField(e.target.value);
-      ​console.log('​I change when this.property changes.'​) +
-      return this.property +
-    } +
-  }, +
- +
-  created() { +
-    this.property = '​Example property update.'​ +
-    console.log('​propertyComputed will update, as this.property is now reactive.')+
   }   }
 +
 +  return (
 +      <div>
 +          <input value={inputField} onChange={handleChange}/>​
 +          <​h1>​{inputField}</​h1>​
 +      </​div>​
 +  );
 } }
 </​code>​ </​code>​
  
 +===== Passing data from child to parent component ===== 
 +
 +In react data flows only one way, from a parent component to a child component, it is also known as one way data binding. While there is no direct way to pass data from the child to the parent component, there are workarounds. The most common one is to pass a handler function from the parent to the child component that accepts an argument which is the data from the child component. This can be better illustrated with an example. ​
 +
 +<code javascript>​
 +const Parent = () => {
 +  const [message, setMessage] = React.useState("​Hello World"​);​
 +  const chooseMessage = (message) => {
 +    setMessage(message);​
 +  };
 +  return (
 +    <div>
 +      <​h1>​{message}</​h1>​
 +      <Child chooseMessage={chooseMessage} />
 +    </​div>​
 +  );
 +};
 +const Child = ({ chooseMessage }) => {
 +  let msg = '​Goodbye';​
 +  return (
 +    <div>
 +      <button onClick={() => chooseMessage(msg)}>​Change ​   Message</​button>​
 +    </​div>​
 +  );
 +};
 +</​code>​
 +
 +The initial state of the message variable in the Parent component is set to ‘Hello World’ and it is displayed within the h1 tags in the Parent component as shown. We write a chooseMessage function in the Parent component and pass this function as a prop to the Child component. This function takes an argument message. But data for this message argument is passed from within the Child component as shown. So, on click of the Change Message button, msg = ‘Goodbye’ will now be passed to the chooseMessage handler function in the Parent component and the new value of message in the Parent component will now be ‘Goodbye’. This way, data from the child component(data in the variable msg in Child component) is passed to the parent component.
 +
 +
 +
 + 
 + 
 + 
 ====== Tasks ====== ====== Tasks ======
  
-  - Create a new vue project using vue-cli (if you can't install the component globally for any reason it will install in the node_modules/​.bin folder) or you can download ​the generated project {{:se:labs:todo-list.zip|here}} (and run npm install ​or run install after)+  - Download ​the generated project {{:se:labs:se-lab3-tasks.zip|}} (amd run npm install ​and npm run dev)
   - Create a to do list app:   - Create a to do list app:
-    ​- Create a component that will represent a todo-list item that should have+  - Implement the List component in component/​List.js 
 +    ​- Create a new component ​in components/ ​that will represent a todo-list item that should have
       - text showing the description of the todo-list item       - text showing the description of the todo-list item
       - delete button that emits an event to parent to remove the item       - delete button that emits an event to parent to remove the item
-      - a state variable in data() that represents view mode and edit mode of the item 
-      - an edit button that switches item to edit state and makes the item editable 
-      - an save button that emits the new value to the parent and switches back to the view state 
-      - use v-if toe design the 2 states inside the <​template>​ 
-    - Use the previously defined component in Home.vue to list an array of items you define in Home.vue 
     - Create an input that you will use to create new list items by appending to your array     - Create an input that you will use to create new list items by appending to your array
-  - Modify Home.vue to initialize the array of items from localStorage with localStorage.getItem and update the localStorage with localStorage.setItem on edits (or localStorage.removeItem if it needs to be deleted) 
  
 ====== Feedback ====== ====== Feedback ======
  
-Please take a minute to fill in the **[[https://​goo.gl/forms/VbXevv0IufQzRF1i2 ​| feedback form]]** for this lab. +Please take a minute to fill in the **[[https://​forms.gle/PNZYNNZFrVChLjag8 ​| feedback form]]** for this lab.
se/labs/03.1539989850.txt.gz · Last modified: 2018/10/20 01:57 by avner.solomon
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0