官方原话:
你可能会在很多组件里用到数据/实用工具,但是不想污染全局作用域
。这种情况下,你可以通过在原型上定义它们使其在每个 Vue 的实例中可用。
在main.js
中添加一个变量到 Vue.prototype
Vue.prototype.$appName = 'My App'
这样 $appName
就在所有的 Vue 实例中可用了,甚至在实例被创建之前就可以。
new Vue({
beforeCreate: function () {
console.log(this.$appName)
}
})
为什么appName
要以$
开头?这很重要吗?
$
是在 Vue 所有实例中都可用的property
的一个简单约定。这样做会避免和已被定义的数据、方法、计算属性产生冲突。
如果我们设置:
Vue.prototype.appName = 'My App'
那么如下的代码输出什么:
new Vue({
data: {
// 啊哦,`appName` 也是一个我们定义的实例 property 名!
appName: 'The name of some other app'
},
beforeCreate: function () {
console.log(this.appName)
},
created: function () {
console.log(this.appName)
}
})
日志中会先出现
“My App”
,然后出现“The name of some other app”
,
因为this.appName
在实例被创建之后被data
覆写了。
我们通过$
为实例property
设置作用域来避免这种事情发生。
你还可以根据你的喜好使用自己的约定,诸如 $_appName 或 ΩappName,来避免和插件或未来的插件相冲突。
变量
每个组件都是一个vue实例。
Vue.prototype
加一个变量,只是给每个组件加了一个属性,这个属性的值并不具有全局性。
- 给所有组件注册了一个属性
$appName
,赋予初始值'main'
,所有组件都可以用this.$appName
访问此变量;- 如果组件中没有赋值,初始值都是
'main'
.
比如以下例子:
点击 home 中的 change name 再跳转about,about里面还是显示 main in test2
// main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
Vue.config.productionTip = false
Vue.prototype.$appName = 'main'
new Vue({
el: '#app',
store,
router,
components: { App },
template: ' ',
})
// home.vue
<template>
<div>
<div @click="changeName">change namediv>
<div @click="gotoTest2">goto test2div>
div>
template>
<script>
export default {
methods:{
changeName(){
this.$appName = "test1"
},
gotoTest2(){
this.$router.push('/about')
}
}
}
script>
// about.vue
<template>
<div>
<div>{{this.$appName}} in test2div>
div>
template>
如果要实现全局变量的功能,需要把属性变为引用类型
Vue.prototype.$appName = { name: 'main' }
后面使用this.$appName.name
改变和引用相应的值
这进入 about 后显示 test1 in test2
在 JavaScript 中一个原型的方法会获得该实例的上下文,也就是说可以使用 this
访问:数据、计算属性、方法或其它任何定义在实例上的东西。
让我们将其用在一个名为 $reverseText 的方法上:
// main.js
Vue.prototype.$reverseText = function (propertyName) {
this[propertyName] = this[propertyName]
.split('')
.reverse()
.join('')
}
// 相应组件
<script>
export default {
data() {
return{
message: 'Hello'
}
},
created() {
console.log(this.message) // => "Hello"
this.$reverseText('message')
console.log(this.message) // => "olleH"
}
}
</script>
npm install vue-axios --save
npm install qs.js --save //它的作用是能把json格式的直接转成data所需的格式
// mian.js
import Vue from 'vue'
import axios from 'axios'
import qs from 'qs'
Vue.prototype.$axios = axios //全局注册,使用方法为:this.$axios
Vue.prototype.qs = qs //全局注册,使用方法为:this.qs
// 相应组件
<script>
export default{
data(){
return{
userId:666,
token:'',
}
},
created(){
this.$axios({
method:'post',
url:'api',
data:this.qs.stringify({ //这里是发送给后台的数据
userId:this.userId,
token:this.token,
})
}).then((response) =>{ //这里使用了ES6的语法
console.log(response) //请求成功返回的数据
}).catch((error) =>{
console.log(error) //请求失败返回的数据
})
}
}
</script>
官方原话:
Vue.component:注册或获取全局组件
。
在说注册全局组件之前,我们先说下局部组件,局部组件才是实际开发用的最多的场景。
// Children.vue
<template>
<div>
<div>组件文件div>
div>
template>
<script>
export default {
data() {
return {};
},
};
script>
<style lang="scss" scoped>
style>
<template>
<div>
<Children1>Children1>
div>
template>
<script>
import Children from './Children.vue'
export default {
components: {
Children
}
}
script>
<style scoped>style>
组件:
其实就是日常开发中的写vue文件,每个vue都可以看成是一个组件。
局部组件:
A组件引入B组件,并在A组件的components
注册并使用。B组件就是一个局部组件。
全局组件,仅仅是从单文件引入改为在main.js
文件中引入即可。
import Vue from 'vue'
import App from './App.vue'
import Children from './views/Children.vue';//引入组件
Vue.component('Children ',Children )//注册组件
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
注意
在日常使用中应该尽量避免使用全局引入,这会大大增加项目体积,
在组件复用性不高的情况下,应该使用局部引入,
只有在组件复用性非常高的时候才应该考虑使用全局引入。
官方原话:
安装 Vue.js 插件。
如果插件是一个对象,必须提供 install 方法。
如果插件是一个函数,它会被作为 install 方法。install 方法调用时,会将 Vue 作为参数传入。
注意
- 通过Vue.use安装 Vue.js 插件,
- 如果插件是一个对象,那么当Vue.use(插件)之后,插件的install方法会立即执行;
- 如果插件是一个函数,当Vue.use(插件)之后,函数会被立即执行
- Vue.use
参数为函数
(插件为函数)时,函数的参数是Vue对象.
- Vue.use
参数为对象
(插件为对象)时,它提供的install方法中参数是Vue对象
// 新建一个 demo.js ,尝试参数为函数时 Vue.use() 的情况 ,demo.js文件内容如下
function demo (Vue){
console.log('fn', Vue)
}
export default demo
// 之后在main.js引入demo.js,并且使用 Vue.use() 调用
import demo from '@/components/demo.js'
Vue.use(demo)
// 新建一个 demo.js ,尝试参数为对象时 Vue.use() 的情况 ,demo.js文件内容如下
const demo = {
// 参数为对象时,需要提供install方法
install: (Vue) => {
console.log('obj', Vue)
}
}
export default demo
// 之后在main.js引入demo.js,并且使用 Vue.use() 调用
import demo from '@/components/demo.js'
Vue.use(demo)
import { toArray } from '../util/index'
// Vue.use 源码
export function initUse (Vue: GlobalAPI) {
// 首先先判断插件plugin是否是对象或者函数:
Vue.use = function (plugin: Function | Object) {
const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
// 判断vue是否已经注册过这个插件,如果已经注册过,跳出方法
if (installedPlugins.indexOf(plugin) > -1) {
return this
}
// 取vue.use参数,toArray() 方法代码在下一个代码块
const args = toArray(arguments, 1)
args.unshift(this)
// 判断插件是否有install方法,如果有就执行install()方法。没有就直接把plugin当Install执行。
if (typeof plugin.install === 'function') {
plugin.install.apply(plugin, args)
} else if (typeof plugin === 'function') {
plugin.apply(null, args)
}
installedPlugins.push(plugin)
return this
}
}
// toArray 方法源码
export function toArray (list: any, start?: number): Array<any> {
start = start || 0
let i = list.length - start
const ret: Array<any> = new Array(i)
while (i--) {
ret[i] = list[i + start]
}
return ret
}
Vue.prototype
- 在多个地方都需要使用但
不想污染全局作用域
的情况下,这样定义,- 在每个 Vue 实例中都可用。
- $ 表示这是一个在 Vue 所有实例中都可用的属性,
- 常用于
方法
、变量
等
import echarts from 'echarts'
Vue.prototype.$echarts = echarts
全局注册组件
- 第一个参数是调用组件时写的组件名,
- 第二个参数是引入组件时写的名称,
- 可用于
注册自定义组件
- 自定义组件:就是我们自己写的vue文件
- 一般情况下,用vue.component注册全局组件的情况不多,多数还是局部组件注册
import myLoading from 'base/loading'
Vue.component('myLoading',myLoading);
Vue.use
- 如果插件是一个
对象
,必须提供install 方法
。当Vue.use(插件)之后,插件的install方法会立即执行,install方法中参数是Vue对象
;- 如果插件是一个
函数
,它会被作为 install 方法。当Vue.use(插件)之后,函数会被立即执行,函数的参数是Vue对象.
。- 常用于
注册第三方插件
。例如:element ui等第三方库
import ElementUI from 'element-ui';
Vue.use(ElementUI);