Vue复习(2)

179 阅读3分钟

书接上回,我们着重复习了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.使用步骤

  1. 使用import导入需要的组件
  2. 在component节点下注册组件
  3. 以标签的形式使用组件

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. 步骤

  1. 在子组件定义要传输的props值
  2. 在父组件中引入子组件
  3. 使用子组件的同时使用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.注意

  1. 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>
    
  2. 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.使用步骤
  1. 在子组件中定义自定义事件名称需要传递的数据,这个时候此自定义事件就会有需要传递的数据
  2. 子组件中就会多一个自定义事件
  3. 父组件接收到使用v-on调用自定义事件
  4. 自定义事件再调用函数接收 数据
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. 实现步骤
  1. 创建eventBus.js模块,向外共享一个Vue实例对象
  2. 在数据发送方调用bus.$emit()函数触发自定义事件
  3. 在数据接收方,调用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.使用步骤

  1. 在DOM元素绑定ref并取名字
  2. 使用this.$refs.name访问元素
  3. 这里获取到的是真实的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>