书接上回,我们着重复习了Vue相关的指令内容,本次我们来复习Vue的方法和相关组件内容
3. vue方法
1. 过滤器
1.介绍
- 常用于文本格式化,只能用在两个地方:插值表达式和v-bind属性绑定
- 过滤器第一个参数总是管道符前面的数值,后面的参数才是过滤器自己的参数
2.使用
<template>
<div id="app">
<!--管道符前面的数值会作为参数传递给后面的函数-->
<h2>{{msg | capi}}</h2>
</div>
</template>
<script>
const vm = new Vue({
el:"#app",
data:{
msg:"hello vue"
},
filters:{
capi(val){
return val.charAt(0).toUpperCase()
}
}
})
</script>
3.全局过滤器
Vue.filter("capi",function(val){
return val.charAt(0).toUpperCase()
})
2.侦听器
1.介绍
- 侦听器监视数据的变化,从而针对数据的变化做特定的操作
2.使用
<template>
<div id="app">
</div>
</template>
<script>
const vm = new Vue({
el:"#app",
data:{
username:""
},
watch:{
//这里的函数名要和data中的数据一致,监听data中 数据的变化
username(newVal,oldVal){
console.log(newVal,oldVal)
}
}
})
</script>
3. 深度侦听
<template>
<div id="app">
</div>
</template>
<script>
const vm = new Vue({
el:"#app",
data:{
username:""
},
watch:{
username:{
handler(newVal,oldVal){
console.log(newVal,oldVal)
},
immediate:true,
//开启深度侦听,可以访问对象里面的对象
deep:true,
}
}
})
</script>
3.计算属性
1.介绍
- 计算属性经过一系列的计算之后,最终 得到一个 属性值
- 当计算属性所依赖的数据源发生变化的时候,计算属性会重新求值
- 内部有缓存机制,可以达到代码的复用
2.使用
<template>
<div id="app">
<p>{{user}}</p>
</div>
</template>
<script>
const vm = new Vue({
el:"#app",
data:{
username:"carlos",
password:"admin123",
},
computed:{
user(){
return this.username + this.password
}
}
})
</script>
完整写法
<template>
<div id="app">
<p>{{user}}</p>
</div>
</template>
<script>
const vm = new Vue({
el:"#app",
data:{
username:"carlos",
password:"admin123",
},
computed:{
user:{
//这里如果要直接修改计算属性的值就要z
get(){
return this.username +this.password
},
set(){
return this.username +this.password
}
}
}
})
</script>
4.mixin
- 可以全局共享的方法和属性
export const mixin={
methods:{
showName(){
alert(this.name)
}
}
}
export const mixin2 ={
computed:{
fullname(){
this.firstname+this.lastname
}
}
}
<script>
import {mixin,mixin2} from "./mixin.js"
export default {
mixins:[mixin,mixin2]
}
</script>
4.vue-cli
1.组件的使用
1.使用步骤
- 使用import导入需要的组件
- 在component节点下注册组件
- 以标签的形式使用组件
2.使用
<template>
<div>
<!--3.以标签的形式使用组件-->
<v-component>
</v-component>
</div>
</template>
<script>
//1. 使用import导入需要的组件
import Components from "./components/componets"
export default {
components:{
//2.在component节点下注册组件
"v-component":Components
}
}
</script>
3.全局组件
//在main.js中
//1.导入需要的组件
import Count from "./components/count.vue"
//注册全局组件
Vue.component("MyCount",Count)
//每个组件里面都可以用MyCount使用组件
2.props
1.介绍
- 用于提高使用组件时的灵活度,提高代码的复用性
2. 步骤
- 在子组件定义要传输的props值
- 在父组件中引入子组件
- 使用子组件的同时使用props
3.使用
//Count子组件
<template>
<div>
{{init}}
</div>
</template>
<script>
export default {
props:["init"]
}
</script>
//Left父组件
<template>
<div>
<!--
这里的值不是数字9而是字符串9
解决办法有两种,一是用v-bind:init,
另一种是将props封装为对象形式指定传递类型
-->
<my-count init="9"></my-count>
</div>
</template>
<script>
import Count from "./components/Count.vue"
export default {
//简单写法
props:["init"],
//复杂写法
props:{
init:{
default:0,
type:Number,
required:true
}
}
components:{
"my-count":Count
}
}
</script>
4.注意
-
props值是不可以被修改的,只有把数据转存到data中才可以修改
//Left父组件 <template> <div> <my-count init="9"></my-count> </div> </template> <script> import Count from "./components/Count.vue" export default { data(){ return { //转存props count:this.init } } props:["init"], components:{ "my-count":Count } } </script> -
props也可以用来传输数据(父向子)
//Left父组件 <template> <div> <my-count :init="msg"></my-count> </div> </template> <script> import Count from "./components/Count.vue" export default { data(){ return{ msg:"hello world" } } props:["init"], components:{ "my-count":Count } } </script>
3.样式冲突问题
1. 样式冲突
- 默认组件的样式会相互影响,需要在样式中加上scoped
2.deep穿透
-
父组件加上scoped之后修改子组件的样式
<style scoped> /deep/ h5 { color:pink; } </style>
4.生命周期
5.数据共享
1.子向父传数据
1.自定义事件
1.使用步骤
- 在子组件中定义自定义事件名称和需要传递的数据,这个时候此自定义事件就会有需要传递的数据
- 子组件中就会多一个自定义事件
- 父组件接收到使用v-on调用自定义事件
- 自定义事件再调用函数接收 数据
2.使用
//子组件
<template>
<div>
<button @click="add">
点击按钮触发add函数
</button>
</div>
</template>
<script>
export default {
data(){
return{
count:0
}
}
methods:{
add(){
this.count++;
//按下按钮调用add函数,触发$emit函数,绑定自定义事件
//传递一个参数是将要传输的数据
this.$emit("countChange",this.count)
}
}
}
</script>
-
第一种方式
<template> <div> <!--2.绑定一个事件,将函数赋值给事件--> <Count @countChange="getCount"></Count> </div> </template> <script> export default { data(){ return{ countFromSon:0 } }, methods:{ //1.定义一个函数接收到一个参数,参数是什么暂时还不知道 getCount(val){ this.countFromSon =val } } } </script> -
第二种方式
<template> <div> <Count ref="student"></Count> </div> </template> <script> export default { data(){ return{ countFromSon:0 } }, methods:{ getCount(val){ this.countFromSon = val } }, mounted(){ this.$refs.student.$on("countChange",this.getCount) } } </script>2. 解绑
//子组件 <template> <div> <button @click="add"> 点击按钮触发add函数 </button> </div> </template> <script> export default { methods:{ add(){ this.count++; this.$emit("countChange",this.count) }, unbind(){ //不传递c this.$off(["countChange"]) } } } </script>
2.props(子向父)
- 所用方法props和v-bind自定义属性
<!-- 子组件 -->
<template>
<div>
<!-- 点击调用send函数 -->
<button @click="send">点我把学校给APP</button>
</div>
</template>
<script>
export default {
//发送hello
props:["hello"],
data(){
return{
schoolName:"华南理工大学",
}
},
methods:{
send(){
//调用hello函数,发送shoolname
//这里的hello是调用函数,接收一个参数,是将要给父组件传递的参数
this.hello(this.schoolName)
}
}
}
</script>
<!-- 父组件 -->
<!-- 将hello赋值为一个函数,函数名就是getSchoolName -->
<v-event :hello="getSchoolName"> </v-event>
<script>
export default {
methods: {
getSchoolName(name, address) {
console.log("收到了schoolname", name, address);
},
};
</script>
2.全局事件总线
- 可以实现兄弟组件数据的共享
1. 实现步骤
- 创建eventBus.js模块,向外共享一个Vue实例对象
- 在数据发送方调用bus.$emit()函数触发自定义事件
- 在数据接收方,调用bus.$on()函数注册一个自定义事件
2.使用
<!--数据发送方-->
<template>
<div>
<!--1.点击按钮调用sendMsg函数-->
<button @click="sendMsg"></button>
</div>
</template>
<script>
import bus from "./eventbus.js"
export default {
data(){
return {
msg:"hello vue!"
}
},
methods:{
sendMsg(){
//触发share函数,将数据作为参数发送
bus.$emit("share",this.msg)
}
}
}
</script>
<!--数据接收方-->
<template>
<div>
</div>
</template>
<script>
import bus from "./eventbus.js"
export default {
data(){
return {
getMsg:""
}
},
created(){
//在bus身上绑定一个share函数
bus.$on("share",val=>{
this.getMsg =val
})
}
}
</script>
//eventBus.js中需要做的事就是向外共享一个Vue实例
import Vue from "vue"
export default new Vue()
3.消息订阅与发布
- 安装
npm i pubsub-js
<!--数据发送方-->
<script>
import pubsub from "pubsub-js"
export default{
sendMsg(){
pubsub.publish("hello",this.msg)
}
}
</script>
<!--数据接收方-->
<script>
import pubsub from "pubsub-js"
export default{
methods:{
pubMsg(name,data){
console.log(name,data)
}
},
mounted(){
//第一个参数是函数名,第二个参数开始才是发送的数据
this.pubname = pubsub.subscript("hello",this.pubMsg)
},
beforeDestroy(){
//取消订阅与发布
pubsub.unsubscipt(this.pubname)
}
}
</script>
6.ref使用
- 用于获取DOM元素或组件
1.使用步骤
- 在DOM元素绑定ref并取名字
- 使用this.$refs.name访问元素
- 这里获取到的是真实的DOM元素
2.使用
<template>
<div>
<h2 ref ="refDom"> </h2>
</div>
</template>
<script>
export default {
methods:{
showDom(){
console.log(this.$refs.refDom)
}
}
}
</script>
2.组件上的ref
- 组件上加上ref,就会获得组件的实例VueComponent
- 这个时候ref的数据和方法就完全暴露
1.$nextTick
- 当代码需要延时到当页面重新渲染完毕之后执行
- 在下一次DOM更新结束之后调用
- 当改变数据 后,要基于更新后的DOM进行某些操作时,要在nextTick指定的
this.$nextTick(()=>{
this.$refs.iptRef.focus()
})
7.动画效果?
- 使用
<template>
<!-- appear是进入的时候就播放动画 -->
<transition name="amt" appear>
<h1>hello animition</h1>
</transition>
</template>
<style>
/*
如果transition标签没有name属性,则用默认v-
如果transition标签有name属性,则用name-
*/
.amt-enter-active{
animation:amt 1s;
}
.amt-leave-active{
animation :amt 1s reverse
}
</style>