Vue入门 - 高级组件

220 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

定义与使用组件

定义组件

一个*.vue文件就是一个组件,组件名可以使用 kebab-case风格命名,也可以用 camelCase风格命名。组件内容Vue 组件框架保持一致

组件使用

import <组件在本文件中的名字> from '组件相对位置'

再通过components属性把引用的组件列举出来,即可在<template>中直接当作组件使用

<script >
   import Button from './Comp.vue'
   export default {
     components:{Button}
   }

</script>

组件的样式

style样式

组件样式Style

scoped:限定组件样式应用范围

默认情况下,组件style里的样式描述是全局可用的。 在组件<style>中添加 scoped 后 (<style scoped>),样式描述仅限本组件

<style scoped>
  .button{
    ...
  }
  .button:active{
    ...
  }
</style>

组件的数据传递

探讨数据的流向

props:Vue组件的属性

从父组件传递数据到子组件,使用子组件的props属性。

props是一个属性,里面每一个对象定义的内容是可以直接在 <template/> 上使用的data。每个对象里面有 typedefault的值

//子组件中
<template>
  <button class="button">
    {{text}}
  </button>
</template>

<script >
   export default {
     props:{
       // text为 data 的名字
       text:{
         type: String,
         default:'按钮',
       }
   }
</script>

在子组件中定义了props属性后,可以在父组件用相应的属性名传递数据

//父组件中
<script >
  import Button from './Comp.vue'
  export default {
    ...
    components:{
      Button
    }
  }
</script>

<template>
  <Button text="确认" />
</template>

监听子组件的事件

父组件可以监听子组件的自定义事件,并作出相应反应。子组件可以通过自定义事件告诉父组件发生的事情

创建自定义事件

$emit('tap',text) 第一个参数为名称,第二个参数为传递的值

//子组件中
<template>
  //定义了一个点击后发生的自定义事件
  <button class="button" @click="$emit('tap',text)">
    {{text}}
  </button>
</template>

<script>
  export default{
    ...
    
    created(){
      //定义了一个创建后发生的自定义事件
      this.$emit('init')
    }
  }
</script>


监听自定义事件

在父组件中可以监听子组件中创建的事件,监听时发生了自定义事件,则在父组件可以指定方法做点事

// 父组件中
<script >
  import Button from './Comp.vue'
 export default {
     ...
     methods:{
        //参数为子组件定义时传来的数据
        onTapAppButton(text){
          console.log('on tap app button', text)
        },
        onInitAppButton(){
          console.log('on init app button')
        }
   },
   components:{
       Button
 }
 }

</script>

<template>
  //当发生 子组件定义的tap事件时,触发onTapAppButton()方法 
  <Button @tap="onTapAppButton" @init="onInitAppButton" text="好了" />
</template>

在自定义组件上使用 v-model

ninghao.co/T5mILy 建议再看一遍

组件间可以使用v-model进行数据的双向绑定。

//父组件
<script >
  import Input from './Input.vue'
 export default {
     data(){
       return{
         value:""
       }
     },
   components:{Input}
 }

</script>

<template>
  // 以下两种写法等值
  // :modelValue="value" 通过 props从父传递至子 ; @update:modelValue 通过自定义事件从子传递至父
  <Input :modelValue="value" @update:modelValue="value = $event"/>
  <Input v-model="value"/>
  {{value}}
</template>

需要在子组件定义好自定义事件和props属性,名称需要固定才能直接在父组件用 v-model绑定

//子组件
<template>
  // @input 当输入事件发生时,创建自定义事件 update:modelValue
  // :value 输入框内的值绑定 props的 modelValue
  <input type="text" :value="modelValue" @input="$emit('update:modelValue',$event.target.value)"  >
</template>

<script>
  export default{
    props:{
      modelValue:{
        type:String
      }
    }
  }
</script>

组件的生命周期

image_SFzq0XEhUF.png 组件会在相应周期执行周期函数内的内容

vuejs.org/guide/essen…

<script>
  export default{
    //...
    beforeCreate(){
      console.log('comp beforeCreat')
    },
    created(){
      console.log('comp created')
    }
    // mounted() beforeMount()
    // updated() beforeUpdata()
    // unmounted() beforeUnmount()
  }
</script>

其余

slot

插槽内容

在父组件中直接为子组件插入任何HTML内容

//子组件
<template>
  <button>
    // 定义插槽的位置
    <slot></slot>
  </button>
</template>

//父组件
<template>
  // 组件内输入的内容会放置在插槽中
  <Input> hello </Input>
</template>

动态组件

通过条件确定渲染哪一个组件,可通过事件更换组件

<component :is="compName"></component>:is 是需要渲染的组件

<script >
 import Login from './userLogin.vue'
 import Register from './userRegister.vue'
 export default {
     data(){
       return{
         compName:"Login",
         hit:"没有账号?立即注册"
       }
     },
   methods:{
     change(){
       // 通过条件切换组件
       switch(this.compName){
         case 'Login':
           this.compName = 'Register'
           this.hit = "已有账号,立即登陆"
           break
         case 'Register':
           this.compName = 'Login'
           this.hit = "没有账号?立即注册"
           break
       }
     }
   },
    components:{Login,Register}
   
 }

</script>

<template>

  <component :is="compName"></component>
  <small @click="change">{{hit}}</small>
</template>

keep-alive

切换组件时,里面的内容会丢失。如果需要保持内容不丢失,可以使用 <keep-alive> 把动态组件包装起来

<template>
  // 里面的组件切换过程中不会被销毁
  <keep-alive>
    <component :is="compName"></component>
  </keep-alive>
  <small @click="change">{{hit}}</small>
</template>

$refs:引用模板

像在代码中直接操作某个HTML元素,可以使用$refs设置id,并且通过id进行相关操作.

<template>
  <input  type="text" ref="username">
</template>

<script>
  export default{
    ...
    mounted(){
      console.log(this.$refs.username)
      this.$refs.username.focus()
    }
  }
</script>