VUE基础(五)

一、ref引用

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

 注:

  • 在每个vue实例上,都包含一个$refs对象
  • 默认情况下,组件的$refs指向一个空对象

 1、使用ref引用页面上的DOM元素

 步骤

  1. 为要引用的DOM添加ref属性,并提供引用的名称
  2. 通过this.$refs.引用的名称,可获取DOM元素的引用
<template>
  <div>
    <!-- 为要引用的DOM添加ref属性,并提供引用的名称 -->
    <h1 ref="myh1">App 根组件</h1>

    <button type="button" class="btn btn-primary" @click="getRefs">获取 $refs 引用</button>

  </div>
</template>

<script>


export default {
  name: 'MyApp',
  methods: {
    getRefs() {
      // 通过this.$refs.引用的名称,可获取DOM元素的引用
      console.log(this.$refs.myh11)
      //操作DOM
      this.$refs.myh11.style.color = 'red'
    },
  },
}
</script>

 2、使用ref引用组件

 步骤

  1. 为要引用的组件添加ref属性,并提供引用的名称
  2. 通过this.$refs.引用的名称,可引用组件的实例
  3. 引用到组件的实例后,可以调用组件上的methods方法
<template>
  <div>
   <!--为要引用的组件添加ref属性,并提供引用的名称  -->
    <my-counter ref="counterRef"></my-counter>

    <button type="button" class="btn btn-primary" @click="getRefs">获取 $refs 引用</button>
  
  </div>
</template>

<script>

import MyCounter from './Counter.vue'

export default {
  name: 'MyApp',
  methods: {
    getRefs() {
      // 通过this.$refs.引用的名称,可引用组件的实例
      console.log(this.$refs.counterRef)
      // 引用到组件的实例后,可以调用组件上的methods方法
      this.$refs.counterRef.reset()
    },
  },

  components: {
    MyCounter,
  },
}
</script>

 counter.vue中

<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>

 3、$nextTick方法

用于解决:

DOM更新是异步的,当函数中涉及到更新DOM,并马上利用ref对DOM进行操作时,会undefined的问题

组件的$nextTick(cb)方法,会把cb回调推迟到下一个DOM更新操作之后执行。从而能保证cb回调函数可以操作到最新的DOM元素

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

    <input type="text" class="form-control" v-if="inputVisible" ref="ipt" />
    <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
      console.log(this.$refs.ipt)//此时为undefined
      // 把对input文本的操作,推迟到下次DOM更新之后
      this.$nextTick(() => {
        console.log(this.$refs.ipt)//此时有值
        // 获取到文本框的引用对象,然后调用 focus() 方法
        this.$refs.ipt.focus()
      })
    },
  },
}
</script>

二、动态组件

动态组件,指动态切换组件的显示与隐藏

vue提供了内置的<component>组件,专门用来实现组件的动态渲染

 注:

  • <component>为要动态渲染的组件的占位符
  • 通过is属性动态的指定要渲染的组件名称
<component is="要渲染的组件的名称"></component>

 步骤:

  1. 在data中定义当前要渲染的组件的名称
  2. 通过is属性,动态指定要渲染的组件的名称
  3. 可进行动态切换组件名称操作

 示例:

<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 ml-2" @click="comName = 'MyMovie'">电影</button>
    <hr />

    <!-- 使用组件 通过is属性,动态指定要渲染的组件的名称 -->
    <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>

<style lang="less" scoped></style>

使用 keep-alive保持状态

默认情况下,切换动态组件时,被切换掉的组件会被卸载,无法保持组件的状态(对组件的数据等进行的一些操作),可使用<keep-alive>保持动态组件的状态

    <keep-alive>
      <component :is="组件名"></component>
    </keep-alive>

示例:

<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 ml-2" @click="comName = 'MyMovie'">电影</button>
    <hr />

    <!-- 使用keep-alive保持组件状态 -->
    <keep-alive>
      <component :is="comName"></component>
    </keep-alive>
  
  </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>

三、插槽

在开发者封装组件时,把不确定的、希望由用户指定的部分定义为插槽。

可以把插槽认为是组件封装期间,为用户预留的内容的占位符。

 1、插槽的基础用法

可通过<slot>元素定义插槽,从而为用户预留内容占位符

<template>
  <div class="com-container">
    <p>这是第一个 p 标签</p>
    <!-- 通过slot标签,为用户预留内容占位符 -->
    <slot></slot>
    <p>这是最后一个 p 标签</p>
  </div>
</template>

 注

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

 示例:

App.vue

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

    <!-- 使用组件 -->
    <my-com> 向组件插槽中传递的内容 </my-com>
  </div>
</template>

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

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

Mycount.vue

<template>
  <div class="com-container">
    <p>这是第一个 p 标签</p>
    <!-- 通过slot标签,为用户预留内容占位符 -->
    <slot></slot>
    <p>这是最后一个 p 标签</p>
  </div>
</template>

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

 2、插槽的后备内容

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

<slot>这是后备内容</slot>

  示例:

App.vue

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

    <!-- 使用组件,并未指定插槽内容 -->
    <my-com></my-com>
  </div>
</template>

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

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

Mycount.vue

<template>
  <div class="com-container">
    <p>这是第一个 p 标签</p>
    <!-- 此时页面显示后备内容 -->
    <slot>后备内容 </slot>
    <p>这是最后一个 p 标签</p>
  </div>
</template>

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

 3、具名插槽

在封装组件时,需要预留多个插槽节点,则需要为每个插槽指定具体的name名称,

这种带有具体名称的插槽叫做具名插槽。

 创建具名插槽

 <slot name="header">标题内容</slot>

 向组件标签的内容节点中,插入具名插槽的内容

 <template v-slot:header>
    <h1>标题</h1>
 </template>

 注:

  • 在声明插槽时,若没有指定名称,则会有隐含的名称叫做“default”
  • 只有默认插槽可省略外层的template,插入具名插槽时,template不能被省略
  • v-slot:可简写为#

 示例:

App.vue

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

    <!-- 使用组件 -->
    <my-article>
      <template v-slot:header>
        <h1>标题</h1>
      </template>
      <template #default>
        <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>

Mycount.vue

<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>

 4、作用域插槽

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

 <slot :info="infomation">为插槽动态的传递props数据</slot>

 在使用自定义组件时接收props数据

 <!-- 利用等号接收props数据,名字自定义即可 -->
<template #default="scope">
        <p>{{scope}}</p>
 </template>

 注:

  • scope默认接收的是一个对象,可通过scope.属性名查看具体属性

 解构作用域插槽的prop

  利用解构赋值即可

<template #default="{ msg, info }">
   <p>{{ msg }}</p>
   <p>{{ info.address }}</p>
</template>

四、自定义指令

 当v-for、v-if等内置指令无法满足开发者的需求时,开发者可自定义指令

分类:

  • 私有自定义指令
  • 全局自定义指令

 注:

  • 自定义指令在使用时,必须以v-前缀开头,在声明时,不需要加

 1、私有自定义指令

可在组件中,通过directives节点声明私有自定义指令

 示例:

<template>

  <!-- 使用v-focus自定义事件 -->
  <input type="text" v-focus />

</template>
<script>
export default {
 directives: {
    // 自定义一个私有指令
    //自定义指令名称:{}
    focus: {
      // 当被绑定的元素渲染到DOM中后,自动触发mounted函数
      //el即为当前指令所绑定的DOM元素
      mounted(el) {
        el.focus()
      },
    },
  },
}
</script>

2、全局自定义指令

全局自定义指令需要在main.js中进行声明,全部组件都可使用

 示例:

main.js中

const app = createApp(App)

// 声明全局自定义指令
// app.directive(自定义指令名,配置对象)
app.directive('focus', {
  mounted(el) {
    el.focus()
  },
}) 

其他组件中

 <!-- 使用v-focus自定义事件 -->
  <input type="text" v-focus />

updated函数

mounted函数只在元素第一希插入DOM时被调用,当DOM更新时不会触发

updated函数会在每次DOM更新完成后被调用

 注:

  • 在vue2中使用自定义指令时,两个函数的名称有变化mounted->bind  updated->update
  • 当mounted与 updated逻辑完全相同时,可简写
// 声明全局自定义指令v-focus
// app.directive(自定义指令名,配置对象)
app.directive('focus', {
  mounted(el) {
  //DOM初次渲染时,自动获取焦点
    el.focus()
  },
  updated(el) {
    //DOM更新后,依旧能够自动获取焦点
    el.focus()
  },
}) 

简写形式

app.directive('focus', (el) => {
//在mounted和updated函数中都会触发
  el.focus()
})

 3、指令的参数值

在绑定指令时,可以通过等号的形式为指令绑定具体的参数值

// binding.value接收具体的参数值
app.directive('color', (el, binding) => {
  el.style.color = binding.value
})
   <input type="text" v-color="'cyan'" />
Vue基础Web项目模板下载非常简单,可以按照以下步骤进行: 第一步,打开浏览器,访问Vue官方网站(https://cn.vuejs.org/)。 第二步,点击页面上方的“文档”按钮,进入Vue的文档页面。 第三步,在文档页面的左侧导航栏中,找到“起步 - 快速原型”这一部分。 第四步,在“起步 - 快速原型”部分中,你可以看到一个“下载vue-cli”按钮,点击它。 第步,你将被带到Vue CLI的GitHub页面,这是Vue的一个脚手架工具,用于快速搭建Vue项目。 第六步,滚动页面,找到一个名为“vue-cli 3.x”的链接,点击它。 第七步,你将跳转到Vue CLI 3.x的npm页面,其中包含有关Vue CLI的详细信息和用法。 第八步,翻滚页面,你可以看到一个类似于“npm install -g @vue/cli”的命令,这是用于全局安装Vue CLI的命令。 第九步,打开终端,输入上述命令并执行,等待安装完成。 第十步,安装完成后,在终端中输入“vue create 项目名称”,其中“项目名称”是你想要创建的项目的名称。 第十一步,按照终端中的提示,选择需要的特性、配置和插件,然后等待项目创建完成。 第十二步,项目创建完成后,你就可以在本地磁盘中找到你的项目文件夹,里面包含了一个基础Vue Web项目模板。 总结起来,下载Vue基础Web项目模板只需要通过Vue CLI工具进行项目的创建和初始化,然后你就可以在本地磁盘中找到你的项目文件夹了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值