vue之组件的使用与通信、ref属性、动态标签、插槽

组件

组件就是:扩展 HTML 元素,封装可重用的代码,目的是复用

例如:有一个轮播图,可以在很多页面中使用,一个轮播有js,css,html
组件把js,css,html放到一起,有逻辑,有样式,有html

组件的分类:

  1. 全局组件:可以放在根中,可以在所有组件中使用
  2. 局部组件:只能在当前组件中使用

组件也有8个生命周期钩子

全局组件

elementui,提供给咱们很多全局组件

创建全局组件
注意事项
  1. 变量在data中必须return出去
  2. 组件的使用不能直接写在body中,必须在标签中
  3. 全局组件是使用Vue.component定义的,可以在全局任意组件中使用
模板
<body>
<div>
    <组件名></组件名>
</div>

</body>
<script>
    Vue.component('组件名', {
        template: `组件样式`,
        data(){
            return {
                // 变量必须return出去
                变量名:'变量值',
            }
        },
        // 方法写在里面
        methods:{
            函数(){
                执行体
            }
        }
    })
</script>
实例
<body>
<div>
  <child></child>
</div>

</body>
<script>
    Vue.component('child', {
        template: `<div>
        <button @click="back">后退</button>
        {{ title }}
        <button>前进</button>
        </div>`,
        data(){
            return {
                title:'首页',
            }
        },
        methods:{
            back(){
                console.log('退了')
            }
        }
    })
</script>

局部组件

注意事项
  1. 局部组件是定义在某个组件内,可以定义多个,只能在它父组件中使用,不能到别的地方使用
  2. 局部组件是定义在某个组件内的:components,只能用在当前组件中
  3. 组件可以嵌套定义和使用,局部组件就在组件的嵌套
模板

局部组件也可以直接写在根组件的components,以k:v键值对的形式

<body>
<div id="id">
  <局部组件名></局部组件名>
</div>
</body>
<script>
    let 局部组件名={
        template: `模板样式`,
        data(){
            return {
                变量:"变量值",
            }
        },
        methods:{}
    }

    let vm = new Vue({
        el:'绑定的id或class',
        data:{},
        components:{
            局部组件名
        }
    })
</script>
实例
<body>
<div id="c1">
  <res></res>
</div>
</body>
<script>
    let res={
        template: `<img :src="url" alt="">`,
        data(){
            return {
                url:"http://pic.imeitou.com/uploads/allimg/230331/7-230331110I0.jpg",
            }
        },
        methods:{}
    }

    let vm = new Vue({
        el:'#c1',
        data:{},
        components:{
            res
        }
    })
</script>

组件间通信

  • 父组件被数据传递给子组件
    • 通过自定义属性实现
    • 1.在子组件中自定义属性,使用属性指令绑定父组件的变量
    • 2.在子组件中,使用props接受 ['属性名','属性名2']
      • 如果props是个对象可以通过键值对限制属性的类型props:{属性名:类型}
    • 3.在父组件中,使用子组件时添加属性名即可,<子组件名 :属性="属性名"></子组件名>

  • 子组件把数据传递给父组件
    • 通过自定义事件实现
    • 1.在父组件里给子组件自定义事件<子组件 @父事件="父函数">
    • 2.在子组件中写一个函数,函数中this.$emit('父事件', this.子组件中的变量),执行函数就会传给父组件
    • 3.在父组件中的函数接受,函数(接受参数){执行体},其中接收的参数就是子组件中的变量值

父传子

<body>
<div id="app">
    <h1>组件的使用</h1>
    <hr>
    <lqz :url="url" :myshow="true"></lqz>
    <hr>
</div>
</body>
<script>
    var lqz = {
        template: `
          <div>
          <h1>我是局部组件</h1>
          <img :src="url" alt="" height="400px">
          <button @click="handleCheck">点我看myshow类型</button>
          </div>`,
        data() {
            return {}
        },
        methods: {
            handleCheck() {
                console.log(this.myshow)
                console.log(typeof this.myshow)
            }
        },
        props: ['url', 'myshow']
    }

    // 根组件
    var vm = new Vue({
        el: '#app',
        data: {
            url: 'http://pic.imeitou.com/uploads/allimg/230331/7-230331110I0.jpg',
        },
        components: {
            lqz
        }
    })
</script>

子传父

<body>
<div id="c1">
    <res @namechange="GetUsername"></res>
    子组件的username:{{username}}
</div>
</body>
<script>
    let res={
                template: `<input type="text" v-model="username" @input="handleChange">`,
                data() {
                    return {
                        username:''
                    }
                },
                methods: {
                    handleChange(){
                        console.log('执行改变')
                        this.$emit('namechange',this.username)
                    }
                },
            }
    vm = new Vue({
        el: '#c1',
        data: {
            username:'',
        },
        methods:{
            GetUsername(username){
                console.log(username)
                this.username= username
            }
        },
        components: {
            res,
        },
    })
</script>

ref属性

ref属性,vue提供的,写在标签上

  1. 可以写在普通标签:在vue中使用 this.$refs.名字 拿到dom对象,可以原生操作
  2. 可以写在组件上:在vue中使用 this.$refs.名字 拿到[组件]对象,组件属性,方法直接使用即可

动态组件

在父组件中写一个标签,并在标签中定义一个is标签
<component :is="who"></component>

component标签的is属性等于组件名字,这里就会显示这个组件

案例

点击按钮切换组件

<body>
<div id="c1">
    <button class="btn btn-success" @click="who='home'">主页</button>
    <button class="btn btn-success" @click="who='book'">图书</button>
    <button class="btn btn-success" @click="who='user'">信息</button>
    <hr>
    <component :is="who"></component>
</div>
</body>
<script>
    let home={
                template: `<div>主页</div>`,
            }
    let book={
                template: `<div>图书</div>`,
            }
    let user={
                template: `<div>信息</div>`,
            }

    vm = new Vue({
        el: '#c1',
        data: {
            who:'home'
        },
        methods:{},
        components: {
            home,
            book,
            user
        },
    })
</script>

keep-alive

是一对标签<keep-alive></keep-alive>,将动态组件包裹起来,动态组件保持存活,在使用动态组件的时候保持组件在被切换前的状态

实例
<body>
<div id="c1">
    <button class="btn btn-success" @click="who='home'">主页</button>
    <button class="btn btn-success" @click="who='user'">信息</button>
    <hr>
    <keep-alive> <component :is="who"></component>  </keep-alive>
    
</div>
</body>
<script>
    let home={template: `<div><p>主页</p><p><input type="text"></p></div>`,}
    let user={template: `<div>信息</div>`,}
    vm = new Vue({
        el: '#c1',
        data: {
            who:'home'
        },
        methods:{},
        components: {
            home,
            user
        },
    })
</script>

插槽

一般情况下,编写完1个组件之后,组件的内容都是写死的,需要加数据 只能去组件中修改,扩展性很差

然后就出现了插槽这个概念,只需在组件中添加<slot></slot>,就可以在body的组件标签中添加内容

不具名插槽

使用步骤:

  1. 在组件的html的任意位置,放个标签<slot></slot>
  2. 后期在父组件使用该组件时<子组件名>放内容</子组件名>
  3. 放的内容,就会被渲染到slot标签中,如果slot标签有多个,多个都会渲染

具名插槽

使用步骤:

  1. 组件中可以留多个插槽,命名,在组件slot标签上名义属性
    slot name="字符串"></slot>
  2. 在父组件中使用时,指定某个标签渲染到某个插槽上
    将使用的标签定义属性<p slot="字符串"></p>

实例

<body>
<div id="c1">

    <home>
        <div>不具名插槽</div>
        <div slot="name">具名插槽</div>
    </home>
</div>
</body>
<script>
    let home = {
        template: `<div>
                    <p>主页</p>
                    <slot></slot>
                    <p><input type="text"></p>
                    <slot name="name"></slot>
                    </div>`,
    }

    vm = new Vue({
        el: '#c1',
        data: {
            who: 'home'
        },
        methods: {},
        components: {
            home,
        },
    })
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值