Close read Vue official documentation series 🎉
Why?
By binding properties or methods to the prototype object of Vue constructor, the global sharing and reuse of data and functions is realized.
Contrast modular code reuse
The require/import approach is more verbose, but produces a clearer list of dependencies and is more maintainable for large, collaborative applications. Extending the prototype is easier and more flexible to use. You can get the properties of these extension members directly from the component instance’s this. For example, this.$foo(), and the extended member methods can also use context objects to get resources on the currently bound component instance, such as props, datas, datas, datas, attrs, $options, computed properties, and other methods.
This convenience, of course, comes at the expense of explicit expression.
Vue.prototype.$http = axios;
Copy the code
Without a clear understanding of the mechanism behind this, it can be confusing to know where the $HTTP method came from.
How?
To avoid overwriting the same names as props, data, methods, calculation properties, etc., of the component instance itself, members of the prototype extension should have their names identified with a specific prefix for scope isolation. For example, $or ω.
To better manage “property on instance”, we should use it as a “plugin”.
alternative
In applications without a modular system (such as Webpack or Browserify), there is a pattern that is common to any jS-heavy front-end application: a global App object.
var App = Object.freeze({
name: 'My App'.version: '2.1.4'.helpers: {
// This is the '$reverseText' method we've seen before
// a pure version of the function
reverseText: function (text) {
return text
.split(' ')
.reverse()
.join(' ')}}})Copy the code
Using object.freeze () to freeze an Object prevents it from being modified in the future. The effect is similar to that of an immutable constant defined by const.
Best practices in TS
First, the Vue type declaration file is modified to add new instance type declarations to its constructors using TypeScript’s Module augmentation mechanism.
// types/shims-vue.d.ts
import {$f, $filters} from './filters.ts';
declare module 'vue/types/vue' {
interface Vue {
$filter: typeof $filters,
$f:typeof $f
}
}
Copy the code
We can then make a plug-in to implement the properties and methods to be extended:
//filter.ts
export const $filters = {
toUpperCase(v){
returnv.toUpperCase(); }};export const $f = function (data:any, ... pipeLines) {
let value = data;
for(const pipeline of pipeLines) {
value = pipeline(value);
}
return value;
}
export defalut install(Vue){
Object.defineProperty(Vue.prototype, '$filters', {
get() {
return $filters
}
});
Object.defineProperty(Vue.prototype, '$f', {
get() {
return $f
}
});
}
Copy the code
Finally, use plug-ins.
import filters from './filters';
Vue.use(filters);
Copy the code
Vue Typescript modules add more declaration types:
declare module 'vue/types/vue'{
interface Vue {} // Declare the type for the instance member on constructor prototype.
interface VueConstuctor {} // Declare globally static member types for the Vue constructor.
interface ComponentOptions <V extends Vue> {} // Declare the type declaration of the component option member.
}
Copy the code