Browserify Cannot Read Property 'prototype' of Undefined

Y'all're browsing the documentation for v2.x and earlier. For v3.x, click here.

Adding Example Properties

Base Example

There may be data/utilities you'd like to use in many components, simply yous don't want to pollute the global scope. In these cases, y'all can make them bachelor to each Vue instance by defining them on the prototype:

          Vue.prototype.$appName =            'My App'                  

Now $appName is available on all Vue instances, even earlier cosmos. If nosotros run:

                      new            Vue({            beforeCreate:                          function()            {            console.log(this.$appName)   } })        

Then "My App" will be logged to the console!

The Importance of Scoping Case Properties

You may exist wondering:

"Why does appName kickoff with $? Is that important? What does it do?

No magic is happening hither. $ is a convention Vue uses for properties that are bachelor to all instances. This avoids conflicts with any defined information, computed properties, or methods.

"Conflicts? What do you hateful?"

Another not bad question! If you set:

          Vue.prototype.appName =            'My App'                  

Then what would you wait to exist logged below?

                      new            Vue({            information: {            // Uh oh - appName is *too* the name of the            // instance property we defined!            appName:            'The name of some other app'            },            beforeCreate:                          function()            {            console.log(this.appName)   },            created:                          role()            {            console.log(this.appName)   } })        

It would exist "My App", and so "The name of another app", considering this.appName is overwritten (sort of) by data when the example is created. We telescopic instance backdrop with $ to avoid this. You tin fifty-fifty use your own convention if y'all'd like, such as $_appName or ΩappName, to prevent even conflicts with plugins or future features.

Real-World Case: Replacing Vue Resources with Axios

Let's say you're replacing the now-retired Vue Resource. You really enjoyed accessing request methods through this.$http and you want to do the same thing with Axios instead.

All y'all accept to do is include axios in your projection:

                      <script              src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.15.2/axios.js">            </script>            <div              id="app">            <ul>            <li              v-for="user in users">{{ user.name }}</li>            </ul>            </div>                  

Alias axios to Vue.epitome.$http:

          Vue.paradigm.$http = axios        

So you'll be able to use methods like this.$http.get in any Vue instance:

                      new            Vue({            el:            '#app',            data: {            users: []   },   created() {            var            vm =            this            this.$http       .get('https://jsonplaceholder.typicode.com/users')       .so(              function(response)            {         vm.users = response.data       })   } })        

The Context of Prototype Methods

In case yous're not aware, methods added to a prototype in JavaScript gain the context of the case. That means they can use this to admission information, computed properties, methods, or anything else defined on the example.

Let'due south have advantage of this in a $reverseText method:

          Vue.paradigm.$reverseText =                          function(propertyName)            {            this[propertyName] =            this[propertyName]     .dissever('')     .opposite()     .join('') }            new            Vue({            data: {            message:            'Howdy'            },            created:                          office()            {            console.log(this.message)            // => "Hello"            this.$reverseText('bulletin')            panel.log(this.message)            // => "olleH"            } })        

Note that the context bounden will not work if yous use an ES6/2015 pointer function, equally they implicitly bind to their parent scope. That means the arrow function version:

          Vue.prototype.$reverseText =                          propertyName              =>            {            this[propertyName] =            this[propertyName]     .carve up('')     .reverse()     .join('') }        

Would throw an error:

          Uncaught TypeError: Cannot read holding 'dissever' of undefined        

When To Avoid This Pattern

Equally long as you're vigilant in scoping epitome properties, using this design is quite safety - as in, unlikely to produce bugs.

However, information technology can sometimes crusade confusion with other developers. They might see this.$http, for example, and think, "Oh, I didn't know about this Vue feature!" Then they move to a different project and are dislocated when this.$http is undefined. Or, maybe they want to Google how to exercise something, simply tin can't discover results because they don't realize they're actually using Axios under an alias.

The convenience comes at the cost of explicitness. When looking at a component, information technology'southward impossible to tell where $http came from. Vue itself? A plugin? A coworker?

And so what are the alternatives?

Culling Patterns

When Not Using a Module Arrangement

In applications with no module system (e.g. via Webpack or Browserify), at that place's a pattern that's oft used with any JavaScript-enhanced frontend: a global App object.

If what yous want to add together has nada to do with Vue specifically, this may be a good alternative to reach for. Hither'due south an example:

                      var            App =            Object.freeze({            proper name:            'My App',            version:            '2.1.iv',            helpers: {            // This is a purely functional version of            // the $reverseText method we saw earlier            reverseText:                          function(text)            {            render            text         .split('')         .reverse()         .join('')     }   } })        

If you raised an eyebrow at Object.freeze, what it does is forestall the object from being changed in the time to come. This essentially makes all its properties constants, protecting you from future land bugs.

Now the source of these shared properties is more obvious: at that place's an App object defined somewhere in the app. To find it, developers tin can run a project-broad search.

Another advantage is that App can now be used anywhere in your code, whether it'due south Vue-related or not. That includes attaching values directly to instance options, rather than having to enter a office to admission backdrop on this:

                      new            Vue({            data: {            appVersion: App.version   },            methods: {            reverseText: App.helpers.reverseText   } })        

When Using a Module System

When yous have access to a module system, yous can easily organize shared lawmaking into modules, then require/import those modules wherever they're needed. This is the epitome of explicitness, because in each file you proceeds a list of dependencies. Y'all know exactly where each one came from.

While certainly more verbose, this approach is definitely the most maintainable, especially when working with other developers and/or building a large app.

doderyrunduarsted.blogspot.com

Source: https://v2.vuejs.org/v2/cookbook/adding-instance-properties.html

0 Response to "Browserify Cannot Read Property 'prototype' of Undefined"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel