vue学习笔记day3——组件高级

一 watch侦听器

watch侦听器允许开发者监视数据的变化,从而针对数据的变化做特定的操作。例如,监听用户名的变化并发起请求,判断用户名是否可用。

1.1 watch侦听器的基础用法

开发者需要在watch节点下,定义自己的侦听器。如下:

<template>
  <div>
    <h3>watch</h3>
    <input type="text" class="form-control" v-model.trim="username">
  </div>
</template>

<script>
export default {
  name:'Mywatch',
  data(){
    return{
      username:''
    }
  },
  watch:{
    username(newVal,oldVal){
      console.log(newVal,oldVal)
    }
  }
}
</script>

1.2 immediate选项

默认情况下,组件在初次加载完毕后不会调用watch侦听器,如果想让watch侦听器立即被调用,则需要使用immediate选项。如下:

watch:{
      username:{
        async handler(newVal,oldVal){
          const res = await axios.get('https://applet-base-api-t.itheima.net/api/finduser'+newVal)
          console.log(res)
        },
        immediate:true
      }
    }

1.3 deep选项

当watch侦听的是一个对象,如果对象中的属性值发生了变化,则无法被监听到。此时需要使用deep选项,如下:

<template>
  <div>
    <h3>watch</h3>
    <input type="text" class="form-control" v-model.trim="info.username">
  </div>
</template>

<script>
import axios from 'axios'
export default {
  name:'Mywatch',
  data(){
    return{
      username:'admin',
      info:{
        username:'zs'
      }
    }
  },
  watch:{
      info:{
        async handler(newVal){
          const {data:res} = await axios.get('https://applet-base-api-t.itheima.net/api/finduser/'+newVal.username)
          console.log(res)
        },
        deep:true
      }
    }
}
</script>

1.4 监听对象单个属性的变化

如果只想监听对象中单个属性的变化,则可以按照如下方式定义watch侦听器

<template>
  <div>
    <h3>watch</h3>
    <input type="text" class="form-control" v-model.trim="info.username">
  </div>
</template>

<script>
import axios from 'axios'
export default {
  name:'Mywatch',
  data(){
    return{
      username:'admin',
      info:{
        username:'zs'
      }
    }
  },
  watch:{
      'info.username':{
        async handler(newVal){
          const {data:res} = await axios.get('https://applet-base-api-t.itheima.net/api/finduser/'+newVal)
          console.log(res)
        },
        deep:true
      }
    }
}
</script>

1.5 计算属性VS侦听器

计算属性和侦听器侧重的应用场景不同:

计算属性侧重于监听多个数值的变化,最终计算并返回一个新值

侦听器侧重于监听单个数据的变化,最终执行特定的业务处理,不需要有任何返回值

二 组件的生命周期

2.1 组件运行的过程

 组件的生命周期指的是:组件从创建——运行(渲染)——销毁的整个过程,强调的是一个时间段。

2.2 如何监听组件的不同时刻

vue框架为组件内置了不同时刻的生命周期函数,生命周期函数会伴随着组件的运行而自动调用。例如:

当组件在内存中被创建完毕后,会自动调用created函数

当组件被成功的渲染到页面上之后,会自动调用mounted函数

当组件被销毁完毕后,会自动调用unmounted函数

App.vue

<template>
  <div>
    app根组件
    <button @click="flag=!flag">显示或隐藏</button>
    <life-cycle></life-cycle>
  </div>
</template>

<script>
import LifeCycle from './LifeCycle.vue'
export default {
  name:'MyApp',
  data(){
    return {
      flag:true
    }
  },
  components:{
    LifeCycle
  }
}
</script>

LifeCycle.vue 

<template>
  <div>
    life
  </div>
</template>

<script>
export default {
  name:'LifeCycle',
  // 组件在内存中被创建完毕了
  created(){
    console.log('created:组件在内存中被创建完毕了')
  },
  // 组建第一次被渲染到了页面上
  mounted(){
    console.log('mounted: 组建第一次被渲染到了页面上')
  },
  // 组件被销毁完毕了
  unmounted(){
    console.log('unmounted:组件被销毁完毕了')
  }
}
</script>

2.3 如何监听组件的更新

当组件的data数据更新之后,vue会自动重新渲染组件的DOM结构,从而保证View视图展示的数据和Model数据源保持一致。

当组件被重新渲染完毕之后,会自动调节updated生命周期函数。

<template>
  <div>
    life---{{count}}
    <button @click="count+=1">+1</button>
  </div>
</template>

<script>
export default {
  name:'LifeCycle',
  data(){
    return {
      count:0
    }
  },
  // 组件在内存中被创建完毕了
  created(){
    console.log('created:组件在内存中被创建完毕了')
  },
  // 组建第一次被渲染到了页面上
  mounted(){
    console.log('mounted: 组建第一次被渲染到了页面上')
  },
  // 组件被重新渲染完毕了
  updated(){
    console.log('updated:组件被重新渲染完毕了');
  },
  // 组件被销毁完毕了
  unmounted(){
    console.log('unmounted:组件被销毁完毕了')
  }
}
</script>

2.4 组件中主要的生命周期函数

 在实际开发中,created是最常用的生命周期函数!

2.5 组件中全部的生命周期函数

三 组件之间的数据共享

3.1 组件之间的关系

在项目开发中,组件之间的关系分为如下3种:

  1. 父子关系
  2. 兄弟关系
  3. 后代关系

3.2 父子组件之间的数据共享

3.2.1 父组件向子组件共享数据

父组件通过v-bind属性绑定向子组件共享数据。同时,子组件需要使用props接收数据。如下:

父组件App.vue

<template>
  <div>
    app---{{count}}
    <button type="button" class="btn btn-primary" @click="count+=1">+1</button>
    <my-son :num="count"></my-son>
  </div>
</template>

<script>
import MySon from './Son.vue'
export default {
  name:'MyApp',
  data(){
    return {
      count:0
    }
  },
  components:{
    MySon
  }
}
</script>

<style>

</style>

子组件Son.vue

<template>
  <div>
    son---{{num}}
  </div>
</template>

<script>
export default {
  name:'MySon',
  props:['num']
}
</script>

3.2.2 子组件向父组件共享数据

子组件通过自定义事件的方式向父组件共享数据,示例如下:

父组件App.vue

<template>
  <div>
    app---{{count}}
    <button type="button" class="btn btn-primary" @click="count+=1">+1</button>
    <my-son :num="count" @numchange="getNum"></my-son>
  </div>
</template>

<script>
import MySon from './Son.vue'
export default {
  name:'MyApp',
  data(){
    return {
      count:0
    }
  },
  methods:{
    getNum(num){
      this.count=num
    }
  },
  components:{
    MySon
  }
}
</script>

子组件Son.vue

<template>
  <div>
    son---{{num}}
    <button type="button" class="btn btn-primary" @click="add">+1</button>
  </div>
</template>

<script>
export default {
  name:'MySon',
  props:['num'],
  emits:['numchange'],
  methods:{
    add(){
      this.$emit('numchange',this.num+1)
    }
  }
}
</script>

3.2.3 父子组件之间数据的双向同步

父组件在使用子组件期间,可以使用v-model指令维护组件内外数据的双向同步:

<template>
  <div>
    app---{{count}}
    <button type="button" class="btn btn-primary" @click="count+=1">+1</button>
    <hr>
    <my-son v-model:num="count"></my-son>
  </div>
</template>

<script>
import MySon from './Son.vue'
export default {
  name:'MyApp',
  data(){
    return {
      count:0
    }
  },
  methods:{
    getNum(num){
      this.count=num
    }
  },
  components:{
    MySon
  }
}
</script>
<template>
  <div>
    son---{{num}}
    <button type="button" class="btn btn-primary" @click="add">+1</button>
  </div>
</template>

<script>
export default {
  name:'MySon',
  props:['num'],
  emits:['update:num'],
  methods:{
    add(){
      this.$emit('update:num',this.num+1)
    }
  }
}
</script>

3.3 兄弟组件之间的数据共享

兄弟组件之间实现数据共享的方案是EventBus。可以借助于第三方的包mitt来创建eventBus对象,从而实现兄弟组件之间的数据共享。

第一步 安装mitt依赖包 npm install mitt

第二步 创建公共的EventBus模块 创建eventBus.js文件,代码如下

import mitt from 'mitt'
const bus =mitt()
export default bus

第三步 在数据接收方自定义事件 在数据接收方调用bus.on(‘事件名称’,事件处理函数)方法注册一个自定义事件。代码如下:

<template>
  <div>
    <h3>数据接收方——————num的值为:{{ num }}</h3>
  </div>
</template>

<script>
import bus from './eventBus.js'
export default {
  name:"MyRight",
  data(){
    return{
      num:0
    }
  },
  created(){
    // 调用bus.on()方法注册一个自定义事件,通过事件处理函数的形参接收数据
    bus.on('countChange',count=>{
      this.num=count
    })
  }
}
</script>

第四步 在数据发送方触发事件 在数据发送方,调用bus.emit('事件名称',要发送的数据)方法触发自定义事件,代码如下

<template>
  <div>
    <h3>数据发送方----count的值为:{{ count }}</h3>
    <button type="button" class="btn btn-primary" @click="add">+1</button>
  </div>
</template>

<script>
import bus from './eventBus.js'
export default {
  name:"MyLeft",
  data(){
    return {
      count:0
    }
  },
methods:{
  add(){
    this.count++,
    bus.emit('countChange',this.count)
  }
}
}
</script>

最后附上App根组件App.vue的代码,如下:

<template>
  <div>
    App
    <div class="brother-box">
      <!-- 3. 使用组件 -->
      <my-left></my-left>
      <my-right></my-right>
    </div>
  </div>
</template>

<script>
import MyLeft from './Left.vue'
import MyRight from './Right.vue'
export default {
  name:'MyApp',
  components:{
    MyLeft,
    MyRight
  }
}
</script>

<style lang="less" scoped>
.brother-box {
  display: flex;
  > div {
    border: 1px solid #ccc;
    flex: 1;
    margin: 10px;
    padding: 10px;
    height: 300px;
  }
}
</style>

实现效果:

点击左侧按钮,count值+1,并且num值=count值 

3.4 后代关系组件之间的数据共享

后代关系组件之间共享数据,指的是父节点的组件向其子孙组件共享数据。此时组件之间的嵌套关系比较复杂,可以使用provide和inject实现后代关系组件之间的数据共享。

3.4.1 父节点通过provide共享数据

父节点的组件可以通过provide方法,对其子孙组件共享数据:

<template>
  <div>
    <h1>App根组件</h1>
    <hr>
    <level-two></level-two>
  </div>
</template>

<script>
import LevelTwo from './LevelTwo.vue'
export default {
name:"MyApp",
data(){
  return{
    color:'red'
  }
},
provide(){
  // 返回要共享的数据对象
  return {
    color:this.color,
    count:1
  }
},
components:{
  LevelTwo
}
}
</script>

3.4.2 子孙节点通过inject接收数据

子孙节点可以使用inject数组,接收父级节点向下共享的数据。示例代码如下:

子组件

<template>
  <div>
    <h3>level-two二级组件</h3>
    <hr>
    <level-three></level-three>
  </div>
</template>

<script>
import LevelThree from './LevelThree.vue'
export default {
name:'LevelTwo',
components:{
  LevelThree
}
}
</script>

孙组件

<template>
  <div>
    <h5>LevelThree三级组件---{{ color }}--{{ count }}</h5>
  </div>
</template>

<script>
export default {
name:"LevelThree",
inject:['color','count'],
}
</script>

<style>

</style>

3.4.3父节点对外共享响应式的数据

父节点使用provide向下共享数据时,可以结合computed函数向下共享响应式的数据。如下

<template>
  <div>
    <h1>App根组件</h1>
    <button @click="color='blue'">change-color</button>
    <hr>
    <level-two></level-two>
  </div>
</template>

<script>
import { computed } from 'vue';
import LevelTwo from './LevelTwo.vue'
export default {
name:"MyApp",
data(){
  return{
    color:'red'
  }
},
provide(){
  // 返回要共享的数据对象
  return {
    // 使用computed函数,可以把要共享的数据包装为响应式数据
    color:computed(()=>this.color),
    count:1
  }
},
components:{
  LevelTwo
}
}
</script>

3.4.4 子孙节点使用响应式的数据

如果父节点共享的是响应式的数据,则子孙节点必须以.value的形式进行使用。如下

<template>
  <div>
    <h5>LevelThree三级组件---{{color.value}}</h5>
  </div>
</template>

<script>
export default {
name:"LevelThree",
inject:['color'],
}
</script>

3.4.5 vuex

vuex是终极的组件之间的数据共享方案。在企业级的vue项目开发中,vuex可以让组件之间的数据共享变得高效清晰且易于维护。

四、vue3.x中全局配置axios

4.1 为什么要全局配置axios

在实际项目开发中,几乎每个组件中都会用到axios发起数据请求。此时会遇到如下两个问题:

每个组件中都需要导入axios

每次发请求都需要填写完整的请求路径

4.2 如何全局配置axios

在main.js入口文件中,通过app.config.globalProperties全局挂载axios,如下:

import { createApp } from 'vue'
import App from './components/06.network/App.vue'
import './index.css'
import axios from 'axios'
const app=createApp(App)
axios.default.baseURL='https://www.escook.cn'
app.config.globalProperties.$http=axios
app.mount('#app')

发起请求 

<template>
  <div>
    <h3>post</h3>
    <hr>
    <button type="button" class="btn btn-success" @click="PostInfo">发起post请求</button>
  </div>
</template>

<script>
export default {
 name:'PostInfo',
 methods:{
  async PostInfo(){
    const {data:res}=await this.$http.post('/api/post',{name:'zs',age:20})
    console.log(res)
  }
 }
}
</script>

五、ref引用

5.1 什么是ref引用

ref用来辅助开发者在不依赖于jQuery的情况下,获取DOM元素或组件的引用。

每个vue的组件实例上,都包含一个$refs对象,里面存储着对应的DOM元素或组件的引用。默认情况下,组件的$refs指向一个空对象。

5.2 使用ref引用DOM元素

如果想要使用ref引用页面上的DOM元素,则可以按照如下方式操作:

<template>
  <div>
    <h1 ref="myh1">App根组件</h1>
    <hr>
    <button type="button" class="btn btn-primary" @click="getRefs">获取$refs引用</button>
  </div>
</template>

<script>
export default {
name:'MyApp',
methods:{
  getRefs(){
    // console.log(this.$refs)
    this.$refs.myh1.style.color='red'
  }
}
}
</script>

5.3 使用ref引用组件的实例

如果想要使用ref引用页面上的组件实例,可以按照如下方式操作:

<template>
  <div>
    <h1 ref="myh1">App根组件</h1>
    <hr>
    <button type="button" class="btn btn-primary" @click="getRefs">获取$refs引用</button>
    <my-counter ref="counterRef"></my-counter>
  </div>
</template>

<script>
import MyCounter from './Counter.vue'
export default {
name:'MyApp',
methods:{
  getRefs(){
    // console.log(this.$refs)
    // this.$refs.myh1.style.color='red'
    this.$refs.counterRef.reset()
  }
},
components:{
  MyCounter
}
}
</script>
<template>
  <div class="counter-container">
    <h3>Counter组件---{{ count }}</h3>
    <hr>
    <button type="button" class="btn btn-info" @click="count+=1">+1</button>
  </div>
</template>

<script>
export default {
name:'MyCounter',
data(){
  return{
    count:0
  }
},
methods:{
  reset(){
    this.count=0
  }
}
}
</script>


<style lang="less" scoped>
.counter-container {
  margin: 20px;
  padding: 20px;
  border: 1px solid #efefef;
  border-radius: 4px;
  box-shadow: 0px 1px 10px #efefef;
}
</style>

5.4 组件是异步执行DOM更新的

<template>
  <div>
    <h1>App</h1>
    <hr>
    <input ref="ipt" type="text" class="from-control" v-if="inputVisible">
    <button type="button" class="btn btn-primary" v-else @click="showInput">展示input输入框</button>
  </div>
</template>

<script>
export default {
name:'MyApp',
data(){
  return{
    inputVisible:false
  }
},
methods:{
  showInput(){
    this.inputVisible=true
    this.$refs.ipt.focus()
  }
}
}
</script>

<style lang="less" scoped>
input.form-contorl{
  width: 280px;
  display: inline;
}
</style>

以上代码在点击按钮后,并不能执行focus()方法,因为this.$refs.ipt是undefined,在执行到该步骤时,input还没有被渲染

5.5 了解$nextTick函数的作用

组件的$nextTick(cb)方法,会把cb回调推迟到下一个DOM更新周期之后执行。通俗的说:等组件的DOM异步地重新渲染完成后,再执行cb回调函数。从而保证cb回调函数可以操作到最新的DOM元素。将5.4中的showInput方法作如下修改,解决报错问题。

methods:{
  showInput(){
    this.inputVisible=true
    this.$nextTick(()=>{
      this.$refs.ipt.focus()
    })
    
  }
}

六、动态组件

6.1 什么是动态组件

动态组件指的是动态切换组件的显示与隐藏。vue提供了一个内置的<component>组件,专门用来实现组件的动态渲染。

<component>是组件的占位符

通过is属性动态指定要渲染的组件名称

<component is="要渲染的组件名称"></component>

<template>
  <div>
    <h1 class="mb-4">App根组件</h1>
    <button type="button" class="btn btn-primary" @click="comName='MyHome'">首页</button>
    <button type="button" class="btn btn-info m1-2" @click="comName='MyMovie'">电影</button>
    <hr>
    <!-- <my-home></my-home>
    <my-movie></my-movie> -->
    <component :is="comName"></component>
  </div>
</template>

<script>
import MyHome from './Home.vue'
import MyMovie from './Movie.vue'
export default {
name:'MyApp',
data(){
  return{
    comName:'MyHome'
  }
},
components:{
  MyHome,
  MyMovie
}
}
</script>
<template>
  <div>
    <h3>Movie组件---{{ count }}</h3>
    <button type="button" class="btn btn-primary" @click="count+=1">+1</button>
  </div>
</template>

<script>
export default {
name:'MyMovie',
data(){
  return{
    count:0
  }
}
}
</script>

6.2 使用keep-alive保持组件状态

默认情况下,切换动态组件时无法保持组件的状态。此时可以使用vue内置的<keep-alive>组建保持动态组件的状态。如下:

<keep-alive>
      <component :is="comName"></component>
</keep-alive>

七 插槽

7.1 什么是插槽

插槽(Slot)是vue为组件的封装者提供的能力。允许开发者在封装组件时,把不确定的、希望由用户指定的部分定义为插槽。

7.2 体验插槽的基础用法

在封装组件时,可以通过<slot>元素定义插槽,从而为用户预留内容占位符。示例:

<template>
  <div class="com-container">
    <h3>MyCom组件----插槽的基础用法</h3>
    <hr>
    <p>这是第一个p标签</p>
     //定义插槽
     <slot></slot>
    <p>这是最后一个p标签</p>
  </div>
</template>

<script>
export default {
name:'MyCom'
}
</script>
<template>
  <div>
    <h1>App根组件</h1>
    <hr>
    <my-com>
//用户定义的插槽内容
      <p>--------</p>
    </my-com>
  </div>
</template>

<script>
import MyCom from './MyCom.vue'
export default {
  components: { MyCom },

}

 

7.2.1 没有预留插槽的内容会被丢弃

如果在封装组件时没有预留任何<slot>插槽,则用户提供的任何自定义内容都会被丢弃。

如果上述代码中将插槽注释,则用户定义的<p>-----</p>不会显示:

 7.2.2 后备内容

封装组件时,可以为预留的<slot>插槽提供后备内容(默认内容)。如果组件的使用者没有为插槽提供任何内容,则后备内容会生效。示例如下:在插槽中输入后备内容,在使用时不提供插槽内容

<template>
  <div class="com-container">
    <h3>MyCom组件----插槽的基础用法</h3>
    <hr>
    <p>这是第一个p标签</p>
     <slot>这是后备内容</slot>
    <p>这是最后一个p标签</p>
  </div>
</template>
<template>
  <div>
    <h1>App根组件</h1>
    <hr>
    <my-com>
      <!-- <p>--------</p> -->
    </my-com>
  </div>
</template>

 7.3 具名插槽

如果在封装组件时需要预留多个插槽节点,则需要为每个<slot>插槽指定具体的name名称。这种带有具体名称的插槽叫做“具名插槽”。没有指定name名称的插槽,会有隐含的名称叫做“default”。

<template>
  <div>
    <!-- 我们希望把页头放到这里 -->
    <header>
      <slot name="header"></slot>
    </header>
    <!-- 我们希望把主要内容放到这里 -->
    <main>
      <slot></slot>
    </main>
    <!-- 我们希望把页脚放到这里 -->
    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

<script>
export default {
  name: 'MyArticle',
}
</script>

<style lang="less" scoped>
header,
main,
footer {
  border: 1px dashed #999;
  margin: 30px;
  padding: 40px;
  position: relative;
  &::before {
    position: absolute;
    right: 5px;
    top: 5px;
    font-style: italic;
  }
}

header::before {
  content: 'header 页头';
}
main::before {
  content: 'main 主体内容';
}
footer::before {
  content: 'footer 页脚';
}
</style>

7.3.1 为具名插槽提供内容

想具名插槽提供内容的时候,我们可以在一个<template>元素上使用v-slot指令,并以v-slot的参数的形式提供其名称。

<my-article>
      <template v-slot:header>
        <h1>滕王阁序</h1>
      </template>
    </my-article>
  </div>
</template>

7.3.2 具名插槽的简写形式

把参数之前的所有内容(v-solt:)替换为字符#。例如v-slot:header可以被重写为#header

<template>
  <div>
    <h1>App 根组件</h1>
    <hr />

    <!-- 使用组件 -->
    <my-article>
      <template #header>
        <h1>滕王阁序</h1>
      </template>
      <template #default>
        <p>豫章故郡,洪都新府。</p>
        <p>星分翼轸,地接衡庐</p>
        <p>襟三江而带五湖,控蛮荆而引瓯越。</p>
      </template>
      <template #footer>
        <p>落款:王勃</p>
      </template>
    </my-article>
  </div>
</template>

<script>
// 导入组件
import MyArticle from './MyArticle.vue'

export default {
  name: 'MyApp',
  components: {
    // 注册组件
    MyArticle,
  },
}
</script>

7.4 作用域插槽

在封装组件的过程中,可以为预留的<slot>插槽绑定props数据,这种带有props数据的<slot>叫做“作用域插槽”。

<template>
  <div>
    <h3>Test</h3>
    <slot :info="infomation"></slot>
  </div>
</template>

<script>
export default {
name:"MyTest",
data(){
  return{
    infomation:{
      phone:'1301216666',
      address:'北京'
    }
  }
}
}
</script>
<template>
  <div>
    <h1>App根组件</h1>
    <my-test>
      <template v-slot:default="scope">
        <p>{{scope.info.address}}</p>
      </template>
    </my-test>
  </div>

</template>

<script>
import MyTest from './MyTest.vue'
export default {
  components: {MyTest},

}
</script>

7.4.1 解构作用域插槽的prop

 <my-test>
      <template v-slot:default="{info}">
        <p>{{info}}</p>
      </template>
    </my-test>

八 自定义指令

8.1 什么是自定义指令

vue提供了v-for v-model等内置指令,除此之外vue还允许开发者自定义指令。

vue中的自定义指令分两类:私有自定义指令,全局自定义指令

8.2 声明私有自定义指令的语法

在每个vue组件中,可以在directives节点下声明私有自定义指令。如下:

<template>
  <div class="home-container">
    <h3 v-color="'red'">MyHome 组件 --- {{ count }}</h3>
    <hr />

    <input type="text" class="form-control" v-focus />
  </div>
</template>

<script>
export default {
  name: 'MyHome',
  directives: {
     // 自定义私有指令
    focus: {
      // 当被绑定的元素插入到DOM中时,自动触发mounted函数
      mounted(el) {
        el.focus() //让被绑定的元素自动获得焦点
       },
     },
  },
}
</script>

8.3 声明全局自定义指令

全局共享的自定义指令需要通过“单页面应用程序的实例对象”进行声明,(在main.js中)示例代码如下:

import { createApp } from 'vue'
import App from './components/07.directive/App.vue'
import './index.css'
import './assets/css/bootstrap.css'


const app=createApp(App)
app.directive('focus',{
  mounted(el){
    el.focus()
  }
})
app.mount('#app')

8.4 updated函数

mounted函数只在元素第一次插入DOM时被调用,当DOM更新时mounted函数不会被触发。updated函数会在每次DOM更新完成后被调用。示例:

import { createApp } from 'vue'
import App from './components/07.directive/App.vue'
import './index.css'
import './assets/css/bootstrap.css'


const app=createApp(App)
app.directive('focus',{
  mounted(el){
    el.focus()
  },
  updated(el){
    el.focus()
  }
})
app.mount('#app')

注意:在vue2的项目中使用自定义指令时,mounted->bind updated->update

8.5 函数简写

如果mounted和updated函数中的逻辑完全相同,可以简写成如下格式:

app.directive('focus',(el)=>{
    el.focus()
  
})

8.6 指令的参数值

在绑定指令时,可以通过“等号”的形式为指令绑定具体的参数值,示例代码:

import { createApp } from 'vue'
import App from './components/07.directive/App.vue'
import './index.css'
import './assets/css/bootstrap.css'


const app=createApp(App)
app.directive('focus',(el)=>{
    el.focus()
  
})
app.directive('color',(el,binding)=>{
  el.style.color=binding.value
})
app.mount('#app')
<template>
  <div class="home-container">
    <h3 v-color="'red'">MyHome 组件 --- {{ count }}</h3>
    <hr />

    <input type="text" class="form-control" v-focus v-color="'cyan'" />
    <button type="button" class="btn btn-primary" @click="count += 1">+1</button>
  </div>
</template>

<script>
export default {
  name: 'MyHome',
  data() {
    return {
      count: 0,
    }
  },
  
}
</script>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小丫么小二郎~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值