vue中全局组件、局部组件、组件通信父传子和子传父以及ref

全局组件

使用

使用 Vue.component('组件名称', { 组件模板对象 })

    <div id="app">
        <!-- 在vue中, 每一个vue实例都是一个根组件, 在根组件中使用自定义的全局组件 -->
       <navbar></navbar>   <!-- 使用全局组件navbar-->
    </div>
    <script>        // 全局组件定义    
        Vue.component("navbar", {
     
     
            template:`
            <div style="background:rgb(146, 146, 240);">
                <button>返回</button>   
                <span>导航栏</span>
                <button>首页</button>
            </div>
            `,     // 模板 
        })
        var app = new Vue({
     
     
            el:"#app",
        })
    </script>

全局组件中的展示数据和绑定事件

component, methods, watch

        Vue.component("navbar", {
    
    
            template:`
            <div style="background:rgb(146, 146, 240);">
                <button @click="handleHack">返回</button>   
                <span>导航栏</span>
                <button @click="handleHome">首页</button>
            </div>
            `,     // 模板 
            methods:{
    
    
                handleHack(){
    
    
                    console.log("返回的按钮")
                },
                handleHome(){
    
    
                    console.log("首页按钮")
                }
            },
            computed:{
    
    

            },
            watch:{
    
    
                
            }
        })

data

  • 在自定义的组件中, data必须是一个函数
    <script>            // 这个名字要按照
        Vue.component("navbar", {
    
    
            template:`
            <div style="background:rgb(146, 146, 240);">
                <button @click="handleHack">返回</button>   
                <span>导航栏</span>  {
     
     { myname }}
                <button @click="handleHome">首页</button>
            </div>
            `,     // 模板 

            data() {
    
    
                return {
    
    
                    myname:"我是组件data"
                }
            },
        })
    </script>

注意

  1. 在给组件起名字的时候, 如果使用啦驼峰写法,那么在使用的使用要使用-链接符
  • 比如:
  • 定义了一个名为 navBar 的组件
  •    Vue.component("navBar", {
          
           template:`<div>***</div>`}
    
  • 那么在使用的时候就应该
  •   <nav-bar></nav-bar>   
    
  1. template模板中只能使用一个根节点
  2. 自定义的组件中, data 必须是一个函数, 数据放在return中

局部组件

  • 局部组件是在全局组件(父组件)中的components中定义
  • 在哪个全局组件中定义就是哪个全局组件的子组件
  • 使用局部组件的时候, 直接在其父组件的模板中使用

使用

        Vue.component("navBar", {
    
    
        	// 父组件(全局组件)
            template:`
            <div style="background:rgb(146, 146, 240);">
                <button @click="handleHack">返回</button>   
                <span>导航栏</span>
                <child></child>
                <button @click="handleHome">首页</button>
            </div>
            `,     // 模板 
            components:{
    
    
                // 局部组件定义在全局组件内部
                "child":{
    
    
                    template:`<div  style="background:red;">我是局部组件</div>`
                }
            },

组件通信

  • 组件中, 每个组件都是独立的, 无法直接访问外面组件的状态和方法, 可以通过间接的组件通信来交流.

父传子

  • 第一步: 使用组件时, 吧组件看成一个自定义的标签(一个dom), 传值的时候先定义一个属性, 比如定义一个 mytitle 属性
  • 第二步: 在组件内部的props列表中, 接收到刚才在组件标签上定义的属性
  • 这时这个传进去的属性就可以咋模板中使用啦
    <div id="app">
        <!-- 第一步: 使用组件时, 吧组件看成一个自定义的标签(一个dom), 传值的时候先定义一个属性, 比如定义一个 mytitle 属性,  -->
       <nav-bar mytitle="首页"></nav-bar>   <br><hr><br>
       <nav-bar mytitle="列表"></nav-bar>   <br><hr><br>
       <nav-bar mytitle="购物车"></nav-bar>  <br><hr><br>
    </div>
    <script>            // 这里名字使用了驼峰命名啦, 所以使用的时候为 nav-bar
        Vue.component("navBar", {
     
     
            template:`
            <div style="background:rgb(146, 146, 240);">
                <button @click="handleHack">返回</button>  
                <span>导航栏 -----{
      
      { mytitle }} </span> 
                <button @click="handleHome">首页</button>  
            </div>
            `,     // 模板 
            // 第二步: 在组件内部的props列表中, 接收到刚才在`组件`标签上定义的属性
            props:["mytitle"],
        })
        var app = new Vue({
     
     
            el:"#app",
        })
    </script>
  • 也可以使用v-bind绑定数据
  • 当需要传入一个bool类型的数据时, 就需要使用v-bind进行数据绑定, 因为直接传入false或者是true, 在js中会解析为字符串, 而字符串的bool类型都为真
  •      <nav-bar mytitle="首页" v-bind:myshow="false"></nav-bar>   <br><hr><br>
         <nav-bar mytitle="列表" v-bind:myshow="true"></nav-bar>   <br><hr><br>
         <nav-bar mytitle="购物车" v-bind:myshow="true"></nav-bar>  <br><hr><br>
    
  • 然后在 prors中接收
  •    props:["mytitle", "myshow"],
    

props

  • 在组件中这个列表里面不仅仅可以放一下定义的属性名, 还可以对这些定义的属性进行数据的约束
  1. 变成一个对象,进行属性验证
    props:{
    
    
      mytitle:String,   			// 会自动验证传入的值是否为字符串, 不是就报错
      myshow:Boolean				// 会自动验证传入的值是否为布偶类型, 不是就报错
     },
  1. 加上一个默认值
	props:{
    
    
		mytitle:{
    
    
			type:String,		// 属性验证
			default:"默认名字"
		},
		myshow:{
    
    
			type:Boolean,
			default:true
		}
	}

子传父

  • 在vue实例中定义一个全局组件, 这个全局组件就是vue实例的子组件, vue实例就是父组件,
  • 子传父, 就是在vue实例之中拿到在子组件的内部的数据
  • 先在子组件身上监听事件, 然后子组件通过this.$emit 触发事件
<div id="app">
    app
    <h1>{
   
   { click_money }}</h1>
    <!-- aaadddccc 是需要跟在子组件中定义分发的名字一样    handleEvent 是在vue实例(父)中定义的事件 -->
   <navbar @aaabbbccc="handleEvent"></navbar>   
</div>
<script>        
    Vue.component("navbar", {
     
     
        template:`
        <div style="background:rgb(146, 146, 240);">
        	<!-- 监听事件, 触发就会把数据分发 -->
            <button @click="handleClick">click</button>   
        </div>
        `,     // 模板 
        methods:{
     
     
            handleClick(){
     
     
                // console.log("click子", this.money)
                // 分发    这个  aaabbbccc 名字可以随便起, 起的什么名用的时候用什么名
                this.$emit("aaabbbccc", this.money)
            },
        },
        data() {
     
     
            return {
     
     
            	// 自组件的数据
                money:99999999999
            }
        },
    })
    var app = new Vue({
     
     
        el:"#app",
        data:{
     
      click_money: 0 },
        methods:{
     
     
            handleEvent(data){
     
     
            	// 父组件中定义的方法, 接收的参数就是子组件传进来的数据
                console.log("根(父)组件中的日志打印", data)
                this.click_money = data
            }
        }
    })
</script>

ref

  • ref 放在标签上, 拿到的是原生节点
  • ref 放在组件上, 拿到的是组件对象, 这样就实现了通信功能
  • ref 是暴力提取子组件中数据, 不建议使用ref 进行修改数据, 因为出错的时候, 不好判断是在哪个地方修改了数据
<body>
    <div id="app">
        <!-- 在组件上使用 ref 命名为aaaaa -->
       <nav-bar ref="aaaaa"></nav-bar>
       <!-- 在标签上使用 ref 命名为 bbbbbb -->
       <input type="text" ref="bbbbbb">   <br>
       <button @click="handleEvent"> 点击按钮获取refs </button>   
    </div>
    <script>        
        Vue.component("navBar", {
     
     
            template:`
            <div style="background:rgb(146, 146, 240);">
                <button>click子组件  我的money:{
      
      { money }}</button>   
            </div>
            `,     // 模板 
            data() {
     
     
                return {
     
     
                    money:99999999999
                }
            },
        })
        var app = new Vue({
     
     
            el:"#app",
            methods:{
     
     
                handleEvent(){
     
            // this.$refs   
                    console.log(this.$refs)
                    console.log("打印子组件中的money的值: ",this.$refs.aaaaa.money)
                }
            }
        })
    </script>
</body>
  • 在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/lxb_wyf/article/details/111464830