You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There may be data/utilities you'd like to use in many components, but you don't want to [pollute the global scope](https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20%26%20closures/ch3.md). In these cases, you can make them available to each Vue instance by defining them on the prototype:
> "Why does `appName`start with `$`? Is that important? What does it do?
31
+
> “为什么 `appName`要以 `$` 开头?这很重要吗?它会怎样?”
32
32
33
-
No magic is happening here. `$`is a convention Vue uses for properties that are available to all instances. This avoids conflicts with any defined data, computed properties, or methods.
It would be `"The name of some other app"`, then `"My App"`, because `this.appName`is overwritten ([sort of](https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch5.md)) by `data` when the instance is created. We scope instance properties with `$`to avoid this. You can even use your own convention if you'd like, such as `$_appName`or`ΩappName`, to prevent even conflicts with plugins or future features.
60
+
日志中会先出现 `"The name of some other app"`,然后出现 `"My App"`,因为 `this.appName`在实例被创建之后被 `data`[覆写了](https://github.com/getify/You-Dont-Know-JS/blob/master/this%20%26%20object%20prototypes/ch5.md)。我们通过 `$`为实例属性设置作用域来避免这种事情发生。你还可以根据你的喜好使用自己的约定,诸如 `$_appName`或`ΩappName`,来避免和插件或未来的插件相冲突。
62
61
63
-
## Real-World Example: Replacing Vue Resource with Axios
62
+
## 真实的示例:通过 axios 替换 Vue Resource
64
63
65
-
Let's say you're replacing the [now-retired Vue Resource](https://medium.com/the-vue-point/retiring-vue-resource-871a82880af4). You really enjoyed accessing request methods through `this.$http`and you want to do the same thing with Axios instead.
@@ -76,13 +75,13 @@ All you have to do is include axios in your project:
76
75
</div>
77
76
```
78
77
79
-
Alias `axios` to `Vue.prototype.$http`:
78
+
设置 `Vue.prototype.$http` 为 `axios` 的别名:
80
79
81
80
```js
82
81
Vue.prototype.$http= axios
83
82
```
84
83
85
-
Then you'll be able to use methods like `this.$http.get`in any Vue instance:
84
+
然后你就可以在任何 Vue 实例中使用类似 `this.$http.get`的方法:
86
85
87
86
```js
88
87
newVue({
@@ -100,11 +99,11 @@ new Vue({
100
99
})
101
100
```
102
101
103
-
## The Context of Prototype Methods
102
+
## 原型方法的上下文
104
103
105
-
In case you're not aware, methods added to a prototype in JavaScript gain the context of the instance. That means they can use `this`to access data, computed properties, methods, or anything else defined on the instance.
Note that the context binding will __not__ work if you use an ES6/2015 arrow function, as they implicitly bind to their parent scope. That means the arrow function version:
Uncaught TypeError: Cannot read property 'split' of undefined
138
137
```
139
138
140
-
## When To Avoid This Pattern
139
+
## 何时避免使用这个模式
141
140
142
-
As long as you're vigilant in scoping prototype properties, using this pattern is quite safe - as in, unlikely to produce bugs.
141
+
只要你对原型属性的作用域保持警惕,那么使用这个模式就是安全的——保证了这一点,就不太会出 bug。
143
142
144
-
However, it can sometimes cause 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 confused when `this.$http`is undefined. Or, maybe they want to Google how to do something, but can't find 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, it's impossible to tell where `$http`came from. Vue itself? A plugin? A coworker?
In applications with __no__ module system (e.g. via Webpack or Browserify), there's a pattern that's often used with _any_ JavaScript-enhanced frontend: a global `App`object.
If what you want to add has nothing to do with Vue specifically, this may be a good alternative to reach for. Here's an example:
155
+
如果你想要添加的东西跟 Vue 本身没有太多关系,那么这是一个不错的替代方案。举个例子:
157
156
158
157
```js
159
158
var App =Object.freeze({
160
159
name:'My App',
161
160
description:'2.1.4',
162
161
helpers: {
163
-
//This is a purely functional version of
164
-
//the $reverseText method we saw earlier
162
+
//这我们之前见到过的 `$reverseText` 方法
163
+
//的一个纯函数版本
165
164
reverseText:function (text) {
166
165
returntext.split('').reverse().join('')
167
166
}
168
167
}
169
168
})
170
169
```
171
170
172
-
<pclass="tip">If you raised an eyebrow at `Object.freeze`, what it does is prevent the object from being changed in the future. This essentially makes all its properties constants, protecting you from future state bugs.</p>
Now the source of these shared properties is more obvious: there's an `App`object defined somewhere in the app. To find it, developers can run a project-wide search.
Another advantage is that `App`can now be used _anywhere_ in your code, whether it's Vue-related or not. That includes attaching values directly to instance options, rather than having to enter a function to access properties on `this`:
When you have access to a module system, you can easily organize shared code into modules, then `require`/`import`those modules wherever they're needed. This is the epitome of explicitness, because in each file you gain a list of dependencies. You 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.
0 commit comments