vue2组件
组件的通信 props $emit $ref
父向子的通信: props
//父组件:
<template>
<div>
<h4>我是父组件</h4>
<input type="text" v-model="message" />//双向绑定message数据
<p>收到子组件的消息:</p>
<Child :messageFromParent="message"/>// prop 可以通过 v-bind 动态赋值,
</div>
</template>
<script>
import Hello from './components/Child.vue'
export default {
name: "App",
components:{Child},
data() {
return {
message:""//父向子传递的数据
}
},
};
</script>
//子组件:
<template>
<div>
<h4>我是子组件</h4>
<p>收到父组件的消息:{{messageFromParent}}</p>//父组件传过来的数据渲染到页面中
</div>
</template>
<script>
export default {
name:'Child',
props:['messageFromParent'],//接收父组件传过来的数据,这里是props
data() {
return {
message:""
}
},
}
</script>
子向父的通信:$emit
//子组件
<template>
<div>
<h4>我是子组件</h4>
<input type="text" v-model="message" @keyup="send"/>//触发键盘事件
</div>
</template>
<script>
export default {
name:'Child',
props:['messageFromParent'],
data() {
return {
message:""
}
},
methods: {
send(){
//通过这里的this.$emit()向父组件传递消息
this.$emit('reseive',this.message)//第一个参数是自定义事件,第二个参数是要发送的数据
}
},
}
</script>
//父组件
<template>
<div>
<h4>我是父组件</h4>
<input type="text" />
<p>收到子组件的消息:{{messageFromChild}}</p>
<Child v-on:reseive="reseive" />
</div>
</template>
<script>
import Hello from './components/Child.vue'
export default {
name: "App",
components:{Child},
data() {
return {
messageFromChild:''
}
},
methods: {
//创建一个自定义事件接收的函数,收到子组件的消息
reseive(data){//data就是这里的this.$emit('reseive',this.message)message参数
this.messageFromChild=data
}
},
};
</script>
组件上使用v-model
$ref
- ref 绑定在标签里,可以获取当前的dom元素
<input ref="myInput" type="text" />
mounted() {
console.log(this.$refs.myInput)
//打印出当前的dom元素 <input type="text">
},
ref 绑定在标签里,可以获取当前的dom元素
<template>
<Child ref="child" />//子组件Child
</template>
mounted() {
console.log(this.$refs.child)
//打印出当前子组件Child的实例,所以可以直接拿到子组件身上的数据
//VueComponent {_uid: 4, _isVue: true, __v_skip: true, _scope: EffectScope, $options: {…}, …}
},
- 父向子通信
插槽的基本用法
- 编译作用域
父级模板里的所有内容都是在父级作用域里编译的,子级模板里的所有内容都是在子级作用域里编译的。 - 插槽的后备内容(相当于插槽的默认值)
可以在slot中提前设置一段内容作为默认值,当父组件提供插槽时会被覆盖。
//父组件
<template>
<div>
<Hello>//子组件
<Haaa></Haaa>//可以插入其他子组件
哈哈哈哈哈哈//可以插入文本
<h3>我在app {{user}}</h3>//可以插入标签,可以插入父组件的数据
</Hello>
</div>
</template>
<script>
import Hello from './components/Hello.vue'
import Haaa from './components/Haaa.vue'
export default {
name: "App",
components:{Hello,Haaa},
data() {
return {
user:"me"
}
},
};
</script>
//子组件
<template>
<div>
<p>标题</p>
<div>
<p>内容</p>
<slot></slot>//父组件<hello></Hello>里的内容显示在这里
//如果Hello组件里没有包含slot元素,则该组件其实标签和结束标签之前的任何内容都会被抛弃
</div>
</div>
</template>
<script>
export default {
name:'Hello',
}
</script>
- vm.$slots
用来访问插槽分发的内容(指的是插槽里面的虚拟dom)
<template>
<div>
<Hello ref="hello">
<template v-slot:default>//获取到子组件中所有插槽的实例
<h3>我在app {{user}}</h3>
</template>
</Hello>
</div>
</template>
<script>
import Hello from './components/Hello.vue'
export default {
name: "App",
components:{Hello},
data() {
return {
user:"me"
}
},
mounted() {
console.log(this.$refs.hello.$slots)
//vm.$slots用来访问插槽里面的虚拟dom
},
};
</script>
具名插槽
作用:需要多个插槽时,具名插槽会将插槽内容到指定位置
//父组件
<template>
<div>
<Hello>
<template v-slot:header>
<div>我是头部</div>//这个位置的内容放在子组件的<slot name="header"></slot>这个位置
</template>
<template v-slot:main>
<div>我是主要内容</div>
</template>
<template v-slot:footer>
<div>我是尾部</div>
</template>
</Hello>
</div>
</template>
<script>
import Hello from "./components/Hello";
export default {
name: "App",
components: { Hello },
};
</script>
//子组件
<template>
<div>
<header>
<slot name="header"></slot>
</header>
<main>
<slot name="main"></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>
<script>
export default {
name:'Hello',
}
</script>
作用域插槽(父组件可以获得子组件的数据)
- 基本用法
//父组件
<template>
<div>
<Hello>
<template v-slot:default="props">//获取当前插槽实例,赋值一个变量props
{{props.user.firstName}}//,获取子组件实例身上的user属性的firstName属性值,改变默认值
</template>
</Hello>
</div>
</template>
<script>
import Hello from "./components/Hello";
export default {
name: "App",
components: { Hello },
};
</script>
//子组件
<template>
<div>
<span>
<slot v-bind:user="user">{{user.lastName}}</slot>//默认值是user.lastName:'默默'
</span>
</div>
</template>
<script>
export default {
name:'Hello',
data() {
return {
user:{
firstName:'老大',
lastName:'默默'
}
}
},
}
</script>
- 应用场景
计算属性computed
- 函数用法
<template>
<div>
<p>单价:{{price}}</p>
<p @click="num +=1">数量:{{num}}</p>
<p>总额{{allPrice}}</p> //return出来的值
</div>
</template>
<script>
import Hello from "./components/Hello";
export default {
name: "App",
components: { Hello },
data() {
return {
price:'100',
num:0,
};
},
computed:{
allPrice(){ //定义了一个函数
return this.price *this.num //必须return ,
}
}
};
</script>
特性
- 计算属性会被加到vue实例
- 计算属性所依赖的数据为发生变化,结果会被缓存
- 对象用法
<template>
<div>
<p>单价:{{price}}</p>
<p @click="num +=1">数量:{{num}}</p>
<p>总额{{ getPrise}}</p>
<button @click="renum">重置数量</button>
</div>
</template>
<script>
import Hello from "./components/Hello";
export default {
name: "App",
components: { Hello },
data() {
return {
price:'100',
num:0,
};
},
methods: {
renum(){
this.num=0 //改变数量。会修改计算属性的值
}
},
computed:{//当要修改计算属性的值,需要传入一个对象
getPrise:{
get(){
return this.price *this.num //得到当前的计算属性,并渲染到野蛮上
},
set(val){//当计算属性改变时候,触发该方法,接收赋值传入进来的参数num
this.num=val
}
}
}
};
</script>
``