Browserify Cannot Read Property 'prototype' of Undefined
- Learn
-
Documentation
-
- Guide
- API
- Way Guide
- Examples
- Cookbook
-
Video Courses
-
- Vue Mastery
- Vue School
-
- Ecosystem
-
Help
-
- Forum
- Chat
- Meetups
-
Tooling
-
- Devtools
- Vue CLI
- Vue Loader
-
Core Libraries
-
- Vue Router
- Vuex
- Vue Server Renderer
-
News
-
- Weekly News
- Roadmap
- Events
- Blog
- Jobs
- DEV Customs
-
- Team
- Resource
- Partners
- Themes
- Crawly Vue
- Browse packages for Vue
- Back up Vue
- One-fourth dimension Donations
- Recurring Pledges
- T-Shirt Shop
- Translations
- 中文
- 日本語
- Русский
- 한국어
- Português
- Français
- Tiếng Việt
- Español
- Bahasa Indonesia
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