IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> vue组件的使用和封装 -> 正文阅读

[JavaScript知识库]vue组件的使用和封装

1. 文件目录结构

在这里插入图片描述

  • 在views目录中放页面基础结构的组件
  • 在components里放页面中各个功能模块的组件

2. 使用组件

(1)在页面中单独引用

<template>
  <Nav></Nav>
</template>

<script>
import nav from '@/components/Nav.vue'
export default {
  name: 'Home',
  components: { Nav },
</script>

(2)在全局引用

  • 在mian.js里

注册单个组件

import Nav from '@/components/Nav.vue' 
Vue.component('Nav', Nav) // 全局注册Nav组件

注册所有组件

const components = require.context('./components', true, /\.vue$/);
components.keys().forEach(key => {
  const name = key.match(/\/(\w+?)\.vue$/)[1];
  Vue.component(name, components(key).default);
});

3. 组件传值

(1)父组件向子组件传值

  • 父组件通过绑定自定义属性来实现,v-bind(简写为:)绑定需要传递给子组件的值,子组件通过props来接收父组件传递的值。
<!-- 父组件 -->
<Child :name="zhang"></Child>
// 子组件
export default {
 props: {
    name: {
      type: String, // 限制类型
      required: true, // 限制必要性
      default: "", // 指定默认值
    },
  },
}

(2)子组件给父组件传值

// 子组件
<button @click="changeName">改变父组件的name</button> 
export default {
    methods: {
        //子组件的事件
        changeName() {
            this.$emit('handleChange', 'zhang') // 触发父组件中handleChange事件并传参Jack
            // 此处事件名称与父组件中绑定的事件名称要一致
        }
    }
}
// 父组件
<child @handleChange="changeName"></child>
methods: {
    changeName(name) {  // name形参是子组件中传入的值Jack
        this.name = name
    }
}

(3)通过 $parent ,$children,$root 或 $refs 访问组件实例

// 子组件
export default {
  data () {
    return {
      title: '子组件'
    }
  },
  methods: {
    sayHello () {
        console.log('Hello');
    }
  }
}
// 父组件
<template>
  <child ref="child" />
</template>
<script>
  export default {
    created () {
      // 通过 $ref 来访问子组件
      console.log(this.$refs.child.title);  // 子组件
      this.$refs.child.sayHello(); // Hello
      // 通过 $children 来调用子组件的方法
      this.$children.sayHello(); // Hello 
    }
  }
</script>

(4)$attrs和$listeners

$attrs

  • $attrs在vue的2.40版本以上可使用
  • $attrs,当一个组件没有声明任何 prop 时,$attrs里包含所有父作用域的绑定的自定义属性 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件
  • 如果给组件传递的数据,组件不使用props接收,那么这些数据将作为组件的HTML元素的特性,这些特性绑定在组件的HTML根元素上(可使用inheritAttrs: false取消)
  • inheritAttrs: false的含义是不希望本组件的根元素继承父组件的attribute,同时父组件传过来的属性(没有被子组件的props接收的属性),也不会显示在子组件的dom元素上,但是在组件里可以通过其$attrs可以获取到没有使用的注册属性, ``inheritAttrs: false`是不会影响 style 和 class 的绑定

$listeners

  • $listeners它是一个对象,里面包含了作用在这个组件上的所有监听器
  • 并且可以通过 v-=“$listeners” 传入内部组件
<!-- 父组件 -->
<template>
  <div>
    <HomeHeader
      @toHome="logoCilck"
      :value="22"
      aa="aa"
    ></HomeHeader>
  </div>
</template>
// 子组件
<template>
 <Menu v-bind="$attrs" v-on="$listeners"></Menu>
</template>

export default {
  name: "HomeHeader",
  inheritAttrs: false, // 避免传入的未声明的值绑定到子组件的根元素上
  mounted() {
    console.log(this.$attrs); // {value: 22, aa: 'aa'}
    console.log(this.$listeners) // {toHome: ?}
  },
};
// 孙子组件
export default {
  name: 'Menu',
  mounted() {
    console.log(this.$attrs); // {value: 22, aa: 'aa'}
    console.log(this.$listeners) // {toHome: ?}
  },
};

(5)子组件之间传值

  1. props$emit结合使用,子组件先传给父组件,再由父组件传给另一个子组件。
  2. EventBus

创建一个 EventBus.js 文件,并暴露一个 vue 实例

import Vue from 'Vue'
export default new Vue()

在要传值的文件里导入这个空 vue 实例,绑定事件并通过 $emit 触发事件函数
(也可以在 main.js 中全局引入该 js 文件,我一般在需要使用到的组件中引入)

<template>
    <div>
        <p>姓名: {{ name }}</p>
        <button @click="changeName">修改姓名</button>
    </div>
</template> 
<script>
import { EventBus } from "../EventBus.js"
export default {
 data() {
     return {
         name: 'John',
     }
  },
  methods: {
      changeName() {
          this.name = 'Lily'
          EventBus.$emit("editName", this.name) // 触发全局事件,并且把改变后的值传入事件函数
      }
    }
}
</script>

在接收传值的组件中也导入 vue 实例,通过 $on 监听回调,回调函数接收所有触发事件时传入的参数

import { EventBus } from "../EventBus.js" 
export default {
    data() {
        return {
            name: ''
        }
    },
    created() {
         EventBus.$on('editName', (name) => {
             this.name = name
         })
    }
}

(6)provide,inject

它们需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。

// 父组件
export default {
  provide: { // 它的作用就是将 name 这个变量提供给它的所有子组件。
    name: 'zhang'
  }
}
export default {
  inject: ['name'], // 注入了从父组件中提供的name变量
  mounted () {
    console.log(this.name);  // zhang
  }
}

4. 插槽

  • **slot **
    默认插槽
    插槽就是子组件中的提供给父组件使用的一个占位符,用 表示,父组件可以在这个占位符中填充任何模板代码
    具名插槽
<!-- 子组件 -->
<template>
  <div class= 'button'>
      <button>  </button>
      <slot name='one'> 这就是默认值1</slot>
      <slot name='two'> 这就是默认值2 </slot>
      <slot name='three'> 这就是默认值3 </slot>
  </div>
</template>
<!-- 父组件 -->
<template>
  <div class= 'app'>
     <ebutton> 
        <template v-slot:one> 这是插入到one插槽的内容 </template>
        <template v-slot:two> 这是插入到two插槽的内容 </template>
        <template v-slot:three> 这是插入到three插槽的内容 </template>
     </ebutton>
  </div>
</template>

作用域插槽 ( 父组件 在子组件 处使用子组件 data)

//子组件 : (假设名为:ebutton)
<template>
  <div class= 'button'>
      <button>  </button>
      <slot name= 'one' :value1='child1'> 这就是默认值1</slot>    //绑定child1的数据
      <slot :value2='child2'> 这就是默认值2 </slot>  //绑定child2的数据,这里我没有命名slot
  </div>           
</template>

new Vue({
  el:'.button',
  data:{
    child1:'数据1',
    child2:'数据2'
  }
})
//父组件:(引用子组件 ebutton)
<template>
  <div class= 'app'>
     <ebutton> 
        // 通过v-slot的语法 将插槽 one 的值赋值给slotonevalue 
        <template v-slot:one = 'slotonevalue'>  
           {{ slotonevalue.value1 }}
        </template>
        // 同上,由于子组件没有给slot命名,默认值就为default
        <template v-slot:default = 'slottwovalue'> 
           {{ slottwovalue.value2 }}
        </template>
     </ebutton>
  </div>
</template>
  • $slots
    vm.$slots是一个对象,键名是所有具名slot的名称,加上一个default,而键值则是一个存放VNode节点的数组。
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-06-29 18:55:53  更:2022-06-29 18:57:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 13:43:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码