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知识库 -> 组件初始化,父子组件传值,插槽 -> 正文阅读

[JavaScript知识库]组件初始化,父子组件传值,插槽

为什么组件化

  • 扩展 HTML 元素,封装可重用的代码

  • 客户端在公司业务发展的过程中体积越来越庞大,其中堆叠了大量的业务逻辑代码,不同业务模块的代码相互调用,相互嵌套,代码之间的耦合性越来越高,调用逻辑会越来越混乱。当某个模块需要升级的时候,改动代码的时候往往会有牵一发而动全身的感觉。特别是如果工程量出设计的时候没有考虑接口的封装,而将大量的业务代码与功能模块代码混在一起时,将来的升级就需要对代码进行大量修改及调整,带来的功工作量是非常巨大的。这就需要设计一套符合要求的组件之间通信的中间件。模块化可以将代码的功能逻辑尽量封装在一起,对外只提供接口,业务逻辑代码与功能模块通过接口进行弱耦合。

组件注册

1.全局组件

通用过 Vue.component 来创建全局组件,在注册之后可以用在任何新创建的 Vue 根实例 (new Vue) 的模板中,也可以用在任意子组件中,相互之间也可以使用。记住全局注册的行为必须在根 Vue 实例 (通过 new Vue) 创建之前发生

<script>
Vue.component('componentName(组件名,可随意)', {
  // ... 选项 自定义...
  template:`<section style="background:red;">
                <button @click="handleLeft">left</button>
                猫眼电影-{{myname}}
                <child></child>
                <child></child>
            </section>`
  methods:{
                handleLeft(){
                    console.log("left")
                },
            },
computed:{},
watch:{},
//data必须是函数写法
data(){
  return {
     myname:"11111111"
            }
 },
 //局部组件
 components:{
       "child":{
        template:`
              <div>child-{{myname}}</div>
              `,
        data(){
              return {
                myname:"child-11111"
            	}
             }
         }
   }
})
</script>

2.局部组件

可以通过一个普通的 JavaScript 对象来定义组件,然后在 components (Vue中的一个属性)选项中定义你想要使用的组件,也可直接在 components 中定义并使用。对于 components 对象中的每个 property 来说,其 property 名就是自定义元素的名字,其 property 值就是这个组件的选项对象。

<script>
var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }

new Vue({
  el: '#app',
  components: {
    'component-a': ComponentA,
    'component-b': ComponentB
  }
})

//或者
new Vue({
  el: '#app',
  components: {
    "component-a":{ /* ... */ },
    "component-b":{ /* ... */ }
  }
})
</script>

局部注册的组件在其子组件中不可用,若要在子组件A中使用子组件B,则要在A的components 中添加子组件B。

编写组件时要注意:

  • 起名字 :js驼峰命名法, 还可使用html 链接符-
  • template选项中的dom片段 没有代码提示,没有高亮显示,书写时注意漏写错写。
  • css 样式只能写成行内。
  • template 包含一个根节点(root element),该节点不能有兄弟节点。
  • 组件是孤岛,无法直接访问外面的组件的状态或者方法。间接的组件通信来交流。
  • 组件可以有data,methods,computed等Vue有的属性,但自定义的组件 data 必须是一个函数

组件间的通信

1.父传子(props down)

  • 第一步:父组件 在引用子组件时,通过属性绑定(v-bind:)的形式,把需要传递给子组件的数据,传递到子组件内部,供子组件使用 。
  • 第二步:把父组件传递过来的数据, 在子组件的 props数组中定义一下。组件中的所有props 中的数据,都是通过父组件传递给子组件,props中的数据都是只读的,无法重新赋值。可使用属性验证来接收数据,Number,String,Boolean,Array,Object,Function,null(不限制类型):
<div id="box">
	<navbar myname="电影" :myright="false" :myparent="parent">
</div>
<script>
Vue.component("navbar",{
 props:{
       myname:String,
       myright:Boolean
      },
 template:`<div>
        <button>left</button>
        <span>{{myname}}--{{myparent}}</span>  
        <button v-show="myright">right</button>  
      </div>`
    })   
new Vue({
      el:"#box",
      data:{
        parent:"1111111"
      }
    })
 </script>

2.子传父(events up)

  • 在父组件中引入子组件,使用 $on(eventName) 监听事件 ,在子组件中使用 $emit(eventName) 触发事件,可以将子组件的数据当做参数传递给父组件。
  • 具体参考以下代码:
<div id="box">   
    <navbar  @myevent="handleEvent"></navbar>
    <sidebar v-show="isShow" ></sidebar>
</div>
<script>
    Vue.component("navbar", {
      template: `
        <div style="background-color: red;">
          <button @click="handleClick()">点击</button>-导航栏
        </div>
      `,
      methods:{
        handleClick(){
          // console.log("子传父, 告诉父组件 ,取反您的isShow")
          this.$emit("myevent",1000000000)
        }
      }
    })

    Vue.component("sidebar", {
      template: `
      <div style="background-color: yellow"> 
          <li>11111</li>
          <li>11111</li>
          <li>11111</li>
          <li>11111</li>
        </ul>
      </div> `
    })

    new Vue({
      el: "#box",
      data: {
        isShow: true
      },
      methods:{
        handleEvent(data){
          console.log("父组件的定义的事件",data)
          this.isShow = !this.isShow
        }
      }

    })
  </script>

3.组件refs

JavaScript中需要通过document.querySelector("#demo")来获取dom节点,然后再获取这个节点的值。在Vue中,我们不用获取dom节点,元素绑定ref之后,直接通过this.$refs即可调用,这样可以减少获取dom节点的消耗。

ref 介绍

ref 被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向该子组件实例。

通俗的讲,ref 特性就是为元素或子组件赋予一个ID引用,通过this.$refs.refName来访问元素或子组件的实例,相当于父子组件卖你对面通信。

this.$refs介绍

this.$refs是一个对象,持有当前组件中注册过 ref特性的所有 DOM 元素和子组件实例

注意$refs只有在组件渲染完成后才填充,在初始渲染的时候不能访问它们,并且它是非响应式的,因此不能用它在模板中做数据绑定。

接下来看一个实例:

<div id="box>
  <button @click=""handelAdd>add</button>
  <child ref="myChild"></child>
</div>
<script>
	Vue.component("child",{
	  data(){
		return{
				myName:"child--111"
				}
			},
	  template:`<div>
          child---{{myName}}  
        </div>`
	  })

	new Vue({
		el: "box",
		methods:{
		handelAdd(){
		this.refs.myChild.myName = "child--222"
		}
		}
})
</script>

4.中央事件总线(bus,兄弟间通信)

利用一个空的vue实例作为中央事件总线(bus),这样无论是组件树的哪一层都能通信到,使用$emit, $on, $off 分别来触发、监听、取消监听事件, 在mounted生命周期中进行监听。

案例:

<div id="box">
      <child1></child1>
      <child2></child2>
</div>
<script>
	var bus = new Vue()
	Vue.component("child1",{
          template:`
            <div>child1</div>
          `,
     mounted(){
            //8个生命周期中一个,组件上树后触发
            bus.$on("kerwin",(data)=>{
              console.log("child1监听的函数",data)
            })
          }
        })
     Vue.component("child2",{
          template:`
            <div>child2
              <button @click="handleClick">click</button>  
            </div>
          `,
          methods:{
            handleClick(){
              bus.$emit("kerwin","111111111")
            }
          }
        })
var vm = new Vue({
          el:"#box",
          methods: {
          }
        })
</script>

5.补充 动态组件

  • component 元素(标签),动态地绑定多个组件到它的 is 属性
  • keep-alive 保留状态,避免重新渲染在这里插入图片描述

slot 插槽(内容分发)

  • 混合父组件的内容与子组件自己的模板,进行内容分发 。
  • 父组件模板的内容在父组件作用域内编译;子组件模板的内容在子组件作用域内编译
  • slot 元素作为组件模板之中的内容分发插槽。在调用该组件时slot元素自身将被替换。
  • 插槽的意义 : 扩展组件能力, 提高组件的复用性

插槽使用情况:

  • 子组件访问不到父作用域的时候,可以先把该内容拿出来,在子组件中留好插槽就行。
  • 要做一些可复用的组件,但不知道使用者要轮播什么或者做什么列表的时候,也留好插槽就行。

单个插槽

<slot></slot>
  • 假如子组件没有slot插槽,父组件的内容将被会丢弃

  • 假如子组件只有一个插槽,并且这个slot没有属性,那么父组件的所有包含在自定义组件标签里面的内容将插入到slot所在的位置,slot标签消失

  • 假如自定义组件标签里面没有内容,就会显示slot里面的备用内容

<div>
 <navbar>
 	<button @click="isShow = !isShow">show/hide<button>
 	<!--控制sidebar的隐藏与显示,isShow是父组件的属性-->
 </navbar>
 <sidebar v-show="isShow"> </sidebar>
</div>
<script>
	Vue.component("navbar",{
	template:`<div>
		navbar
		<slot></slot>
		</div>`
		}
</script>

具名slot插槽

有时我们需要多个插槽,slot 元素有一个特殊的 属性:name。这个 属性可以用来定义额外的插槽,不带 name 的 <slot> 出口会带有隐含的名字“default”。

<hello>
	<div slot="a">aaa</div>
	<div slot="b">bbb</div>
</hello>
<script>
	Vue.component("hello",{
	template:`<div>
		<div style="background:yellow"> 第一部分
			<slot name="a"></slot>
		</div>
		<div style="background:red"> 第二部分
			<slot name="b"></slot>
		</div>
		</div>`
		}
</script>
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章           查看所有文章
加:2021-09-22 14:35:15  更:2021-09-22 14:37:59 
 
开发: 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 20:50:52-

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