ref属性
ref属性可以获取DOM元素,被用来给元素或子组件注册引用信息(id的替代者)
<h1 v-text='msg' ref='title'></h1>
<script>
methods:{
showDom(){
console.log(this.$refs.title)
}
}
</script>
-
如果给组件添加ref的话拿到的是组件的实例对象(vc)
-
如果给html标签添加ref的话拿到的是真实的DOM元素
props配置项
可以通过props把子组件的data传递给父组件
当组件复用,但是里面的属性需要使用不同的数据的时候,可以使用props配置项来实现。
父组件==>子组件 通信
子组件==>父组件 通信(要求父组件先给子组件一个函数)
- 传递数据
- 接收数据
- 只接收
- props:[‘name’]
- 限制类型
- props:{name:Number}
- 限制类型,限制必要性,指定默认值
- props:{name:{type:String,required:true,defaule:"小明“}}
- 只接收
Student.vue
<template>
<div>
<h2 v-text="msg" ref="title"></h2>
<h2>学生姓名:{{name}}</h2>
<h2>学生年龄:{{age}}</h2>
<h2>性别:{{sex}}</h2>
</div>
</template>
<script>
export default {
name:"School",
data() {
return {
msg:'你好啊',
}
},
//第一种,简单接收
props:['name','sex','age'],
//第二种,对象接收
props:{
name:String,
age:Number,
sex:String
},
//第三种接收,类型指定,默认值显示,必要性限制
props:{
name:{
type:String, //name是字符类型
required:true //name是必要字段
},
sex:{
type:String, //sex是字符类型
required:true //sex是必要字段
},
age:{
type:Number, //age是字符类型
default:99 //默认值为99
}
}
}
</script>
App.vue
<template>
<div>
<!-- 添加Student组件 -->
<Student ref="Student" name="kitty" sex="女" :age="18"></Student>
<hr>
<Student ref="Student" name="tom" sex="男" :age="9"></Student>
</div>
</template>
如果想要传入数字可以使用:age="18"这种v-bind的形式传入,因为v-bind传入的是引号内的内容
注意:
- props是只读的,Vue底层会监测你对props的修改,如果进行了修改会发出警告(vue监视的是浅层次)
obj.a=12
这种vue不会算作修改obj={x:1,y:2}
这种形式vue会算成修改
- props的属性的优先级大于data属性的优先级
- props传过来的若是对象类型,修改对象中的属性时Vue不会报错,但不推荐这样做
- v-model绑定的值不能是props传递过来的值,因为**props是不可修改的**。
如果要修改props的数据
<template>
<div>
<h2 v-text="msg" ref="title"></h2>
<h2>学生姓名:{{name}}</h2>
<h2>学生年龄:{{myAge}}</h2>
<h2>性别:{{sex}}</h2>
<button @click="addAge">点我增加年龄</button>
</div>
</template>
<script>
export default{
name:"school",
data(){
//利用myAge存储age
myAge:this.age
},
methods:{
addAge()
{
this.myAge++
}
}
}
</script>
mixin混入
两个组件共有的东西可以使用mixin进行混合复用,只需要在mixin中写一遍就行了。
mixin不会破坏你的代码,你的代码中有的mixin中也有那么以你的代码为主。
但是生命周期钩子来说都会使用。
mixin.js
export const mixin1={
methods:{
showName()
{
alert(this.name);
}
}
}
export const mixin2={
x:1,y:2
}
School.vue
<template>
<h2 @click="showName">学生名称:{{name}}</h2>
</template>
<script>
//引入mixin
import {mixin1,mixin2} from '../mixin'
export default{
name:'School',
data(){
name:"school"
},
minxins:[mixin1,mixin2]
}
</script>
Student.vue
<template>
<h2 @click="showName">学生名称:{{name}}</h2>
</template>
<script>
//引入mixin
import {mixin1,mixin2} from '../mixin'
export default{
name:'Student',
data(){
name:"tom"
},
minxins:[mixin1]
}
</script>
全局混合
在main.js中进行混合,那么在项目中所有的vc,vm都会得到mixin
//引入mixin
import {mixin1,mixin2} from '../mixin'
Vue.mixin(mixin1)
Vue.mixin(mixin2)
scoped样式
组件中的样式最终会汇总到一起,如果不同组件中有同名样式那么会发生冲突(后引入的会覆盖先引入的)
给style标签添加scoped标签那么就不会产生冲突。
scoped作用原理:给组件中的元素添加一个特殊的标签属性(该属性中的值为随机生成),该标签属性会和样式一起使用。
APP中的样式只有APP可以使用。
<template>
<h2 class='test'>
school
</h2>
</template>
<style scoped>
.test{
color:red;
}
</style>
slot插槽
默认插槽
在组件template标签中使用
Category.vue
<template>
<!-- 定义一个插槽(挖个坑,等组件使用者进行填充)-->
<slot>我是默认值,当使用者没有传递具体结构时我会出现</slot>
</template>
App.vue
<template>
<Category>
<!--img就会出现在slot的位置-->
<img src="xxx">
</Category>
</template>
具名插槽
当有多个标签需要插入的时候,这里可以使用具名插槽
Category.vue
<template>
<slot name="center"></slot>
<slot name="footer"></slot>
</template>
App.vue
<template>
<Category>
<img slot="center" src="xxx">
<!--在template标签中也可以写成v-slot:footer(只可以在template标签中这么写)-->
<template slot="footer">
<ul>
<li>xxx</li>
<li>xxx</li>
</ul>
<h3>你好啊!</h3>
</template>
</Category>
</template>
作用域插槽
当要使用的数据不在App组件,那么可以使用作用域插槽
Category.vue
<template>
<slot :games="games"></slot>
</template>
<script>
export default{
data(){
games:['1','2','3']
}
}
</script>
App.vue
<template>
<Category>
<!--注意,如果要接收数据那么必须使用template标签包裹-->
<template scope="receive">
<ul>
<li v-for="(g,index) in receive.games" key="index">{{g}}</li>
</ul>
</template>
</Category>
</template>