7 Secret Patterns Vue Consultants Don’t Want You to Know

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
beautiful okay so welcome to the seven secret patterns view consultants don't want you to know I am I am testing out a lot of these patterns and part of it is I want to know a little bit more about the audience so I know how much detail I'm going to go into for some of these examples so raise your hand way up high if you've been building view apps before if you have prior experience building view apps raise your hand up high if you've heard of you never used it quite a few people okay I'm sorry to say for those of you who have never used view before unfortunately some of this may be a little bit over your head but I will try to I hopefully that the previous talk answered some of those questions and you'll be able to use a lot of these tips as soon as you start building view apps and you'll be able to tell your view using friends how you know more about you than they do which will be a lot of fun okay so first I want to talk a little bit about me that's me right there this is that the first view comps in Poland that's me right next to Evan who's actually wearing my shirt because he forgot his view shirt amazingly and I am the only person as you can see looking at the wrong camera at the water those looking in a completely different direction I don't know what he's looking at but I think I think this is a lot about me everyone knew what camera to look at except for me somehow and don't know how that happened and I work on the view core Docs I work on a lot of tooling for developers in the view community such as the the migration helper I've developed the parts of the EOS lint plug-in and I also do a lot of consulting work helping companies all around the world build mostly these days view applications because when people contact me it's usually because of you and from this I've taken a lot of a lot of experiences where I tell someone a trick like something small that they can do in their view apps and they think like oh wow like I wish I knew this all along I wish I you know this said this had been more clear to me before and sometimes it's not clear because we add new things to the docs all the time and we're also constantly updating them to make them more clear and adding new resources we're also developing a cookbook where we hope to reveal some of these patterns and I also have a separate project where I've documented a lot of these patterns and other patterns that I don't have time to talk about today but I will talk to you about the the project later if you're interested and I've divided these secrets into three general categories productivity boosts radical tweaks and unlocked possibilities trying to stay with a clickbait theme and I want you to know even though there's gonna be a lot of code here you don't have to take notes I all of these slides will be available afterwards I'm gonna show you a link and I'm also going to show you some code that's part of larger demos and that code will also be available at that link that you can check out later so productivity boost number one smarter Watchers how many people raise your hand if you've used a pattern like this and actually for those of you who haven't used view before you can raise your hand if you've used a pattern like this in another framework where as soon as the component is created you're doing something for example maybe fetching a user list from an API and then also whenever some kind of data changes like search text you're recalling that method to fetch new data from the API for example if that data that search text is attached to maybe an input where as users type you want to filter the users and then make a new search and show them a new list of users like if they search for John show them the users that are called John so raise your hand high if you've used a pattern like that in your app so quite a few people this this kind of code looks familiar so I'm gonna show you a few optimizations that you can make to improve this code a little bit and the first one is that Watchers can actually take a string as a value instead of a function and that string is just the name of the one method that you want to call whenever that happens a lot of people don't know that it's something that's easy to miss it's a skip over in the docs and there was once upon a time when we didn't document it as clearly which has now been fixed the other optimization I want to talk to you about is immediate true so I'm gonna rewind you see we the value of search text the search text watcher is a string now it's an object and the handler is either the function or the string that has the name of the method that we want to call an immediate true means we don't need the created hook anymore because the handler will be called as soon as the component is ready it'll be called immediately so this can not only make your code a little bit cleaner but in case you decide to do a greater variety of things uncreated and also when that method is watched by consolidating at all in the watcher you can also reduce the surface area for bugs in your application so that's the first the first tip the first of seven productivity boost number two component registration so how many people have seen a pattern something like this in your apps where there are a lot of like base components I gotta have you raise your hands in a second - dorri dorri I'm going to describe the pattern first and then we're gonna do a raise hands so you have a bunch of base components that sometimes maybe just wrap like another element in order to apply some some styles to them that are specific to your app so you're importing face button bass icon bass input and then you're registering all of them all for sometimes less template code then there is JavaScript code just to make that possible so now erase your hands how many people have had a deal with something like that before it feels like it feels kind of frustrating doesn't it feels like how do all this worry just just to get this little bit of code I'm using the the button in like every single component why don't have to import it always I'm going to show you a solution this will look like a lot of code at first but I'm going to walk through it slowly so the require context down I I know I was told a stay near the podium do you mind if I okay I'm gonna jump up right here require context that's something specific to web pack that you can use when you want to require a whole groups of a whole group of components programmatically so here you can see we're requiring all of the components in the current directory that matched the pattern base - and end with dot view so all the dot view components that start with base - and base is a common prefix that I like to use in applications for components that I'm using everywhere and they often just wrap an element and they often have the name of the element in the name like base input base button and then we're going through all of the components that match that pattern we're getting the component config and then we're getting a pass pascal case version of that component and then we're registering it right there at the bottom with view dot component and this is a global registration so that means it'll be available everywhere in your app and in order to use this you can drop this code just in your in your main dot j s or entry file for your application but i often like to keep it in a component slash underscore Global's is and then in my main dot J's file or entry file I'll import components slash Global's so that all of these global components are registered before my new view instance and don't worry you don't have to take pictures you don't take pictures Lee there's gonna be slides slides later so you can if you want I guess you don't like live-tweeted but maybe this isn't the most exciting live-tweeting and i want to talk to you about one more one more pattern here that you might be interested in that's actually not really so much of you thing but more of a web pack thing that a lot of people don't know so down here we have component that default or component config so how many people already know like oh yeah I know why he's doing that raise your hands it's like one person two like two people who are like really into web pack like maybe unhealthily into web pack like me so if you in your dot view component if you export default that means your component options will be under component config dot default it'll be under the default option on the exported module if you are importing like if you import something from something else using the es6 syntax then that automatically will look for a default when you're using require though it doesn't so we have to specify that we want the default or if you've never export defaulted in your view component like let's say you're using module exports equals for the common JSON tax then your component options will be under component config also if you are if you just have like a template and maybe some styles and you don't even have a script tag then you are component config will also be under component config instead of dot default so little little webpack thing can trip people up a lot of times they're not sure like why is it doing it why is it a default sometimes why is it not a default sometimes and I have been one of those people and now I know and I want you did not first be frustrated with that too okay so now using that pattern we can take all this javascript that was needed to support this pretty simple template and get rid of it we never need it we only have to import components when we actually need them now you may be wondering like wow this seems like why don't we just like import everything globally like register all components globally and and you could do that but I wouldn't recommend it for this reason for more niche components like let's say you have a navbar in your application and you decide to stop using that navbar or maybe you're not using that navbar for all users or with webpack you want to split it out into a separate module so that it's it's only fetched from your server when you actually need it to reduce the size of bundles if you decide to do something like that but you're registering all of your components globally then all of your components are guaranteed to be in your bundle even if they're not being used and even if you have specified that you'd like to split them out into a separate a separate bundle so your bundles can get really big and it can get difficult to maintain over time but your base components are being used everywhere productivity boost number three module registration so this is a little bit similar to the previous one I want to get a quick quick hands for people who have used view X before okay and keep your hands up if you've used view X modules okay so view X modules are little pieces for those who don't know little pieces of state management that you can bring into your application so like let's say you might have an off module to handle authentication in your app and keep keep track of like whether a user is signed in and things like that you might have a post module to keep track of all the posts that you know you're keeping track of in your application that you maybe you've fetched from the server and are displaying to the user same thing for comments for those posts so these are just discrete pieces of application state and this pattern isn't unique to view acts if you're using you know some other kind of library like redux with view or if you're using a completely different framework but are using webpack you can still use a pattern like this in your apps so whenever you whenever you create a new module whenever you have a new kind of thing that you want to keep track of the state for like let's say we also have us you know post stars or you know maybe users can star all sorts of things you know so we we're keeping track of all the things that users have starred in the application we might have a separate module for that and when we add that module we'll have to add okay I import stars from module stars and then also add stars to the modules here it's a little bit more setup that you have to do every time and eventually your store file here can get really big and busy it's tedious but there's a solution this might look familiar from what we previously just did with component registration so we are requiring all the different modules I usually keep this in an index J's file inside of modules by the way all of the J's files inside of the current folder and then we're going through each of those files and if the file name is indexed to J yes basically if the index touch es file is looking at itself just like bail don't do anything with it because it's the one thing in that folder that won't be a module and then we're getting the module name by camel casing the file name and then we're adding it to a modules hash our modules object sorry I talked I was giving a ruby talk earlier not exactly a talk but sort of a consultant thing and then we were requiring the module by its file name and then we export all those modules and there's one other optimization that I want to show you that I often like to do here if you like named based modules or if you want to set some other kind of default option for all of your modules you can do that here by saying like namespace to true which is false by default for few X modules and then add in the rest of the the module options there that's really great for managing its really great for mentioning like best practices in your apps like if you've decided on your team like we want all of our modules we namespace unless there's a very good reason for them not to be named spaced that's a great way to code it in so that no one can accidentally leave that out like they have to explicitly say names based false so now our modules are our store file is much simpler we can just import modules from modules and an export neat default new view X door modules much better so those were all the productivity boosts now I'm gonna tell you about some radical tweaks radical tweak number one so these are these are tweaks that are like tiny changes that have a big impact cleaner views so how many people again I want to I want to get a sense for how many people have used view router okay for those who haven't used view router it's a companion library for view that helps you manage pages with or sorry helps you manage applications with multiple pages so let's say you have you know a forward slash it is just like your home page and forward slash about as soon as you need that forward slash about if you're using a quote-unquote single page application which is like what everybody in industry calls it but it's kind of a bad name because usually single page applications have more than one page it's just like one one HTML file so this helps you have more than one page despite that one HTML file that you're serving to all your clients so this is a lot of setup where in our data we're setting some defaults and then every time the route changes notice we're watching it with our old watcher trick or smarter watcher trick so this is a combo trick we have to reset the data to its initial value just in case the previous route was using the same component as this route so let's say for example you're going from forward slash posts forward slash one one being just like the ID of the post and then you're going from that route to forward slash posts forward slash to what view will do is it'll see like okay both of these routes use the same component so instead of you know starting it up from scratch I'm gonna be a little bit smart and render the minimal possible you know make the minimal possible changes and I'm not even gonna start like a new host component I'm just going to give it different data which can lead to some edge cases which we have to deal with with this code and sometimes it really be nice if you could simplify to something like this so as you can see we've gotten rid of all of our reset data gotten rid of our watcher now we're just getting the post uncreated and we have our get post method still and we have our data that we only have to initialize once which is ideal the way to do that is with one line by adding a key to router view and specifically a key I often like to add is route full path and that just tells view that if the full path changes even if the component is the same you should render it from scratch so what that means is you might have or you will have slightly worse performance from route to route but your view components or route components will be a lot simpler and probably less likely to have bugs in them I've seen a lot of people get frustrated from like oh yeah I guess we can have like multiple posts and then they they never test that until they actually you know go from one post to another they actually add a link from a post page like a next post and then there are wondering like what's going on like it's still showing the old post and they get really frustrated and this just makes all of your routes a little bit more predictable and they behave a little bit more like views that you're used to in a lot of other like back-end frameworks especially if you're coming from a back-end so I think it's more than worth the sacrifice of slightly slower performance on route changes for most applications radical tweak number two transparent wrappers so we are looking at some like base input base button components before here's what are the template for our base input might look like it just has an input and then we're assigning the value as the value value being passed down as a prop and then every time there's an input for those who aren't familiar we were looking at V on earlier in the first talked at is an alias for V on and the colon is an alias for V bind so whenever there's an input event basically whenever you user type something in it emits the input event to the parent so this can work with V model which we also saw earlier in the first talked and you might also have some Styles here too and then when you're using this component it's very common that you might want to listen for some other kind of event that you haven't explicitly specified in your component so let's say every time the component gains focus you want to do something and you have to add this dot native modifier because otherwise this will listen the @ focus will listen for a focus event emitted from the component similar to what we're doing with input here and the dot native says no we want to listen to an event that's on the the root element of the component and the root element of this component happens to be input there's a problem what happens when we add this what happens when we refactor our base input component in a little bit now it's wrapped in a label and now the root element of that component is a label so our focus dot native listens for a focus event on the label instead of the input and so then you're focusing on the input and wondering like why is why isn't this working anymore I just wanted to I just wanted to listen for a focus event on the input it's a base input event and this is my solution I like to create a listeners computed property that returns an object with all the properties from listeners this dot listeners stores all of all of the listeners from the parent component and then will override input so that again it still works with fee model and then we're going to use the V on object syntax you can use V on without any kind of event specified pass it in object and it will listen for all of the the listeners specified in that object which means for our base input we no longer have to do focus native we can basically treat it as an actual input component and just use focus unfocused do something and it'll just work and it's future proof when we're using this base input component we no longer have to know about like oh how is it structured internally like what's the root element this will just always work so I usually recommend building base components like this from the start but we're not quite done yet there's an additional problem what happens when we add this placeholder here it'll add a placeholder to the label because by default view passes any and not attributes any attributes not specified as a prop to the root element of the component in this case the label and a placeholder on a label I you know I actually haven't tried it but I would assume it does nothing I would assume it would just make my app not work when really I want to pass I want to pass anything here directly to the input because I want it I want to act like I'm just interacting with an input and there's an option here to that's relatively new to view if you learned a few awhile ago and you haven't completely reread the docs like every week since then you might have missed out in some things inherit actors false this is an option that you can add to your view component config that tells view that you don't want this component to just automatically inherit attributes to the root element of the component instead we're going to explicitly define how these attributes are handled with V bind actors V bind also takes an object syntax and actors is an object that contains all of the attributes all of the attributes that aren't defined as props in this component but passed to it right here and I've seen a lot of UI component libraries were before this was available or maybe they didn't know this was available they just had a huge huge component file for like every possible attribute that you could add including like custom like data attributes from some third-party plug-in that they want to use with few like you know if they they want to use like some like jQuery date picker or something like that and it requires like you know data a pic or something like that and so this component can sometimes become like hundreds of lines long just with these huge lists of attributes that we want to make sure are passed to this input component and this gets rid of all of that you never have to worry about whether the attribute will be handled correctly so now we really have fully transparent wrapper components this is this is actually one of my favorite tips once I was able to do this like I I think there might have been a tear there might have been a small tear so we've gone through the productivity boost we've gone through the radical tweaks now we're on to unlocked possibilities so these are things that you might not even known you could do with view number one single root components so here's an error that I've seen a lot where view tells me oh you need exactly one root element how many people have seen this before raise your hand up high yeah I know this I know this I wrote the doc that warns people about this and it still happens to be sometimes like I all right yeah I'll just like I'll wrap it in a div and then I'll make you happy unfortunately that doesn't always work sometimes you want a pattern that really requires returning more than one component like in this hypothetical actually not that hypothetical because this is an actual component I built navbar component that renders you know some persistent nav roads these are some you know navigation routes that are always there you know if there are some some routes I only want to show if you're logged in and some routes I only want to show if you're logged out there probably aren't a lot of applications that have like sign-in and sign-out that don't require like something like this right this is a pretty common use case but there's a problem here this component this navbar component has a single root element the UL but our navbar routes might be problematic because when we try to do something like this it looks like oh yeah we only have one root element like Li we only have one Li it's just repeated with V for a bunch of times so we're trying to return an array of elements and fuse not gonna be very happy with us we've actually created an error here how do you both run into that yeah me too me too I still I still dream sometimes well there's a solution a lot of people don't know this but functional components that user render function can actually return in array of elements so here we're rendering over or we're mapping over all of our routes and then we're returning an ally with a router link which is a view router specific component and that will actually work multiple components I was really really happy when I was able to do this too it opened up like a whole new a whole new arena for patterns the only downside that I found is if you if you are using components like this like all over your app that means all the developers on your team probably have to know how to write render functions which is maybe not something you might want if you have a lot of juniors on the team or if you have a just a really big team with a lot of diverse skills so in those cases that might be worth trying to refactor to use something that's not quite as nice of a pattern but still allows you to have one one root at each component I'm curious about this how many people hmm I don't want to include the people who haven't used view yet you probably didn't know about this trick but for the people who have used view raise your hand if you didn't know about this trick that render functions could actually return multiple it's okay so quite a few I'll be asking at the end to see how many people didn't learn anything and I will find you and I will teach you something unlocked possibility number two rendering non HTML so this is a little map that I built with a library called matte box GL which is a really really cool mapping library that I highly recommend these are all the different cities that I've lived as you might see you can zoom in zoom out you can hover over cities and get a little tooltip there's also a little navigation down here and matte box GL as you might have guessed from the name doesn't render HTML but it actually renders WebGL and that's how we get these like really nice slick performant Maps and WebGL code or matte box GL code tends to look like this you know you have a map unload you had a source at layers add events now the only issue is this isn't really like the declarative view code that you may have grown to love this is you know we're back to just declarative code and I've seen I've seen integrations like this where you basically just have a component that's like oh yeah I'm created just do all this stuff and it renders the whole map and and that component isn't really reusable because if you want to have a different map that's like slightly different then it's still like one big file and what do you do do you like copy that over and then just like change the one thing like oh we want to like different colors we really want an API it's more like this like we want to feel like we're using HTML so maybe a map box map and inside of the map you're gonna have matte box markers for all those little like pins that we had in the map and I'm defining a template here for what shows up when you hover over that map in here matte box GL actually allows us to use some excuse me to use some HTML so we can pass it some HTML in this template and then we have a matte box navigation component to make the the navigation show up and the way that I like to do that is usually with um this is the only time up like in this kind of situation is the only time that I'll say yeah might be okay to use this stop parent everywhere else in the docs and everywhere else in real life I'll tell you know please don't use this stop parent like it's for you know it very specific situations and this is one of those very specific situations where inside of our map box marker components and map Box navigation components it might actually be okay to reach into the parent and get the map because those are very tightly coupled components you're probably not going to have a map box marker component that's not inside of a map and if you want a little bit of a different strategy so if you have deeply nested deeply nested components inside of the map box like if it gets really complicated you might want to look into the provide inject interface which is also relatively new if you've been using view for a while I'm not going to talk a lot about that but you can check it out of the docs just put that away provide injector you can that's that's the one case where you can write a little note because that won't be anywhere and then I'm created we do some initialization before destroy we do some cleanup and you can also with some Watchers you know update your data source when you know the the markers that are passed to maybe this matte box markers components or the items that are passed that's what the prop is called pass to the matte box markers component Changez then you can watch that and then instead of a template we have a render function that just returns null you can actually do that you can return null it'll just like okay well I won't render anything I try I'll trust you you got this so these are really more abstract components that allow us to take this this imperative code these like lists of instructions and sort of morph it into a more declarative interface that is reusable across your app and I want to pay special attention to the the template slot scope city here so you can actually pass if you haven't used scope slots before you can pass a template to a child that uses data that only the child has so for each city you know the child is going to pass this part of the template the city and then we're gonna render the city name and an h3 and I want to show you how we're actually doing that in in MapBox GL so here we have our scope slot and we're passing marker dot properties to it this creates some V nodes virtual nodes these are like blueprints for HTML and then we're creating a new view instance to render the pop-up content nodes get the inner HTML and then set that pop of HTML so now we've turned view into sort of like a generic template system you know sort of like pug or you know handlebars or something like that ej s embedded javascript in HTML files where you can you can pass it some data and use it outside of you know the Dom that view is controlling if you can't get enough that was my last tip if you can't get enough I recommend checking out github.com slash crispy Fred / view Enterprise boilerplate this is a Reis release project that has a lot of these patterns in it with like described in detail in the source code including more examples for like how to handle authentication and apps and all sorts of things I highly highly recommend it and I also have an announcement just today this is the first time announcing it I just heard of the patreon ah small plug I apologise patreon.com slash chris view Fritz I just started this today you're the first people in the world who know about it because right now I use like 20 percent view time and I have 80 percent consulting time now I want to flip it so I can make your lives even easier right more Docs more tooling stuff like that and that's it that's the end of the plug now we can do some questions for just like a couple minutes we might have time for one question you can find these slides and other source code at seven secret patterns I'm at crispy frits everywhere github twitter I think it's it actually but if I if I do join another network that's who I'll be repeat question for audience what does it mean again repeat question for audience oh god I got yeah yeah yeah I know that deal okay cool cool cool cool any questions yes that's right here yeah you'll find a link to it yeah you'll find a link to it yeah sorry the question was do you have the map box thank you I know seriously she just told me and then we clarified it okay yeah so thank you thank you ah where can you find the map box project yes you can if you follow that link it's in the readme there'll be a link to it in the readme and it's not actually like open-source it's sort of just like a little demo because I took it out of another app and it's not really me it's not really built for consumption for like other people yet but you can do that if you want to and you have more time than me go ahead - number one most avoidable mistake well I'd say if mostly if so many people are making it it's obviously not the most avoidable so I'm not exactly sure how to answer that question gosh I do see I do see a lot of people reach for like this not parent or interact with the Dom manually you know the win there when they're not used to you know having view mostly handle that stuff for them yeah it's hard to say depending on their past experience you'll get a lot of different kinds of mistakes any other questions yeah go ahead most common anti-pattern that I've seen let's see gosh uh there are some that I'm torn because there are some that I really don't like and there are some that I've seen more unfortunately I think we've done a good enough job in documentation that the ones I really don't like I tend not to see very often but I I don't see this very often anymore cuz I've like plastered notices about it everywhere but if when people are using something like an event bus instead of view acts or some kind of more robust state management solution that can be frustrating I have zero minutes left so if you have another question oh I can do one more all right go ahead do I find myself splitting up computed properties into getting and setting a lot no I find myself doing it sometimes but not frequently yeah but some other people like Guillaume from the view core team he uses it more than me and I think the way that he uses it like is cool and good it's just there are often equally good patterns that you could reach for and that's one that I reached for a little bit I don't know average okay and I think that was the last question I have time for but I will be here all day so you're free to like ask me a question during a break or just tell me about like what you're building stuff like that let me hear from you ciao you [Applause]
Info
Channel: Coding Tech
Views: 148,703
Rating: 4.8998017 out of 5
Keywords: vue.js, vuejs, javascript, vue framework, vue patterns
Id: 7YZ5DwlLSt8
Channel Id: undefined
Length: 44min 15sec (2655 seconds)
Published: Sun Apr 29 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.