Vue(六) render函数、Vue.config.js配置文件,ref属性,props配置项、mixin混入、插件、scoped
文章目录
- 一、render函数
- 二、Vue.config.js配置文件
- 三. ref属性
- 四. props配置项
- 五. mixin混入
- 1. 局部混入
- 2. 全局混入
- 六. 插件
- 七. scoped
一、render函数
在main.js文件中,采用了render函数。
import App from './App.vue'
new Vue({
// 这句代码的意思是将App组件放入容器中
render: h => h(App),
}).$mount('#app') // 挂载容器
印象中,若采用之前template配置项的方式,写法是这样:
import Vue from 'vue'
// 引入App组件
import App from './App.vue'
// 关掉Vue的生产提示
Vue.config.productionTip = false
// App组件引入、注册且正确使用
new Vue({
el: '#app',
template: `<App></App>`,
components: { App }
})
报错,且提供了两种解决方案
原因是生成的项目默认导入的是运行版的vue(vue.runtime.esm.js)。比完整版的vue少了模板解析器。
解决方法:导入完整版的vue或者采用render函数
- 引入完整版vue
import Vue from 'vue/dist/vue.js'
- render函数
new Vue({
el: '#app',
// render是个函数,vue负责调用这个函数。
// 调用render函数时,传递了createElement函数,该函数可以创建具体元素
// 所以template行不通,render同样可以实现这样的功能。
render (createElement) {
console.log(createElement);
return createElement('h1', 'hello')
}
// 简写为箭头函数,
// render: h => h(App),
})
为什么不用完整版的vue:
在vue.js文件中,模板解析器的代码量约占vue.js的三分之一;webpack打包后,代码已经变成浏览器认识的js等内容,此时模板解析器没有什么作用了,也不应该再参与打包了。不打包模板解析器也能节省一点空间,让打包出来的文件小一点。所以采用精简版的vue。
总结:
- vue.js与vue.runtime.xxx.js的区别
- vue.js是完整版的js,包含核心功能+模板解析器
- vue.runtime.xxx.js,只包含核心功能,没有模板解析器,所以不能使用template配置项,需要render函数接收createElement函数去指定具体的内容
二、Vue.config.js配置文件
这个文件用来修改一些默认配置,比如项目入口的文件名不再使用main.js,改为peiqi.js; 执行命令:
vue inspect > output.js
生成ouput.js文件,默认配置都在该文件内
具体可以修改哪些配置,查看官网说明:https://cli.vuejs.org/zh/config/
三. ref属性
给元素添加ref属性,可用来获取DOM节点
- 打标识:
<h1 ref="xxx">...</h1>
- 获取:
this.$refs.xxx
应用在html元素中,获取到的是真实DOM元素(相当于定义id属性,document.getElementById…)。
应用在组件标签上是组件实例对象(vc)
<template>
<div>
<!-- html元素 -->
<h1 ref="title">欢迎学习</h1>
<button @click="showInfo" ref="btn">点击显示节点信息</button>
<!-- 组件 -->
<School ref="sch"></School>
</div>
</template>
<script>
...
methods: {
showInfo () {
console.log(this.$refs);
}
}
</script>
四. props配置项
propos配置:可实现组件传值。
传值:
//APP组件给子组件School传值
<template>
<div>
<!--传递的值都是string类型,若要传数字型,则用v-bind绑定属性`:age=xxx`,xxx里是js表达式,则age转为数字型-->
<Student name="张三" gender="男" :age="18"></Student>
</div>
</template>
接收值:
// School.vue接收值
<template>
<div>
<h2>学生年龄:{{ stuAge }}</h2>
<h2>学生姓名:{{ stuName }}</h2>
<button @click="stuAge++">点击+1</button>
</div>
</template>
<script>
export default {
data () {
return {
msg: '学生信息',
// 定义变量来接收props值,
stuName: this.name,
stuAge: this.age
}
},
// 接收
props: ['name', 'age'],
</script>
注:propos接收的值不能修改,若要修改则需在data中定义变量接收这个值,然后再修改
propos配置:组件接收外部来的数据,有三种接收方式
- 只接收:
props: ['name', 'age', 'gender']
- 限制类型:
props: {name: String,...}
- 限制类型、限制必要性、指定默认值
props: {
name: {
type: String,
required: true,
default: 99
}
}
五. mixin混入
minxin就是把多个组件中一样的配置提取出来,形成一个对象。使用的时候导入即可,无需再写这个配置。
1. 局部混入
1、在src包下创建一个mixin.js文件,写入配置对象
// src/mixin.js
export const hunhe = {
methods: {
showInfo () {
alert(this.name)
}
}
}
export const hunhe2 = {
data () {
return {
x: 200,
y: 600
}
},
mounted () {
console.log('加载');
}
}
2、在组件中混入并配置好
<template>
<div>
<h2 @click="showInfo">学校名称:{{ name }}</h2>
<h2>学校地址:{{ address }}</h2>
</div>
</template>
<script>
import { hunhe, hunhe2 } from '../mixin.js'
export default {
data () {
return {
name: '窗户学院',
address: '魔法堡',
x: 1
}
},
mounted () {
console.log('School组件挂载完毕');
},
mixins: [hunhe, hunhe2]
}
</script>
点击学校名称,触发事件
如果组件内的配置项与maxin内的配置项(与methods里的方法重名,或与data里的属性充满)有冲突,则以组件内的为准,(生命周期函数除外)
School组件里的x还是1,但是多了个y值
生命周期函数:
2. 全局混入
在main.js中混入,这种方式会给所有组件都混入mixin的配置
import { hunhe, hunhe2 } from './mixin.js'
Vue.mixin(hunhe)
Vue.mixin(hunhe2)
所有组件都有了x和y属性
六. 插件
插件的本质是一个对象,且必须包含install
方法。install
的第一个参数是vue,第二个以后的参数是插件使用者传递的数据。
- 定义插件:
创建文件src/plugins.js
export default {
install (Vue, x, y, z) {
console.log(x, y, z);
// 全局过滤器
Vue.filter('mySlice', function (value) {
return value.slice(0, 4)
})
// 定义全局指令
Vue.directive('big', (element, binding) => {
element.innerText = binding.value * 10
})
// 定义混入
Vue.mixin({
methods: {
showInfo () {
alert(this.name)
}
}
})
// 给Vue原型添加一个方法
Vue.prototype.hello = () => { alert('hello') }
}
}
- 引入并应用插件:
main.js
// 引入插件
import plugins from './plugins'
// 使用插件
Vue.use(plugins, 1, 2, 3)
七. scoped
作用是让样式在当前组件生效,防止冲突。
编码时,所有组件内的style样式会汇总到一起,所以选择器可能会发生冲突
比如目前有两个组件school和student,添加背景色
School.vue
:
<template>
<div class="demo">
<h2>学校名称:{{ name }}</h2>
<h2>学校地址:{{ address }}</h2>
</div>
</template>
<style>
.demo {
background-color: orange;
}
</style>
Student.vue
:
<template>
<div class="demo">
<h2>学生姓名:{{ name }}</h2>
<h2>学生年龄:{{ age }}</h2>
</div>
</template>
<style>
.demo {
background-color: skyblue;
}
</style>
由于两个组件的类名一致且都选用类名选择器,所以:
最终色是哪个取决于App.vue中引入组件的顺序,
import School from './components/School.vue'
import Student from './components/Student.vue'
在style标签中加入scoped,则可防止样式冲突。本质是本组件的元素添加了自定义属性,选择器采用类名[属性名=属性值]
的叠加选择器