Ionic & Vue.js - Full Tutorial (Build a Complete App)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Try Quasar, it'll change your life.

๐Ÿ‘๏ธŽ︎ 5 ๐Ÿ‘ค๏ธŽ︎ u/bohaan ๐Ÿ“…๏ธŽ︎ Dec 04 2020 ๐Ÿ—ซ︎ replies

Maximilian is by far the best online tutor that I encountered.

๐Ÿ‘๏ธŽ︎ 5 ๐Ÿ‘ค๏ธŽ︎ u/karacic ๐Ÿ“…๏ธŽ︎ Dec 04 2020 ๐Ÿ—ซ︎ replies

Yaaasss this is exactly what I needed! Thanks for posting! Havenโ€™t watched it yet - is this a new vid? Does it use Vue 3?

๐Ÿ‘๏ธŽ︎ 3 ๐Ÿ‘ค๏ธŽ︎ u/littlecaesarspizza ๐Ÿ“…๏ธŽ︎ Dec 04 2020 ๐Ÿ—ซ︎ replies

I love Academind

๐Ÿ‘๏ธŽ︎ 3 ๐Ÿ‘ค๏ธŽ︎ u/rrallykid ๐Ÿ“…๏ธŽ︎ Dec 04 2020 ๐Ÿ—ซ︎ replies

Having Flutter being around the corner, its really hard to convince myself to learn a non-native mobile framework. Btw, I learnt Vue entirely from this guy, heโ€™s the best.

๐Ÿ‘๏ธŽ︎ 1 ๐Ÿ‘ค๏ธŽ︎ u/kirajiahaur ๐Ÿ“…๏ธŽ︎ Dec 04 2020 ๐Ÿ—ซ︎ replies
Captions
hi there welcome to this video in this video we are going to get started with ionic and vue ionic in case you don't know is basically a library which helps you with building mobile applications real mobile apps which you can distribute through the app stores and vue.js is a javascript library a javascript framework we can use for building modern front-ends modern web applications running in the browser driven by javascript now with ionic view we can combine both and we can build real mobile applications with vue.js and that's exactly what this video is about we're going to build this basic application which features a lot of important core features you typically want in your mobile apps like navigation forward backward navigation and using a device camera submitting data and storing data and we're going to build this application whilst learning everything you need to know for getting started with ionic and vue enjoy the video so let's get started with ionic view and the best place to get started really is ionicframework.com that's the official webpage of the ioniq company and project and there you got amazing resources you can learn all about ionic deer it's also a great place to dive deeper and on that page if you go to developers installation you find detailed instructions on how to work with ionic in combination with different technologies so here you can also learn how to use ionic standalone with just vanilla javascript how to use it with angular with react with vue of course which is what we're going to do in this video here and you learn about advanced features about theming and a lot of stuff though of course i'm going to walk you through all the important things all the important bits and pieces in this video so here if we go down to view on the left part here and to quick start we get an overview over what ionic is but then we also find installation steps alternatively you can also go to cli installation here at the very top below getting started and you basically find the same steps just in a more general way there and it all starts with installing the ionic cli with npm which of course means that we need to install nodejs first now we also need node.js because ionic also will spin up a little development server which allows us to preview our application we get live reload there and so on and that will also use node.js so make sure you have node.js installed from nodejs.org and you can simply pick the latest version here or the long time stability version should also work and once you got that installed i already do have it you can run this command here so simply open up your terminal or command prompt and run npm install dash g at ionic cli in there if you're getting permission issues on mac os or linux you might want to add sudo in front of that so simply enter your password if you should be prompted and maybe enter the right one and that will now install the ionic cli on your system which is simply a little tool the ionic company gives you which makes creating ionic projects but also running and building ionic projects easier now once you got that installed make sure that you switch to a folder on your system where you want to create your new ionic project i just did that and then simply run ionic start in that path and ionic start is a command which will then open up the the wizard for creating a new project which allows you to well create that project and here we first of all have to pick the framework we want to go with and i will go with view here since this is an ionic view video so simply select that hit enter and then give your project a name of course and i will name it view first app but the name of course is totally up to you this will also be the name of the folder which is created for the project though now you can pick a starter template there you can for example start with an application which already has tabs or a side menu but i will start with a blank application and this will now basically set up this project folder for you walk through all the installation steps of installing all the required dependencies and it will take a couple of moments and once it's done you will have your ionic project set up already now i can already say whilst this is setting up ionic of course is a tool a framework a library which we use to build native mobile apps at least that very often is the the goal when you start using ionic i also want to say though that actually ionic is not that technology ionic is two things it's the company which built ionic so the company is also called ionic and ionic is a library of ui components in the end so of components that have a certain look and feel and which allow you to build rich user interfaces and these components happen to look like the native counterparts so they look like you would expect components to look like on android or ios they also automatically adapt to the underlying operating system to have the proper look that's all amazing but ionic the library alone will not give you a native mobile app instead it will give you a web app you can build a web app with it because these components which you're using are basically web components simply then wrapped for the specific framework you're using ionic with so in our case we'll get a bunch of view components which under the hood are just these native ionic web components just wrapped with view components so to say and that's ionic so you can build nice looking web applications with ionic it's giving you all these components which you need but to get a native mobile app you actually need another technology which is also developed by ionic the company and that would be capacitor capacitor is another library which we haven't installed at this point of time which in the end allows you to turn any and that's important any javascript application any web application let's say any front-end web application consisting of html css and javascript into a native mobile app for android and ios which you can distribute through the app stores you don't need to use ionic to use capacitor often you will because ionic gives you the proper look so to say but you can add capacitor to any project to any front-end javascript driven project and it will give you that native mobile app that's really important now we'll come back to capacitor later because of course we're going to build native mobile apps here but we're going to start with just building a web app with ionic because capacitor in the end will then just wrap this web app into a native mobile app so you get a real native mobile app but in the end it's this wrapped web app so back to ionic we installed the ionic cli we created the ionic project and that of course means we can now open it up in our favorite editor or ide now i did that here i'm using visual studio code and in the end here i'm just using the default dark plus color theme if you want that same look i got a couple of extensions installed important here is probably path intellisense which can help with auto completing import paths prettier for code formatting vture for great view js development because that's important we're going to use these ionic components but all the logic and all our extra components which we might need will be written with javascript and view so we're still building a view app here as you will see and that's why i have this extension installed and yeah that should basically be it now we got our starting project here and in the end that's a regular modern front-end project as you know it from vue from react and so on just already fine-tuned for ionic now it actually already did add capacitor here you also see it in package.json i have to correct myself there but we're not going to use it yet but soon so capacitor is already pre-installed and pre-configured to turn this into a native app but for a moment let's focus on ionic and vue and for that as you see in the package.json we got view installed version 3. we got the view router already installed and that's the regular view router which you already know and as a side note of course if you want to learn all about vue if you need these basics first then my view the complete guide course might be just the right thing for you you of course find a link below the video also with a nice discount i'm not going to teach you here in this video that's not the goal of it i'm going to focus on viewing ionic so we got view parts and libraries installed and then we got ionic view installed and the ionic view router which in the end is a wrapper around the normal view router just with some extra animations which have this nice mobile animation look and that is basically what we got here and then a bunch of development dependencies for a great development experience got a bunch of configuration files here but then here it's the source folder which is interesting to us and we can already see we got typescript here um by default ionic projects at the moment at least give you typescript projects because ionic itself is written with typescript the ionic team likes typescript and it is a great language i like it too but of course when working with vue you might be used to working with just javascript and the good news is you can easily adjust this to have just a view javascript project with ionic you also find adjustment steps in the official docs here if you go to the view part quick start and then here build your way with typescript or javascript here you find instructions on how to move from typescript to javascript and that's what i'm going to do so first of all run this command here inside of my project so here in the terminal navigated into this project to basically uninstall all typescript specific packages because we don't need them if we don't use typescript as a next step we basically need to change all ts extensions to dot js obviously and we only have two files which we need to adjust that's the main js file and then here in router the index ts file which i change to index.js now this shims view dts file can simply be deleted you also find this script here this step here and we also can and should edit our eslint rc javascript configuration file here where is it here it is and in that file we should remove this view typescript recommended and typescript eslint entries so this one and this one and then save that file of course you can also delete the tsconfig.json file because that is a configuration file for typescript and if we're not using typescript we obviously don't need that and then as a next step we also have to adjust our code files a little bit in main.js we should be good yes in a router index.js we need to remove this type assignment here though because obviously we can't use types anymore we also can get rid of that import then that one import here and that's it and in app view we want to remove this lang equals ts part here on the script and in views in home.view we also want to do that so get rid of this as well and that should be it let's have a look yep that's looking good and now we got a javascript app so a couple of adjustments let me quickly commit this converted project to javascript you also find all the code attached or linked below this video so you can of course also use that code if you want to get this starting state okay so now we got this all set up and now let's see what we get out of the box for this i'll open up my terminal here built into this ide of course and we can now simply run ionic serve here again using that ionic cli but now to bring up a development server which serves this application so let me hit enter here and this will now well obviously start a development server it should automatically open up a new tab in your browser here it is and that's our ionic view web application which with capacitor can easily be converted to a native mobile app and that's what we get out of the box here we got this here and if we have a look at this home.view file we can already see a couple of ionic components in action here all these i and dash elements here these are ionic components which are part of the ionic framework the ionic library which we can use in this project here we also see that all these components are in the end imported down there in our script tags we're importing them from ionic view and they're then defined as local components here in this component in this view component and that's also important we have a regular view component which we export here the fine component is a function you might not have seen before i'm not using it in my view course for example you don't need it technically you can remove it it can just provide extra understanding to the ide and to typescript which is why it was there initially because this project was created with typescript you could remove it and everything would still work if i save it now you see i still got this project here and that's that that's this first starting page but of course we're not here for the first starting page instead we want to build our own ionic application and we want to get a feeling for how view ionic works and therefore i'm going to clear everything here i'm going to delete the home view file i'm going to delete the views folder even and in app view i'm also well i can leave the find component here i will leave app view as it is actually but in the router index.js file i'm going to remove this route and of course remove the import because this home component doesn't exist anymore and now let's start from scratch because now obviously this page is empty so how can we now build an ionic view application and for that let's actually start by adding let's say a simple list yes lists are always boring i know no one likes them but it is great to get started with them because with a list where we can add and remove items i can actually show a lot of things and we're going to spice this up fraud this video by then also adding the camera so that we can take a photo and that we can basically manage data which has images included but that's the next step let's start with the list and for this i'll first of all create a new folder named pages and i'll add a first page and let's say we're managing a bunch of memories here so i'll name this memories page dot view which is just one possible way of naming this component and this will be a view component and it will hold the code for one of the pages i want to have in my application which will render a list of memories in the end now here we create a regular single file component with a template and a script tag and i will also say right away with ionic view you can of course use both the options api for building your components or the composition api both works and i'll use the options api here maybe if you want it we can also transform this project to the composition api in a separate video but i'll use the options api because i would guess that more people know how to use that okay so we get this template now we got this view component and we want to use it as a page which we load with the router so in our router index.js file here i will actually import my memories page from dot slash no going up one level and then pages memories page dot view and add a new route and you add a route just as you know it from view router because we are using view router here so there's nothing special about that so here i will then simply add a path let's say slash memories and i'll define a component which should be loaded for this path and that's my memories page so this component which i'm importing here and i'll ensure that all requests to just slash so my domain slash nothing are forwarded to slash memories by setting the redirect here and if we now save that we get an error because we got an empty template here in the memories page but this proves that it's trying to load this component at least now in here we generally can now write regular html code because it is a regular web application and that's really something you have to keep in mind it is a regular web application you can apply what you know you could add a header here you could add a h2 tag where you say the memories page all of that works you can do that if i now reload and i go to slash nothing i'm forwarded to slash memories and i see the memories page just with some default styling which is provided here by iotic basically we're going to have a look at styling later so we get the memories page and of course we're not here to build just a regular web application with just regular html instead we typically want to use these ionic components to get these nice looking mobile ready components and for that we need to import and register the components which you want to use and we could import and register them as global components as you know and learn in my course but also as local components and generally registering components locally is a best practice because it ensures that components are in the end only loaded if needed if you are loading the component that uses the components lazily so if you would load memory's page lazily which we're not doing at the moment but which we could do if we would do that then all the local components in memories page would only be loaded if they're needed which of course is better than if they're always loaded it reduces the initial bundle size so therefore here in the memories page component we import from ionic view and we now import all the components we want to use here obviously you now probably ask yourselves which components do we have here and the answer of course can be found on ionicframework.com if you go to developers again and click on ui components then you get an overview of all the components the ionic library comprises and you get a bunch of components there for alerts for modals for lists for forms everything which you might want to build and of course definitely browse through this list here to get a feeling for which kind of components you have i can tell you what we will need is first of all an iron page component and all these ionic components start with iron so we will need an iron page component we'll need our i n header component we'll need our i and title component and i'm going to tell you why we need them of course but we will need those we'll also need the iron content component and these will be four essential components which you basically need on every new page which you build not on every component which you build but on every component which you want to load as a page through the router and i'm going to tell you why in a second now once they are imported in our component object here we have to register them as components through the components option no matter if you're using the options or a composition api and we do this by picking a key name of our choice for example iron page and assigning the appropriate component on the right side of the colon and of course we can shorten this in modern javascript and just write iron page to register the iron page component under an iron page key so let's do the same for i and header and iron title and iron content and once we did all of that we can use these components in this memories page component and here we can now use them with kev up case also with this syntax here since this code will be compiled ahead of time but i'm a fan of using kebab case since this works always with vue no matter if you load it through a cdn or whatever and the goal here always is if you're building a page so if you're building a component which is loaded through the router that you wrap the entire template the entire content which you want to load with the iron page ionic element this component this is required to ensure that ionic can load this page with a nice animation and transition between multiple pages if you would have multiple pages smoothly at the moment of course we don't have multiple pages but that's going to change so always use iron page around your main page components which you're building with vue in ionic and that's true also if you're using ionic react or ionic angular as you also learn in my respective ionic angular and ionic react courses also linked below the video of course so we got this iron page and then once we get that it's important to understand that every page typically consists of two main parts and that's the header so this bar at the top which we saw before which is gone now but the header basically and then the main content and that's why i added iron header and iron content the title is simply the title of the page in the header so the visible title not the metadata title or anything like that but the title which you can see so here we're going to add our i and header now and the iron content side by side and in the iron header we can also add our iron title and simply say all memories here as a title and here between iron content i'll say h2 these are my memories list to be added like that and if we now save this and go back to our application we see our title here and we see this text here and actually i forgot one super important component which you also always need and that's the iron toolbar you also need to import that and also add this by the way the position where you import and add it doesn't matter you need the iron toolbar as well because inside of the iron header around your iron title you need that iron toolbar component for proper styling so make sure you add iron toolbar very important component and now this looks better so now we got this web application and um yeah we got our first ionic page obviously not too exciting yet but we're getting there step by step so now that we've got this first page here let's fill it with more live than just this h2 element and for that i want to render a list here and for this we get the iron list component and also already the iron item component which allows us to render list items and we then simply import iron list and iron item so we'll simply add them as components and then here in iron content we can add an i in list and then here in the iron list i iron item and if we do that we could render a couple of names here max manual julie george whatever if you do that and reload you see these items here and now let's also switch away from this web view here it is a web app but let's not view it like this but instead here in chrome we can open up the developer tools and then click on this icon here to preview this on a mobile device so to say it's still a web application but we see how it will look like on a mobile device and here let's say we go i want to preview it on an iphone x or maybe well let's actually go with the pixel 2 and now we got the look we will probably have if we would build this as a mobile app and run it on a pixel 2 though the final look can always deviate a bit you should always test it on a real device and we're also going to do this later so we got this now i got this dummy list rendered of course with hard-coded data though but it is a first step before we take any other next step let's talk about the styling here now we got some default styles like these separators between the list items a certain font but of course it's also pretty white at the moment right and we can fine-tune the entire look here with our theme folder and the variable css file here though i also want to say that of course you always have to keep in mind that this is a regular web app which you're building so you can always add in your own styling you can add the the style section here in your single file component and start styling these elements you can even target these elements so you can even target the ion title like this and then assign a background color of red for example you can't do that doesn't look pretty here but you can do that now for a general theming and for tweaking these out of the box styles which you get we have this variables css file here and in there a feature is being used which is built into modern css and modern web development so to say the css variables feature this is not sas or anything like that instead here we get a bunch of css variables which are used under the hood by the ionic components and here we can tweak our different colors and also which colors should be used to wear so as you can see for example we get some basic colors here quite a lot we also got support for dark mode here though i will actually remove that here i will remove that dark mode part here not entirely though let's grab these color steps here the eye and color step variables and let's cut them here and actually add them here in this first block so in this first block for this root selector and then thereafter i'm going to remove everything below that root selector because i want to keep it simple here so we already got a bunch of colors though that's what i want to say and nonetheless we don't see these colors being used anywhere because it just happens to be the case that out of the box a toolbar for example doesn't use any of these colors or not one of the colors we can see it uses a white color to be precise but that's something you can change you can add a new file here in the theme folder which i'll name core css the name is entirely up to you though and i will import this in main.js right below this theme variables css import here i'll import theme core css so that whatever i write in that file will be picked up and here i'll now target every iron toolbar element so this will be applied as a global style not scoped to any component and in there we can set another special variable so using these css variables is an important thing in ionic and you can always see which ionic variables or which css variables can be tweaked where if you look for a specific element like the iron toolbar and then you'll learn how to use it and then at the bottom you have a list of css properties which you can override and for example here we can set the background off the toolbar by setting the dash dash background css variable inside of the iron toolbar selector so here dash dash background and here we can now set this to a certain color and of course i want to use one of the colors i define here for my theme let's say the primary color and for that we can use the var function in css and then use some other css variable which has been defined before in this case the iron color primary variable i'm using it here as a value for this upper variable which then under the hood will be picked up by ionic to give that toolbar a background color if we do all of that we see now it's blue now to ensure that the text is well readable we also want to set the dash color variable inside of iron toolbar because that allows us to set the text color and i'll set this to iron color primary dash contrast which in variables css defines a contrast color for this primary color max from the future here i have to step in here real quick you can set the color of the toolbar items like this and this will work on android but on ios you might not be seeing the toolbar buttons and so on so instead of setting dash color in the iron toolbar selector for that you can also set a different variable in the variables css file in this root selector here there you can also set the iron-toolbar dash color variable to this primary contrast color and by doing that the toolbar items all the buttons in the toolbar and so on should have the appropriate contrast color not just on android which should work with this setting alone as well but also on ios that's just a little note if we do that and go back here this looks better now maybe you don't want to go with these default colors though then of course you can tweak these variables in the variables css files and use different colors for the primary color the secondary color and so on and there are different components in the ionic library which will use these colors some if you tell them to and some out of the box now if you want to adjust all these colors in one go and get a nice tool for tweaking and previewing the colors you want to pick you can go back to the ionic docs here to developers yeah let's go to installation and then here to the theming part and there you'll find a color generator which is awesome there you get a preview of your colors and you can tweak these colors and then you can export them as css code so for example here i could pick like a purple a dark purple color here for my primary color secondary let's say is then a lighter purple and a tertiary i'll i'll stick to this darker bluish purple here and actually for secondary let's maybe go with that color or let's actually take a orange color as a contrast that might be good too so these are the colors i'll pick you can tweak them all you can tweak the success colors and then you can just click copy down there and you get these variables you can now go to your root part here and actually replace all these colors you could almost replace the entire root selector but i want to keep these color steps here which are for text colors so i'll just repeat the other colors and just replace the other colors and get rid of this unnecessary nested root selector here okay if i now save that with my new colors here we go got this purple color and that's how you can tweak this so it's this combination of using all these css variables to tweak individual components and setting these core variables these colors maybe with help of the color generator to give your application the look you want and in addition to that always keep in mind that you can write your own styles as well so you're not limited to just the built-in variables and so on you can always override everything and tweak everything with your own custom css styling you can learn way more about styling and theming and how you could add brand new colors with your own names here in the theming docs of course there you can also explore how to add dark mode for example but i'm happy with this look here and therefore as a next step i want to make sure that we can tap these list items so that we're taken to a second page so that we then also can see these beautiful animations in action so let's add a second page and here i'll have my memory details.view file and of course at the moment these aren't really memories these are names i'm aware of that but we're going to change this to be memories soon actually let me go there to the memories page and give these more memory-like names like a trip into the mountains surfing the sea side whatever good eating and let's get rid of the third one so now this is more memory like and now i get the memory details component again it's a regular view component so we add our script and our template here and as i mentioned before we'll need this core skeleton of having iron page i in toolbar and iron header iron content and typically also the iron title and therefore of course we want to again import like on the memories page all these components here from ionic view however if we do that we basically repeat ourselves which is not horrible here but which we typically want to avoid the better solution in the view world would be to build another component and then use composition to combine these different components to avoid reusage and therefore we can add a components folder here in the source folder and in there maybe add another folder which we named base whatever for some base components and oops and in there in this base folder in the components folder i'll add a base layout dot view file which should hold a base layout component and here i'll again use template and script and now i'll take the imports from the memories page component and add them here in base layout however not i enlist an iron item just page header toolbar title and content and i'll of course register them as components so i'll copy that as well but get rid of iron item and i list of course and then here in this template i will basically copy my skeleton from memories page so this entire iron page block with iron header and everything inside of it and paste it in here but actually replace the concrete content so in this case this list here with a slot that's how we then later can use composition to use this here as a wrapper component and then put any content in there which we want to that's how we can do that and we could use multiple slots if we had multiple dynamic pieces so here i of course also want to make the title dynamic and we could use another slot for that a name slot but i will just use interpolation here and name this page title and expect a prop here so in my component definition i'll add props and then either use the longer syntax where you describe in detail how a prop should look like or just have an array of props and define the page title here so that we get this as a prop and then we can use the base layout component here in memories page or since we're going to use it in a lot of different components in the app and basically on every page we even register it as a global component because importing this early won't hurt because we're going to use the base layout component on every page anyways so over here we can import base layout from dot slash components base base layout dot view and then simply use our app here called component method on it and register the base layout component under a base layout tag like this and now we can use this in any view component so here in memories page we can now replace i and page and ion content here with base layout like this and of course also use the closing tag here and set the page title to all memories in this case if we now save that i have an error yes that i'm importing a bunch of things which i don't need here anymore so let's remove iron page header toolbar title and content imports from the memories page also remove the component registrations because the actual ionic components we're actively using in this template here in the memories page now is our list and iron item because of our outsourced base layout and now we can use this base layout in memory detail as well like this and just set a different page title like the details though of course maybe this should be dynamic later for the moment i'll hard code it and then here we can have a h2 tag where we say the details page for the moment now save that and reload this works again and now we want to reach this memory details page of course and how did would that work well it's a new page and i want to be able to go there with routing therefore we want to go to our router index.js file and then add a new route here with a path of let's say slash memories slash id as a dynamic segment and then load this component and here we can actually also use lazy loading because we might not always visit this page and that's very easy to do in view we just add an inline function here and dynamically import from the pages folder the memory memorydetails.view component and then this code for this component will only be downloaded if we really need it now in order to go there we now also need a link and the link of course should be the item here right the different items we have if we click them i want to be taken to the details page for that item so therefore on the memories page where we have that list every item should be clickable and that's something you can easily do in ionic now to go to the details page when clicking on this ion item we can simply add a router link on it and then simply point at memories 1 for example to go to the memory with id 1 of course 1 or the id 1 is just made up here if we do that and reload i can click on a trip into the mountains and i'm taken to the details page and we can use the browser back button for now to go back and that's how easy we can navigate here now of course we might want to have a back button here in the toolbar since that would be our mobile app in the end and you don't always have a another back button on android you might have that on ios you don't in the effort to add a back button we can go to the base layout where we have our header and toolbar and inside of the toolbar we can use another ionic component related to navigation and that's the iron back button which we should import and then register as a local component in the base layout and then here we can add iron back button here in the toolbar if we now go back reload and go it to a trip into the mountains we see it here now obviously it's placed awfully it works but it's not looking pretty because ionic doesn't know where to place it in this iron toolbar we now get two elements the back button and the title with one element everything was fine but you can think of iron toolbar as an ionic component because in the end it is which also has a slot and all the content between the opening and closing tags of iron toolbar is then placed in that slot now for one element this was no problem but now both the back button and the title are placed in this one slot in the middle and well they simply split the content or the available space therefore looks like eye and back button takes the entire line and therefore the details moves to a new line and looks ugly now we can tell ionic where to place something by adding the slot attribute to certain elements in certain places for example to the back button inside of a toolbar we can set this slot here to start however we shouldn't do this on the back button actually but instead we should use a narrower component the iron buttons component iron buttons not button but buttons all the registered and then wrap your back button with iron buttons and add the slot start on iron buttons iron buttons is a specific component which should be used inside of the toolbar instead of a header so that ionic can position all the buttons you might have there because obviously you can have more buttons in the toolbar than just the back button so that ionic can place these buttons in a nice way and now if we save that with iron buttons with a slot start and the back button inside of the iron buttons if we now go back reload and go to a trip into the mountains now this looks better and you also see the beautiful animation we get out of the box because we're using ionic under the hood the ionic view router and the iron page components now you'll also notice that if i reload on the details page i don't have the back button the reason for that is that if we reload all the previous applications state is lost and therefore ionic doesn't know if we can go back and where this back page would be it does know it if we come from another page without reloading in between because it then memorizes that we came from there but if we reload on the details page that information doesn't exist so to make sure that we still get the back button there we can add a default ref a default reference here so a default link basically which will be used and since i have my base layout component here which can be used on different pages this default ref should be dynamic and should maybe point at a prop which i'll name page default back link whatever name you want to use i'll go with page default backlink and add this as a prop which i expect here and now we can go to the memories page where we use the base layout excuse me to the memory detail page where we use the base layout and set the page default backlink to slash memories because from the memories details page which is slash memories slash sum id we want to go back to just slash memories if i now save that and i reload you see the back button is there after reloading because we set the default link and i can click it to be taken back to that page even though we reload it and that's the basics of navigation in action here now with that we got our list we can navigate back and forth and we added some styling let's now use at least a little bit more dynamic data here instead of having the hard-coded ion items here so let's now make this a little bit more dynamic and for that in the memories page component i will add my data option because i said i'll use the options api and in here i'll have my memories simply an array of items and now it'll still be some dummy data but i at least have a little bit more complex dummy data and will render the list here dynamically so every memory let's say has an id m1 for example and has a title which can be the nice titles i came up with up here so simply have these titles here as strings and then let's say every memory also has a short description text it was a really nice trip something like that now i'll also replicate this to have more memories and then here i set my title to surfing the seaside of course because that was the second title i used here and last but not least let's add this third dummy memory here good eating and adjust the descriptions feeling the cool breeze something like that and here [Music] really tasty now obviously this is just some dummy data we can of course also add some images some links to images which should be shown here for that i'll add an image field here and now we need to find some images so here i just did a quick image search for images which i can use for free here and i'll just grab a bunch of such links here i'll fast forward through that i'll skip that because you can simply pick some images of your choice some links to images of your choice here and fill that into your dummy data so be right back and here i have it i added image links to all three items and now we want to output them dynamically and of course also render these images so therefore first of all i'll remove two ion items here and remove the hard-coded text and the hard-coded link and we're going to use a directive which we know from view the v4 directive for looping through some data and rendering a component multiple times so here we'll go through all our memories so memory in memories is the code we have here to go through all these memories and then the router link for example is set dynamically to a string where we go to memories slash and then here i'll inject memory dot id so that we go to that page and here i also of course inside of the iron item wanna have my title which is now output dynamically with interpolation here and that's memory memory.title and if we use v4 we also should set the key here bind the key in this case dynamically to memory.id so that every item has a unique id a unique key and now we get the same text as before but output dynamically obviously it would now be nice to also have an image and for that we can use another component which you can import from ionic view and that's the iron image component we could also use the regular image tag but the iron image also has some extra features it also is easier to style and easier to fit into an iron item that's a plus and in addition it's loaded lazily so it's only loaded if it needs to be displayed and if it's outside of the visible screen it would not be loaded for example that's why i'll use iron image instead of the regular image we do then use it just like the regular image though in the end so we add iron image like this and then set the source here dynamically to memory dot image because that is our image link right and set the alt text maybe to memory.title and if we do that we now get an image as well obviously however not looking that great because it doesn't have the finished styling out of the box it's just a bit easier to combine with certain other ionic elements but here i'll use the iron thumbnail image to add an image which looks good because we can simply wrap a image even a normal image actually with iron thumbnail inside of iron item use the right slot again to tell ionic where instead of the item to position it and it will look good so let's add iron thumbnail and let's also already add iron label because we'll need that as well and register both eye and thumbnail as well as iron label as components in the memories page and then wrap the eye and image with iron thumbnail like this and wrap the text with iron label this is technically not required we could also use a span but this again ensures that everything looks perfect and works perfectly together now on iron thumbnail we again add this slot instruction which certain ionic components take in certain places in this case to tell ionic where to place this thumbnail inside of this item and i'll set slot to start to tell ionic that it should be in a specific spot at the start so on the left of the ionic item if we now save that and go back this looks much better right doesn't this look beautiful we now got our items here we can of course still click them and please note that in the url different ids are loaded so now as a next step of course let's make sure that we also display the real information for the specific memory on the memory details page and for that of course we need to find out which id this page was loaded with and then we need to grab the data for that and for this of course we also should manage our memories not just here in memories page but also in a more global place where all components have access to that could be our app component our root component for example with provide and inject we can make data accessible in all components we could also build our own state management solution or we use vuex so for that i'll stop this development server here and npm install dash dash save view x at next at the moment because i'm recording this at a point of time where the latest version of ux is not officially out yet it's stable and everything but yeah so let's install view x here and view x in case you don't know is views official state management solution for managing application-wide state i also teach that in great detail in my view course so if you want to learn all about that my course is the place to go let's wait for this to be installed and once it is installed here i will restart ionic serve to bring up that development server again and add a new store folder here next to my pages and components folder and so on in which i want to set up my view x store now there are different ways of defining a ux store depending on the complexity and so on you can use modules to split it into multiple pieces here i'll set up a very simple store i'll just add an index.js file in the store folder and then import from ux and import the create store function here and then we create a store by calling create store and i will then export that store as a default and go to main js and there below importing my router actually now that i see it let me also import my component up there to have all the component imports in one place this is optional but i still want to do it but now below that below my router i'll import my store from dot slash store we could say dot slash index but it will automatically import from the index.js file if you have such a file in a folder and now we just need to make view aware of this store which we do by going to our create app call here and we chain another use call to also use our store in this created view app and now this store is available now in or to create store we pass an object where we configure this view x store and there we definitely need a state function which returns our state data and my state data is actually the data i had in the data option on the memories page before so i'll grab this memories key here cut it from the memories page and add it here in my view x state now i also will of course add some getters so that we can get that data and i'll just name my gather memories we get access to the state here and i'll keep it simple and i'll just return state memories so i'll just return these memories we can also add mutations and actions but for the moment we don't need these so now back on the memories page we of course want to utilize this store and we typically do that by adding a computed property with the computed option here in this case since i'm using the options api and here i'll add well i'll name this memories as well and return this dollar sign store this is a globally available property because we added view x and we're using view x on our app and then there i access dot getters.memories and this gives me access to the memory scatter which i defined a second ago and now we again have access to the memories here but they're now managed in ux if i save and reload though it still works as before but since i'm managing my data in view x now or with vue x now we can also take advantage of it here in the memory details there i now want to get the memory for the specific id that was loaded for that we first of all need to find out which id was used for visiting this memory details page because of course we have different ids now we can get that idea and store that id by adding some data and having our memory id here which initially is null and then we can add a watcher and actually watch dollar sign route dollar sign route is a globally available property which exists because we're using the view router now this is a method actually watchers are methods in view and this method will be triggered whenever our route changes and it does change if the id changes for example we then get our current route object here and we can for example extract our id parameter from there so here we can then set this memory id equal to current route dot params that's where you access the route parameters so the parameters encoded in the url dot id dot id here because in my router configuration i named this segment id if you use the different name here you also need to use a different name here so now with that we get our memory id and now we can use a computed property here to get a specific memory for that id and for that we need to go back to the store and that and add another getter which we could name memory and here we get our state like an all getters but here i actually return a function so that this getter actually returns a function to the place where we access it and this function takes the memory id as a parameter and then simply returns so this function which is returned returns state memories find and now i'm searching for a memory where the id is equal to the memory id i'm getting as a parameter in this return function and that allows me to call this function from inside my view components to get a specific memory from that list of memories which i have here obviously this will return undefined if we don't find a memory for this id in the memory detail page we can now add a computed property memory or loaded memory whatever you want to call it and here i'll return this store getters memory but now i don't just point at it as i did it with my memories getter in the memories page but i'll execute it because memory is now a function it's a function the function which we return in this getter which we need to execute to find a specific memory and here i'll pass in my memory id and this will give me that memory uh which we loaded now obviously we might load a page for a memory which doesn't exist that's why we should have a fallback for that we could for example say we load this h2 tag if not loaded memory if that is undefined or knowledge then we say could not find a memory for the given id but otherwise we say loaded it for the moment just to see whether it works with the else in this case and we also want to bind the page title dynamically now to use the actual memory title so here we can access the loaded memory dot title if we now save that and we go to a memory we get an error cannot read property title of undefined a reason for that is that initially we have no memory yet we start with a memory id of null so therefore there is a time span where we don't have a loaded memory yet because we don't have an id yet and that's why accessing this title doesn't work so we can simply check whether loaded memory is truthy and only set the title if it is and other and otherwise say loading like this and if we now do that and i now click here this looks better at least to a certain degree but it never loads the memory which we want it always says loading and that it could not find a memory for the given id so why is that happening simply because this watcher isn't fired when we initially load the page it would fire if the route would change whilst we're on the page if we if we had a button that changes the id in the url whilst we're on the page for example but not if we initially visit the page but the good thing is when we initially visit the page we can already read the data from the url and we can set our data here this memory id which we initially set as a first value to this route params.id therefore and then only have that watcher as a backup if the id should change whilst we're on the page if you can rule out that this ever happens and indeed in this application it shouldn't happen we can of course also remove this watcher now with that we now reload you see a trip into the mountains is loaded here and if i reload the page we also load that so that's now working when i navigate away you see the data here is lost but to my knowledge this is just a temporary bug with the view router where this watcher fires when we leave the route and since we don't need it anyways i'll comment it out this watcher and then i always have this proper behavior here so that's working now we have our dynamic data being used loaded on both the list page as well as the details page now let's refactor this a little bit before we then make sure that we also can add our own memories which also then will happen with help of the device camera so let's refactor this a little bit at the moment we have only two page components and the memories page component for example holds the entire list rendering logic it is a better practice to split this up and to have small reusable components just as your functions should be focused on one thing and should be small have a look at my clean code course to learn more about that so in components we can therefore add a memories folder for example and in there add a memories list.view component and also already a memory list item.view component now let's start with the memory with the memories list though i have my template in my script in there and my goal is to take that entire iron list and cut it from memory's page and instead render it here in the template of memories list however the iron item actually will not be rendered here i'll cut that instead that will be rendered in the memory list item so here we also need a template where we render the iron item and with that we can have these smaller easier to maintain components which are each focused on one thing for example here the memory list item component is focused on well rendering a memory list item so we get the ion item here and therefore here in the script tags of this memory list item component we need to import the ionic components which we are using here in this case the iron item the iron thumbnail the iron image and the ion label not loading but label and then register these components as components here in this view component like this and now we can use them all here now of course in the memory list item component we rely on a bunch of data we need our memories to be precise so that we can loop through them and therefore i'll add a prop which i expect here and that's the memories prop here we could also use the more expressive props syntax but i'll use the short one here to save some time so we have memories as a prop in memories list we now use the i list so we want to import that import ion list from ionic view and register that as a component here and of course here we also need the data which should be rendered in that list we need our memory list item and we need the memories which we then use to create these memory list items and therefore here i expect to get some props as well i expect to get my memories and actually this is the actual place where we should get our memories not the memory list item there we should actually get a single memory because that looping logic with v4 should not be in the memory list item component that's just one item after all it should be in the memories list component so let's grab this looping logic and that key here and just refer to memory all the time which is the new prop i set up there and in the memories list component let's import the memory list item component from that memory list item.view file and register it as a component of course here in the components key and instead of iron list we then render the memory list item and we put our v4 directive onto the memory list item and i add our key here as well and now we also want to bind the memory prop here because that is the prop the memory list item component expects so we add this and bind this to memory so to the memory variable we get from this loop here to this variable we bind the disk prop and now we can use the memories list component in the memory's page component so here we can remove all these imports actually we're using none of them anymore and instead just import the memories list component from components memories memories list dot view register this as the only component here and then in the base layout simply output memories list and pass in the memories prop which we do expect here in the memories list component pass in the memories prop and bind it to the computed memories property we got here so that we get the memories here in the page component we could get them in the list component as well but it's here in the page component where i want to do all that data fetching and then we forward the memories to the memories list which is responsible for rendering a list which then renders the memory list items which are responsible for rendering the concrete items and if we saved it all we should have the same output as before except that i got this error but that's because i do import iron label in the memory list item component but i'm not defining it as a component which we of course should do and now i got a duplicate key for iron item yes this doesn't need to be imported twice or defined twice once is enough and now this works so now this is working now let's work on the details page and let's make sure that we dare also see more than just this dummy text and for this here in memory details we of course want to render more than just this h2 tag here and therefore i'll already create a new component here in the components folder in the memory folder in this subfolder and here i'll add a new component and i'll name it memory overview dot view that's my file name got my template in there and my script tags and in here i in the end wanna let's say render an image and then below that the title and below that the description hence i will import a couple of components from ionic view and we can import the ion image again we could also use the regular image because lazy loading won't really play a role here this image will always be visible but i'll stick to iron image here and that's it for now actually let's now register this as a component and then in here output iron image and set the source to something and set alt to something like this and below that maybe a h2 tag where we want to output the title and below that h3 tag where we have the description or a paragraph tag is maybe better and now of course the data is missing and i want to get that through props because this is not a page component which is loaded through the router and even though we still could use the router to get the id here and then reach out to ux i want to use the memory details page component here to fetch all the data and then just pass it on to my memory overview component here and as a side note this of course should be called memory details page to be in line with memories page that's a tiny thing which also needs to be adjusted in the router index.js file now here but it is something which i want to adjust but that wasn't the main thing instead here in memory overview i now expect to get my data as props and here i expect to get a title i expect to get a image and i expect to get a description we could also just expect one object which has all these fields as properties but to mix it up i'll expect the individual props the individual property values as separate props and then here we combine source of iron image to image bind alt to title and also output title here with interpolation and output the description here with interpolation as well and in the memory detail page component we can now import memory overview so this component we just worked on from components memories memoryoverview.view and then simply register this as a component so add the component's key here and register memory overview and then here instead of a h2 tag i will render memory overview in the vls case so if we found a memory and then simply set title to loadedmemory.title set image to loadedmemory.image and set description to loaded memory.description if we now save that and i fix my error which i introduced if we save that and i go to this page we now have this which looks better i would say now of course the text there that's not looking that great though now to style this in a nicer way this text here we can use a couple of utility classes ionic chips with if you check out the ionic docs here the theming docs or here under layout you do see that they also offer a grid which you could use which we're not using here but you do have a grid which is really powerful but that you also get a bunch of css utilities which are small utility classes which for example can help with text alignment and that's what i want here to the title i'll add a class of iron text center to center this text and i'll do the same here for my description just like that if i now save this this looks much better obviously it's still a simple component but we're getting there step by step and now we get this details page as well now i would say it's time that we can add our own memories as well before we then make sure that we can also add our own memories with our own images which we took ourselves so let's now work on being able to add our own memory and for that we first of all need a new page where we can have that form for adding a new memory so i'll add it and name it the add memory page here in the pages folder and that should not be a folder but a file so add memory page.view is the file name in there as always we got a template and a script and we want to load it through the router there i'll register a new path therefore and that could be memories slash add and then we have a dynamically loaded component where we import from the pages folder the add memory page.view file sidenote because we're using the latest view router we can have slash memories slash add after memories slash dynamic id and it will still find that because behind the scenes it reorders these routes by and matches them in an intelligent way basically in the past with older versions we would have to move that route in front of memory's id because otherwise add would have been treated as an id but now the latest view router is able to differentiate and if we visit slash memories slash add it will load this route might sound like something which should be obvious but in the past this didn't work now it does that's just a side note now this is registered and now we can work on this page of course i want to use my bazel layout here because we need iron page the toolbar and everything and i will add a title here which is or page title actually which is um which could be create or add memory like this and i will have a default what was my name page default backlink my page default back link which here is slash memories so that's my base layout thus far now i also need some content and for the moment i'll just say add a memory here like this and now we need a way of getting there and there are different ways of doing that of course different ways of achieving that but i want to have a plus button here in the toolbar which takes me to that page and therefore here on my memories page which is a list of memory or which holds that list of memories i want to have that plus button in my toolbar the problem is that the toolbar is borrowed here in my base layout the solution could be a slot here i'll add another set of iron buttons like this and then in there have a slot which now has a name so a named slot and i'll give this slot a name of actions end because i'll set the slot here to end so these will be the buttons positioned on the right side or it depends on the platform on which this runs but on the end of the toolbar where wherever that is but on the end of the toolbar i'll have some buttons and they are set here by passing in a slot which has this name now because i have this slot here in the base layout i can go to my memories page and utilize this slot we already do pass the memories list to the default slot now we can also target that named slot for that here we need to add another template tag that's how we need to do that in view and we use the v-slot directive then and target our slot with the name of actions end like this and then between these templates tags we have the content which will go into that slot of this other component and in this case this will be a button with an icon now both are components which are provided by ionic so i'll import them from ionic view and i'll import the iron button and i'll import the iron icon and to set a icon i'll take advantage of another package which is installed automatically which is a dependency of ionic and that's the ionicons package and there from slash icons we can import various icons which we can use nicely looking svg icons and here i'll import the add icon now to find out which icons exist you can visit ionicons.com and here you find a list of all the icons and you can always click on an icon then and you'll get the code on how you could include it and you'll get the name of the icon as well now for view including works a little bit differently there we have to import the icon by its name which we want to use and then we have to add the data property or return it in the setup method if we're using the composition api and basically return our icon as data so here i'll return add which i imported as data in this component and then we can use it later now we can use all of that between my template tags here to add iron button whoops iron button which has the iron icon inside of it and i'll give this iron icon a slot of icon only because it's a button which only has that icon and if we use that slot the icon will be positioned correctly inside of that button and then here i set the icon to a dynamic value so i'm binding it and i'll bind it to add so to that icon which i import here and which i return in my data and that's why i am returning it here so that i can seamlessly use it here in my template i of course also need to register iron button and iron icon here as components in the memories page and then this works if i reload now you see the plus button here the plus icon now of course pressing it doesn't do anything yet and what it should do is that we should go to our details page to our add page here to memories slash add and that's easy to do on our button we can add the router link attribute and point at slash memories slash add and if we do this and reload now this button takes us to this add page simple like that and if i reload on the add page we also have that back button and we can go back because of that page default backlink which i set here so that's great we now got this page we got a button in the toolbar now let's fill this with some live let's add a form here let's add a form where we can add a title a description and for the moment an image link so therefore here i will render a form and in ionic you often do that by creating a iron list with iron items not items which are rendered dynamically with v4 but instead hard-coded items but you get a nice look by doing that you are totally free to set up that list and create that list however you want though you must never forget that it's all just a web app with html css and so on you don't even have to use these ionic components if you don't want that look so you can write any code you want here i however will actually import from ionic view and i will use iron list and i an item here and i will also use iron label and iron input and iron input is a component which will help us with fetching user input i will also import iron text area which you might be guessing it is basically a text area input now let's register all of that here so i enlist iron item iron label iron input and iron text area let's register all of that as local components and then here in base layout we can render our ion list and then our different items and now here i want to have a label for my first input where i say title so the title of the memory and then below that i an input which will be for the actual user input now just like on a regular html input you can set the type here for example to email if you needed that here i'll just use text because i want to get some text we can add required to require this and add this basic built-in validation which the browser offers and so on we can treat this like a regular html input in the end on the ion label i'll add a position and set this to floating and that's one of the special props we can set on iron label if we have a look at it in conjunction with iron input here it's this position and this defines on how the label will be rendered related to the input so if we now repeat that and we add another item here for the image url the type here could indeed be url and we add another item for the description and here i use iron text area and maybe add rows equals five then if i save that all and i go back to this page and reload we see this form here and by setting the proper types here by the way if we would run this on a mobile phone the proper keyboards would be displayed so if you had type email for example that would be a soft keyboard on their mobile device which makes it easy to reach that at symbol that's just a side note so now we got this we also of course need a button to submit this and i also want to have some padding around the form actually and in general this is not really a valid form yet for that we should wrap it with a form of course with a regular form element as we know it from html and then also add another ion item maybe which holds a button to submit the form so for this we can import iron button here and of course register this button as a local component for something like a button you could also argue whether you want to make it a global component because you're going to use it a lot but here i'll stick to a local component because indeed we are loading the add memory page lazily so indeed we do benefit from loading it locally this iron button component it's then only loaded if it's needed so it makes sense and in iron item we can now add the iron button here and say save on the button for example and now we got this button here it looks a bit sad to be honest i'll fix that soon one thing i want to fix right away however is on the form we can add a class with a utility class another ionic utility class that ships with the iron padding class to add some padding around the form like this and now for the button i think it will look better actually if we don't wrap it in an item but instead we move it out of the form and then we can configure this button of course we can for example give it a expand prop again you find all these supported props in the official docs and set this to to full to have this button here to have this look you can also change if it's a filled button or not by adding the fill property and for example setting this to outline and if i now reload it's a outlined button and if it wouldn't be set to full here but to block it would also have borders on all four well borders but i'm happy with the default so with that filled button and hence i'll go with that so now we got a button which will submit the form if we press it we get these different fields and you see the floating labels now let's make sure that when we do press the button we do indeed submit the form and add a new memory now for that to handle this submission i'll first of all grab this entire form here cut it and outsource it into a new component create memory form.view could be a great name for this component put it in there and then add the script tags here and this is not required it's just considered a good practice to split your application into smaller components and then we can take these imports here cut the imports of all these ionic components from add memory page and add them here in the create memory form component and register them as local components in that component therefore and then just use the create memory form component here create memory form inside of that add memory page so here i'll import this component which we just created of course register it locally and then simply render that and that keeps this page component relatively lean which is my goal here with that i got a typo here and if i fix that this loads again now for the form submission and for adding a new memory here in the add memory page that's always where i want to do my data fetching and my my actual work you could say here i want to handle the form submission and as a side note for the moment i'll not implement validation and showing an error message you can do that but it will just be regular view code of course the majority of all of that here is regular view code you could argue but still it's a huge video let's not make it too long i will focus on the form submission and therefore i'll add a method here in my add memory page component and i'll name it save memory and here i expect to get my memory data so the title description and the image url and i in the end wanna store that in my ux store for that we need to go there in the view x store and add a mutation and an action because that is how you do change data in ux hence here we add mutations and actions and the mutation which i'll have here is the add memory mutation and i get access to the state here of course because the mutation needs to mutate the state and i get access to my memory data here as a payload and then the goal is simple i'll create a new memory here on the fly let's create an object let's give it an id and here i'll generate a pseudo unique id by taking the current timestamp and converting it to a string it's not perfect theoretically you could have two memories created at the exact same millisecond but that's unlikely to happen here so it's a good enough dummy id and then i'll set the title to memory data title the image to memory data image url let's say and the description to memory data description and then we can reach out to state memories and maybe unshift it to add it at the beginning as a first memory and add this new memory here in that array and i'll then add a action which is also called add memory which gets this context which actions always do and which also gets the memory data and it's a simple action it would be the place where you now for example reach out to a backend server and store it there but we're not having this functionality here in this application so here all i'm going to do is i'm going to commit my add memory mutation this mutation we just worked on and forward the memory data so therefore it's kind of redundant but again you would be doing asynchronous work or any other kind of work you might want to do in addition to saving that state here in this action if you had other work so therefore now we want to dispatch add memory in the add memory page component when save memory is triggered and we do this by reaching out to this store dispatch and then dispatch add memory and forward our memory data here so again a very simple save memory method which in the end just dispatches this basic action now it should be dispatched when this form is submitted and therefore we can emit a custom event in create memory form so let's go to create memory form and let's add the emits key to make everyone aware of the event we're emitting this is technically not required but recommended as you learn in my course and here i will emit an event which could be named save memory anything like that that could be our event name and in the add memory page we can therefore listen to save memory and trigger the save memory method when that event is emitted so point at the save memory method here and in the create memory component we now have to emit this so here i also add a method submit form could be the method name and in here i now want to collect all the data the user entered pack it all into one object this memory data which i send along with my event and then emit that event so here i wanna in the end emit we could also do extra validation as i said i'm not going to do it here instead i emit my save memory event and i got my memory data package which i want to pack here now for that we need to get access to the values entered here and we could use refs for this or two-way binding and i will go with two-way binding here so i'll add my data method here and manage some data for this component and that would be the entered title which initially is an empty string the entered image url which initially is an empty string and the entered description which also is empty initially and we then pack our memory data here we create this object and set the title equal to entered title the image url equal to entered image url and the description here equal to this entered description and then forward that along with our emitted event now we just need to bind these values here and therefore on these ion inputs we can absolutely use two-way binding even though these are ionic components but they do support it we can use v model there and therefore we can bind the entered title here the entered image url here and on the text area we have our entered description like this okay now we got this this button can be set to type submit to be very clear about the fact that it will submit the form and now we just need to make sure that this submit form method is triggered when the form is submitted and for that on the forum we add a listener to the submit event and we point at submit form here and i will add the prevent modifier to ensure that when it is submitted we don't have the browser default of sending a request automatically but that instead this is prevented and we let just javascript handle this so that should all be working that should add the memory and now in the add memory page we maybe then also want to navigate away once we submitted the form so here in save memory besides dispatching the action i will also use this dollar sign router to programmatically navigate away and we can do this by calling push on the router to go to slash memories or actually call replace because i don't want to be able to go back to the ad form thereafter i just want to go to the memories page without being able to go back to the memories forum because going back makes no sense when it was submitted and replace ensures that we can't go back so if i now save all of that and reload we can enter some data here like hiking pick a nice image url and adding a description click save we go back and we have our memory added here and of course we can also go to the details page then this all works so that's great this works this is how we can add our own data our own memories and with that i already covered a lot of the core features you gotta know when working with ionic and vue you hopefully see that in the end you're building a regular web app and you're using all the view features which you already know like data binding and the options api and the router and ux and this all works just as you know it but then you add in certain ionic components to get this beautiful look and mobile behavior out of the box with the ionic component library here now as a last step i will now also ensure that we don't just have the dummy data and our own custom data like this with our remote urls for images but that we can take our own images and store them on the device that will be the final building block of this introduction to ionic and vue and of course as part of that we'll then also run this not just in the browser as this preview here but as a real mobile app on an emulator and a real device so at this point we got our vue ionic application up and running but you probably came here because you wanted to build a real native mobile app with vue and ionic and up to this point we only have a web app which looks very much like a mobile app especially when we preview it in the browser with that mobile app preview feature but it isn't a mobile app yet it's a web app but we can easily turn it into a mobile app with help of capacitor capacitor is another tool developed by the ionic company so by the same team or the same company which also developed the ionic component library so their components give us the look you could say the look and behavior of a mobile app capacitor now is a tool to really create a mobile app and it does create a mobile app based on a web app by basically giving us a shell you could say it creates a real native mobile app which then internally hosts a web view which hosts our web application so it's our web application running inside of a mobile app but it's still a real mobile app in the end which you distribute through the app stores now of course since it's being wrapped there is a tiny performance loss as you can imagine since there is a wrapper around your web application but on modern devices nowadays this isn't really a problem and it's also not a big performance loss unless you're building a super performance intensive application which you're probably not building with ionic anyways there shouldn't be any problems at all and you just gain a lot by having this easy way of building a real mobile app now you might want to check out my comparison of ionic flutter react native and native script linked below the video to learn more about the main options you have for building mobile apps besides using the official languages and how they compare so capacitor is a tool which wraps a web app any web app even if you're not using the ionic components this is not a prerequisite and here's how we can use it obviously you can visit capacitorjs.com and there you find docs where you can learn more about using capacitor also in non-ionic projects if you do have an ionic project though as we do using it is particularly easy here we even have capacitors set up already we got the capacitor config json file at least but all we got to do here to enable capacitor even if we would have no setup at all is run ionic integrations enable capacitor run this command in your ionic project and this would enable and add capacitor if it wouldn't be enabled already here you see it already is enabled you also find these steps in the official capacitor docs of course if you check how you can use it with ionic now once you did run this command the next command you need to run to really set everything up for capacitor is npx cap init and then an app name of your choice and an app id of your choice and these two values matter because these two values will also later be used when you deploy your app to the app store the app id matters there every app needs a unique id across the entire world and the app name of course is the name users also will see so let's run npx cap init here and pick an app name i will go with view memories here in quotes since i have a white space in there and then an app id and for the app id there is a clear best practice on how to pick a unique app id use a domain which you own or which you could own for example one which includes your company name or your personal name anything which probably is unique around the entire world and then invert it so for example for me i could use com academind because i catamined this my company acadamine.com is our website com acadamine view memories for example and you shouldn't have a dash or anything in here instead use a white space if you want to separate this or just use one word now this did set up this app id here and the app name here in the capacitor config file and now you need to add the specific platforms which you want to support android ios electron is possible as well if you want to build for the desktop but we're going to focus on android and ios here now before we can run the commands for that though you need to make sure that you have your system your operating system your machine configured for android and ios development and for that you can check out capacitorjs.com required dependencies there you learn that you need node we already got that but then for ios you need a mac unfortunately that's a restriction by apple you need a mac because you need xcode there is a way of building ionic apps in the cloud with ionic app flow which is a service offered by the ionic company but this is not a free service and we're also not going to use it here but there would be this service if you want to build your app in the cloud and not install the ios and android dependencies locally but i am going to install them here and therefore you need to install xcode for which you need a mac once you got xcode installed on a mac run this command here inside of the terminal and also run this command inside of the terminal i already did that off screen but you should of course do that to set up everything for ios development now for android you need to install android studio and you can install that on all operating systems so here you are not restricted simply download android studio from developer.android.com and whilst android studio of course is also an ide for building mobile apps here we download it because it also installs all the android sdks which are used by capacitor under the hood to create this wrap wrap and to build this app so simply download and install android studio i'll not do it here because it takes quite some time make sure you install a recent android sdk whilst going through that installer and once you're done with all of that you should have android studio and there for all the android requirements installed again check out the required dependencies page here to see all the instructions in detail and to get all these links and once you did all of that you should be able to run these commands here so here i'll run npx cap add android to add android and i get an error now this is a error which i get because you need to build your app at least once before you can add a platform and with build i simply mean build your web app now here in view ionic's case we can build the app simply by running this build script here in the package.json file or by running ionic build which under the hood will just run that build script so this will now build our app for production and we need to do that in order to then build it as a mobile app as well because your mobile app wraps your production ready app that's why you need to build it once now once the build completed here we can run npx cap at android again and now this works and now it sets up an android project an android app project in this view ionic project folder here it will then set up everything we need and it will give us that android app which is wrapping our ionic our view ionic app it gives us this android folder therefore now we can also run npx cap at ios at least if you're on a mac if you're if you're on windows or linux this unfortunately does not work as i mentioned but here i am on a mac so i can run it and this will now install or set up the ios app and all the dependencies for that now once you did all of that you can run npx cap open and then android or ios to open the respective development tools android studio or xcode with that app so with that app loaded into the tools so that you can run your app through these tools on a real device or on an emulator to preview it so here i'll run npx cap open android and this now opens up android studio with that built android app which is wrapping this view ionic app here it is and we're not opening this to edit the code but really just to run the application to test it and to preview it and here i want to preview it on an emulator now for this we need to wait until this is fully built and initialized you see it here at the bottom of the screen that it's still building this and once it's done building this app so here the android app is being built is being generated you could say once that is done we can also run it on an emulator or on a real device so let's wait for that to finish here we go it's done and now you can go to tools here in android studio and go to the avd manager this allows you to set up a virtual emulator which allows you to run an android phone basically on your computer so that you can preview your app in this emulator in this simulator now i already got a couple of emulators you can click on create to create a new one and then simply pick one of the templates like the pixel 3 let's say click next here and then simply use a stable api version here i'm going to with android 10 here click next and finish and now this sets up such an emulator which we can now launch by clicking on this launch button here and now this launches this emulator on our system it doesn't yet launch the app on it but it launches the emulator already here it is up and running and with that launched we can close the abd manager and now launch our build android app so this wrapped view ionic app which was wrapped by capacitor and which was now built as an android app by android studio on that running emulator by selecting the emulator in this drop down here in this drop down up here and then clicking that run button and this will now launch our app the app we built as a web app which is now turned into a mobile app on that emulator so this will take a couple of seconds but ultimately the app should come up here and should be running on that emulator let's wait for that to happen here it is coming up i will already say it is quite slow on this emulator because the emulator is not the fastest thing ever because it's a mobile phone android phone running on your computer and it's also not optimized for production at all so don't be confused if this is not super fast here now you will see however that this all works as shown and we got our application up and running here we can open up the soft keyboard here we could add a memory and we can navigate around here with all the features we saw in the browser as well but now this is really a mobile app running on a mobile device on an emulator but still it's a mobile app and we could of course now also build this and deploy it to the google play store to distribute it to the world this is how easy it is to build a real mobile app with ionic and vue and it is a web app wrapped by a mobile app of course but no one can tell it's super fast and smooth and it looks and feels like a mobile app it's the best of both worlds you can leverage what you know about web development and about vue and you can build amazing apps in no time because you can use the existing knowledge you don't have to learn a new programming language or a new tech stack and you get real mobile apps which you can push out to the world now we're not done we're going to add the camera capabilities but this is a great step forward of course so now let's work on this form and let's make sure that we can actually take an image with our device camera and for that we will use capacitor because capacitor is this tool which creates a native app by wrapping the web app but it's not just that it's a library which also gives us a ton of plugins that allow us to communicate with the device on which the app is running so for example there are plugins which allow us to access the device camera for this you need to make sure that capacitor is installed and here i do have capacitor core android and ios installed and it was installed when we enabled the capacitor integration earlier and with it installed we can work on this create memory form component there which is the component that manages this memory form and i want to start with the interface currently we have this input for the url but i no longer want to have that instead i now want to have a button to launch the device camera and take an image and then a preview of that image and for that we can of course again use an iron thumbnail here for the preview for this of course we need to import iron thumbnail here from ionic view and register this here whoops iron thumbnail and instead of that iron thumbnail we could use an iron image and we would have to import and register this as well or to keep things simple i'll use a regular image here with some source which i'll set later now that's one thing besides that i also want to have a button so first of all on iron thumbnail i'll add a slot of start so that inside of this iron item this thumbnail is positioned on the left and then next to it side by side to iron thumbnail in the same iron item i'll add a iron button which we already are registering with an icon so with an iron icon which should have a camera symbol and a text of let's say take photo or something like that now to use iron icon we need to import this of course and then also here register it and i need to import the icon which i want to use so we have to add an import from ionicons slash icons and here i will import the camera icon makes sense i guess since we'll have a button that opens the camera and then here we have first of all have to return it in data of course so here i return camera this camera icon which we're importing as you learned it earlier in this video and then on the icon here i'll set the icon to camera and i also want to add a slot here and to find out which slots are supported not just for the button but for any ionic element here we can go to the official docs and then to the slots part and we see that there is a end and i can only slot which we already used before and a start slot and i want to have my icon at the start of the button so i'll assign slot equals start here to position this icon at this specific nicely styled start slot inside of the button and then we have the text in the default slot so to say if we do all of that we go back to our application this is what we get and this doesn't look too bad this is our button here and i will actually change the button look a little bit and i'll change it to fill equals clear again the possible values here are something you can look up in the official docs to have this look here okay now of course we don't have an image yet and we could display some placeholder here whilst we don't have one we could render the image conditionally and show some fallback text whilst we're waiting for it but i want to focus on the camera part so i'll ignore this ugly image for now and instead wire up this button now to wire it up we need a method which should be triggered when this button is clicked let's say a take photo method the name of course is up to you but this method here should be fired whenever this button is pressed so i'll go to this button and add a click listener and make sure that take photo is triggered that we point at this method since this button is inside of a form i'll also add type button here so that this button will not submit the form because of course it shouldn't do that the only button which submits the form is this button at the bottom not this one and therefore now this method will get fired whenever the button is pressed now i want to use the camera functionality and for this we will use capacitor on capacitorjs.com you can go to the plugins area to find all the core plugins which are built into capacitor so all the core native device functionalities which are built into capacitor and there you'll find the camera here you find usage instructions and you for example see that we need to tweak some things when it comes to permissions now let's start with ios here in the ios folder which you only have on a mac because you can't add ios capabilities on windows or linux machines but on a mac you should locate your info plist in this nested app folder here and there you'll have certain key value pairs for example here for the camera usage and so on and you want to make sure that these keys which are specified here ns camera usage photo library these two photo library usage keys here that these keys exist here and that they do have string values these string values basically are the text which will be displayed to your users when they are prompted to provide permissions so when they are prompted whether they want to allow taking that photo or not and therefore you want to make sure that you enter any text here which you want to present to your users i will go with the default text and therefore i don't need to edit anything here but you should make sure that these key value pairs are set now for android you want to go into the android folder and there into the app folder the source folder main and then to the android manifest and there you go a couple of permission users permission elements tags which you can add and remove and by default you should have a lot of tags here when you deploy your application and when you upload it to the app stores you of course want to remove all the permissions which you don't need so that you're not asking for tons of permissions which typically leads users to not install your app especially if the permissions make no sense for the kind of app you are deploying for development it's great that all these permissions are set here because it means we can easily use and play around with any plugin with any capacitor plug-in and any device functionality of our choice in this case we should make sure that these permissions are set read and write external storage and that's the case here therefore we don't need to change anything but you should be aware of that and you should clean up your permissions before you publish your application but therefore we are now ready to go so in the create memory form component here we now want to import certain things from at capacitor core and to be precise here we want to import plugins import plugins from capacitor core and then go down to take photo and we'll use the plugins there or one specific plugin to be precise to be very precise we can actually go up and extract one specific plugin here from plugins by using destructuring and that's the camera plugin so here i'm using object destructuring in javascript to pull out the camera key value pair and store it in a new constant named camera that's the camera plugin to which we now get access through that constant and here in take photo we can now call camera dot get photo just like that it's very simple and this will actually return a promise to you because of course taking a photo is an asynchronous task after all the camera app will open up and the user has to take and confirm a photo and therefore of course we can use async await here to await this operation alternatively we could use then and then catch and so on but here i'll await this and i will get my photo here in the end as a result now get photo takes an object as an argument where we can configure this operation and how we want to take a photo and we got various keys which we can set here and of course the official docs are the best place to learn about all possible values but for example we want to set the result type here and we want to set it to a specific result type based on an object or an enum like object which we also import from capacitor core and that's the camera result type object we also can already import camera source so make sure you add these two imports from capacitor core because we'll need them to configure the camera because now for result type we can access camera result type and then here choose yuri uri like this this basically means that the photo will be stored in a temporary location on the device and you get a url a pointer at that location a path to that location in the result in addition we can set the source and we want to set that to camera source and then here you can choose whether it should be the photos app which is opened so that users can pick an existing photo or if you want to really open up the camera and that's what i want to do here and then for example we can also set the quality to a value between 0 and 100 and i'll go with 60 quality here to make sure that the image isn't too big now there are way more settings which you can set again definitely check out the official docs for that so this will now take a photo and give it to us here in this constant and now of course we don't just want to have the photo for the moment we at least want to preview it here in this thumbnail in this image and that's not too difficult because this photo which we get here is actually an object which will hold the path to that taken photo and we can use that path to then preview it it will already be a path which works with the image element that some convenience capacitor gives us so therefore we can simply add a piece of data here preview image url and initially that's an empty string for example or null but then here once we took the photo we simply set this preview image url equal to photo and then there is a web path field and that's this path to the image on the device which can be used in an image tag to preview or to display that image and that should already be all if we now save that that should work now here i'll reload open up the console to see any errors and click take photo and it now fails here in the browser it then opens the image picker instead simply it fails here because we needed to install an extra package or some extra elements to make that work and it gives us a link where we can learn more about that this pwa elements document here and there you also learn how you could install that this basically adds some extra web components which are needed to display a nice looking take a image in the browser model to this web application really useful but not what i want to focus on here so i'll ignore that here and just live with that image picker fallback instead we will test this on a real device or at least on the android emulator and to test this i'll stop this development server and then build the app again and again ship it to the real device to the emulator now to preview this or to test this on our emulator we first of all will run ionic build again to rebuild this application because we always need that production ready build of our web application first and once it was rebuilt we'll again basically tell capacitor to wrap its native app around this rebuild updated web app and then we can launch that through the emulators and so on so through android studio on an emulator or on a real device and i'll simply do that by running npx cap copy thereafter so this will now take the build application and again copy it into the native app folders so into the android and ios folders and wrap it with these native apps and then again we can run npx cap open android in this case to open up android studio with this updated native app loaded in there so now it's loading this again and it's then building this again and thereafter we can launch this on an emulator again so let's wait for this build step here in android studio to finish and then i'll again run this on my pixel free emulator on which we tested this before so this is the emulator starting up now the build of the updated app started and here's the updated app starting up and if i now click the plus here and i click take photo i'm asked whether i want to grant this access which i do and now the camera app will open up and the first time it opens i get this um this little introduction here on the emulator and i can take my photo and i have to go back but that's just the first time because that's just the emulator thing where it tells me how to use the camera now if i take this again i can take this dummy image in this emulator camera simulator confirm this image and it's taken it's just not showing up here which it of course should so let's find out why this is not working and of course the reason for this not showing up is very trivial i'm not binding my image source i should do that i should bind my image source to this preview image url because otherwise updating this piece of data isn't worth a lot so make sure that you bind your image source to this preview image url which we're updating and once you did that we can try this again now it might be cumbersome to always rebuild this theoretically there is a live updating mode which you can learn more about in the ionic docs so where the app on the emulator is live updated but it never did work for me really well so well here we are i'm just rebuilding this and i typically just test it in the browser anyways and then it's just sometimes for these native device capabilities which i don't need to test all the time though so it's not really a big problem so now i'll again run npx cap copy to copy this over don't need to run the open command again because android studio is still open and i will now relaunch the app here rebuild it and restart the updated app on the emulator therefore so let's wait for this build process to finish and for the app to launch again here and it did restart here for me and now let's try this again let's take a photo here and this looks better now we got the preview here as well now if i enter the rest of the data here and save this the image is not showing up here because currently we're not using that taken image we're just displaying this preview but we're not storing it when the save button is pressed but that's of course the next thing we can do we can make sure that this photo does show up here as well and of course that's not too hard previously we collected the entered image url and we passed this along with our memory data well now it's this preview image url which we need in the end and therefore i'm not too happy with that name maybe we should get rid of the entered image url and rename this to chosen image url or taken image url and of course also update this down here now and take photo and also bind this here in our preview and then simply forward that when submit form is called so that image url is set equal to this taken image url and with that the image will not just be used to preview it here but the url is also passed along with the image data into our vuex store now that's all great but still this is not ideal because at this point of time we're always passing around this display ready url we get here from this photo object here this web path value this works but it's only stored in a temporary location we can't rely on this image to live on and to ensure that it survives not just now but also in the future we might want to consider storing it in the file system of our device now this is something we can cover in a future video if you want to definitely let me know and below the video i will also provide a link to resources where you learn how you could do that how you could use the file system capacitor plug-in to store the image permanently but for this video i'll stop here because we can always continue working on this we can always add more but you now did learn and did see how you can build an ionic view application you learned what ionic is that it's a bunch of ui components and how you can leverage your view knowledge to build a web app and then based on that with help of capacitor a real mobile app with ionic and capacitor and view and you saw how the view router fits in how ux fits in how you still use what you learned about vue about methods and building templates and components that all of that still applies but how you can mix in these ionic components and the capacitor plugins to build real native mobile apps if you want to learn more definitely let me know of course definitely comment below the video let me know if you want to learn more what you like what you build of course also and check out the official docs also to learn more about that and to build any mobile app you want with ionic and vue because these are two real amazing technologies and working with them is a lot of fun as you hopefully also saw in this video
Info
Channel: Academind
Views: 98,783
Rating: undefined out of 5
Keywords: ionic, capacitor, vue, vuejs, vue.js, ionic vue, vue ionic, complete app, tutorial, full app, course, ionic vue tutorial, vue ionic tutorial, maximilian schwarzmueller, maximilian schwarzmuller, maximilian schwarzmรผller
Id: mQ4zmFy4d7Y
Channel Id: undefined
Length: 134min 52sec (8092 seconds)
Published: Thu Dec 03 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.