ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

vue之组件与通信

2022-05-03 15:01:05  阅读:112  来源: 互联网

标签:vue 插槽 通信 Vue template 组件 new data


目录

组件化开发基础

组件是什么?有什么用

扩展 HTML 元素,封装可重用的代码,目的是复用
	-例如:有一个轮播,可以在很多页面中使用,一个轮播有js,css,html
	-组件把js,css,html放到一起,有逻辑,有样式,有html

注意事项

1 自定义组件需要有一个root element,一般包裹在一个div中
2 父子组件的data是无法共享
3 组件可以有data,methods,computed....,但是data 必须是一个函数

组件注册方式

1 全局组件
	Vue.component('组件名', {
                template:`html代码`,
        	   // 这里的data必须是方法所以要加() 在return里写变量
                data(){
                    return {
                        变量:值
                    }
                },
                methods:{
					方法(){}
                    }
                }
            },)
2 局部组件  在Vue对象内  和el、data、methods同级写components
	components:{
            '组件名':{
                template:`html代码`,
                data(){
                    return {
                        变量:值
                    }
                },
                methods:{
                    方法(){}
                    }
                }
            },
        }

局部组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
    <Top></Top>  // 在这里调用局部组件
    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    <Bottom></Bottom>
</div>

</body>
<script>
    var vm = new Vue({
        // el  data  methods watch computed 8个生命周期函数
        el: '#app',
        data: {},
        // 定义再这里面的叫局部组件,只能再局部使用,只能再id为app的标签内使用
        components: {
            'Top': {
                template: `<div><h1 style="background: pink;font-size: 60px;text-align: center">{{name}}</h1><hr><button @click="handleC">点我看美女</button>
                    </div>`,
                data() {
                    return {
                        name: "我是头部"
                    }
                },
                methods: {
                    handleC() {
                        alert('美女')
                    }
                },
            },
            'Bottom': {
                template: `<div>
                <hr><h1 style="background: green;font-size: 60px;text-align: center">{{name}</h1>
                    </div>`,
                data() {
                    return {
                        name: "我是尾部"
                    }
                },
            },
        },
    })
</script>
</html>

全局组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
    <top></top>   // 在这里调用全局组件
</div>

</body>
<script>
    // 定义全局组件--->任意位置都可以用
    Vue.component('top', {
            template: `
                <div>
                    <h1 style="background: pink;font-size: 60px;text-align: center">{{name}}</h1>
                    <hr>
                    <button @click="handleC">点我看美女</button>
                </div>
            `,
            data() {
                return {
                    name: "我是头部"
                }
            },
            methods: {
                handleC() {
                    alert('美女')
                }
            },

        },)
    var vm = new Vue({
        // el  data  methods watch computed 8个
        el: '#app',
        data: {},
    })
</script>
</html>

组件通信之父传子(自定义属性)

通过自定义属性实现

步骤:

1.给组件自定义属性绑定一个父中定义的变量eg:

2.在定义组件内写props属性,对应一个数组,数组内包含组件自定义属性名eg: props:['fathername',]

3.这样组件(子)就可以使用Vue对象(父)内的变量啦,实现了通信.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>

<div id="div_id">
	// 给组件自定义属性绑定一个父中的变量
    <top :fathername="headName"></top>
    <hr>
    {{headName}}
    <hr>
    <input type="text" v-model="headName">

</div>

<script>
    Vue.component('top', {
                template:`
                <div><h1 style="background-color: pink;font-size: 60px;text-align: center">{{fathername}}</h1>
                </div>
                `,
                data(){
                    return {
                        name:'我是头部'
                    }
                },
                props:['fathername',]

            },)
    let vm = new Vue({
        el:'#div_id',
        data:{
            headName:'哈哈',
        },
    })
</script>
</body>
</html>

组件通信之子传父(自定义事件)

通过自定义事件实现

步骤:

1.给组件绑定自定义事件对应一个函数eg: <top @myevent="handleRev">

2.在另一个标签上绑定事件通过this.$emit('自定义事件名', 要传递的参数...)来触发其对应函数的执行

3.这样就在Vue对象中获得了组件传来的参数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>

<div id="div_id">
    <top @myevent="handleRev"></top>
    <hr>
    接收到的参数:{{revText}}
</div>

<script>
    Vue.component('top', {
                template:`
                <div><h1 style="background-color: pink;font-size: 60px;text-align: center">{{name}}</h1>
                <input type="text" v-model="text"><button @click="handleSend">点我传数据</button>
                </div>`,
                data(){
                    return {
                        name:'我是头部',
                        text:''
                    }
                },
                methods:{
                    // 触发绑定在该组件上的事件,myevent,然后传参.父组件中会执行事件对应的函数handelRecv
                    handleSend(){
                        this.$emit('myevent', this.text)
                    }
                }
            },)
    let vm = new Vue({
        el:'#div_id',
        data:{
            revText:'',
        },
        methods:{
            handleRev(text){
                // 接收一个参数,赋值给父组件的revText
                this.revText = text
            }
        }
    })
</script>
</body>
</html>

ref属性实现双向通信

ref放在标签上,拿到的是标签对象,可以点属性拿到对应的值
ref放在组件上,拿到的是组件对象,可以点属性拿到对应的值
通过这种方式实现子传父(this.$refs.mychild.text)
通过这种方式实现父传子(调用子组件方法传参数)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<!--    通过ref,获取input的值-->
    <input type="text" ref="mytext">
    <button @click="handleClick">点我</button>
    <child ref="mychild"></child>
</div>
</body>
<script>
    Vue.component('child',{
        template:`<div>child</div>`,
        data(){
            return {
                text:'子组件数据'
            }
        },
        methods:{
            add(){
               console.log('子组件的add方法')
            }
        }
    })
 var vm = new Vue({
        el: '#box',
        data: {

        },
        methods: {
            handleClick() {
                console.log(this)
                //this.$refs.mytext 获取到input控件,取出value值
                console.log(this.$refs.mytext.value)
                console.log(this.$refs.mychild.text)
                // this.$refs.mychild.add()
                this.$refs.mychild.add('传递参数')

            }
        }

    })
</script>
</html>

动态组件和keep-alive

keep-alive:组件不销毁(页面切换之前输入的数据会保留)

component:有个is属性,指定显示的组件是哪个

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>

<div id="div_id">
    <ul>
        <li @click="handleC('index')">首页</li>
        <li @click="handleC('order')">订单</li>
        <li @click="handleC('good')">商品</li>
    </ul>
    <keep-alive>
        <component :is="who"></component>
    </keep-alive>
</div>

<script>
    Vue.component('index', {
        template: `
                <div><h1>我是首页</h1>
                </div>`,
    },)
    Vue.component('order', {
        template: `
                <div><h1>我是订单</h1><input type="text">
                </div>`,
    },)
    Vue.component('good', {
        template: `
                <div><h1>我是商品</h1>
                </div>`,
    },)
    let vm = new Vue({
        el: '#div_id',
        data: {
            who: ''
        },
        methods: {
            handleC(func) {
                this.who = func
            }
        }
    })
</script>
</body>
</html>

image

插槽

插槽就是可以在组件标签中间插入标签或内容,比如我自定义一个index标签,那么直接写是不行的,需要在定义index标签的时候加slot标签就行了

基本使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="box">
    <!-- 不使用插槽写的aaa不会显示,使用就会显示-->
    <child1>aaa</child1>

</div>
</body>
<script>
    var bus = new Vue() //new一个vue的实例,就是中央事件总线
    Vue.component('child1', {
        template: `<div>
          首页
          <slot></slot>
        </div>`,

    })
 var vm = new Vue({
        el: '#box',

    })
</script>
</html>

插槽应用场景1

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="box">
<!--    写了一个轮播组件,用户想轮播什么就放什么-->
    <swiper>
        <p v-for="data in 4">{{data}}</p>
    </swiper>

       <swiper>
           <img :src="data" v-for="data in 5">
    </swiper>

</div>
</body>
<script>
    var bus = new Vue() //new一个vue的实例,就是中央事件总线
    Vue.component('swiper', {
        template: `<div>
          <slot></slot>
        </div>`,

    })
 var vm = new Vue({
        el: '#box',

    })
</script>
</html>

插槽应用场景2

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="box">
    <!--通过插槽实现在一个组件中控制另一个组件的显示隐藏-->
    <navbar> <button @click="isShow=!isShow">点我显示隐藏</button></navbar>

    <swiper v-if="isShow"></swiper>
</div>
</body>
<script>
    Vue.component('navbar', {
        template: `<div>
          navbar
          <slot></slot>
        </div>`,

    })
    Vue.component('swiper', {
        template: `<div>
          <p>111</p>
          <p>222</p>
          <p>333</p>
        </div>`,

    })
    var vm = new Vue({
        el: '#box',
        data:{
            isShow:true
        }
    })
</script>
</html>

具名插槽

具名插槽的意思就是给插槽起名字,然后使用的时候把指定的标签或内容插到指定的插槽中,这样可以指定不同的插槽使用不同的内容

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>

<div id="div_id">
<index>
    <p slot="a">我来替换插槽a</p>
    <div slot="b">我来替换插槽b</div>
</index>

</div>

<script>
    Vue.component('index', {
        template: `
                <div>
                <slot name="a"></slot>
                <h1>我是首页</h1>
                <slot name="b"></slot>
                </div>`,
    },)
    let vm = new Vue({
        el: '#div_id',
        data: {
        },
    })
</script>
</body>
</html>

image

标签:vue,插槽,通信,Vue,template,组件,new,data
来源: https://www.cnblogs.com/zonghan/p/16218388.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有