前端之Vue day 05 父子通信、ref、动态组件、插槽、计算监听属性
阅读原文时间:2023年07月09日阅读:1

因为组件间数据不共享,所以我们要想办法打通父子之间的数据联系

自定义属性:

在父级中,给在使用的子组件标签加一个自定义的属性,因为要用到data,所以要写成
:自定义属性名=''  #注意,不用冒号也能传,但是都是字符串

子组件内注册:

在子组件中,新增一条
props:['自定义属性名','自定义属性名']
用数组套字符串的形式,给父级传过来的自定义属性名注册,这样子组件立刻就可以用了

属性验证:

也可在props的时候,{}内部指定一下数据类型

props:{age:Number,name:String}

注意:

  • 不要和子自己data中的变量名冲突,不然子自己的就用不了了,会优先使用子标签属性上传过来的变量的值(优先用父级传过来的)
  • 自定义属性名时不要用驼峰,会报错

通过自定义事件

给子标签属性加上自定义的事件,比如说@myfunc=’xxxx‘

xxxx是在父类中的方法,先不写

子标签中,可以给一个函数绑定触发子标签自定义事件的方法

比如说子标签中,有一个按钮,触发子标签内的一个函数,我们就可以在这个函数内写方法,触发自定义事件,并且传参
this.$emit('自定义事件名',传的参)

这样,子标签中调用一个子标签的事件,会触发子标签定义的自定义方法,并且把数据传过来,在父标签的自定义方法名字绑定的事件中就可以使用被传出来的参

<body>
<div class="myDiv">
    <h1>我是根</h1>
    <p v-text="hobby">{{hobby}}</p>
    <hr>
    <xixi :age="age" @myfunc="wawawa"></xixi>

</div>

</body>

<script>

    var foo={
        template:'<div><p>我是世界的主宰</p><p>|||||姓名:|||年龄:{{age}}</p>' +
            '<hr> <button @click="childClick">点我发送子组件数据</button></div>',

        data(){
            return{city:'changsha',hobby:['song','dance','ball']}
        },
        methods: {
            childClick(){
                this.$emit('myfunc',this.hobby)
            }
        },
        props:['age']

    }
    var vm = new Vue({
        el: '.myDiv',
        data: {
            name: '李小狼', age: 16,
            show: false,
            city:'shanghai',
            hobby:[]
        },
        methods: {
            wawawa(hobby){
                console.log(hobby)
                this.hobby=hobby
            }
        },

        components:{
            xixi:foo
        }

    })

</script>


通过this.$refs可以拿到标签,对象类型

1.放在普通标签上,拿到标签的dom对象

2.放在组件上,拿到的是组件对象(常用),啥都能点!函数也是!

<child ref="mychild"></child>


methods: {
    handClick() {
    console.log(this.$refs)
        this.$refs.myinput.value='哇,you could really dance'
        this.$refs.mychild.name='小樱'
        this.age=this.$refs.mychild.age
    }

},

// this.$refs.mychild.name='小樱' 控制子组件内部
// this.age=this.$refs.mychild.age 子组件的变量传出来到父组件

​ 想做一个页面,根据不同的操作显示不同的组件

不使用动态组件

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

    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
          integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
</head>
<body>
<div id="mydiv">
    <h1 class="text-center">商城</h1>
    <span>首页</span>|||<span>订单</span>|||<span>商品</span>
    <p></p>
    <button @click="orderClick">点我换到订单页</button>||||||||||||||||<button @click="goodClick">点我换到商品页</button>
    <home v-if="choose==='home'"></home>
    <order v-else-if="choose==='order'"></order>
    <good v-else></good>

</div>
</body>

<script>
    // 定义三个组件
    var home={
        template:'<div><h1>俺是home页面</h1></div>',
        data(){
            return{}
        }
    }
    var order={
        template:'<div><h1>俺是order页面</h1></div>',
        data(){
            return{}
        }
    }
    var good={
        template:'<div><h1>俺是good页面</h1></div>',
        data(){
            return{}
        }
    }

    var vm=new Vue({
        el:'#mydiv',
        data:{
            choose:'home'
        },
        methods:{
        orderClick(){
            this.choose='order'
            console.log(this.choose)
        },
        goodClick(){
            this.choose='good'
            console.log(this.choose)
        }
        },
        components:{
            home,
            order,
            good
        }

    })

</script>
</html>

使用动态组件

<home v-if="choose==='home'"></home>
<order v-else-if="choose==='order'"></order>
<good v-else></good>

上面三行删除,换为
<component :is="choose"></component>

这就是动态匹配,匹配一个变量,变量名是啥,就匹配显示啥组件,别忘了冒号!

keep-alive属性

​ 让用户切换组件时,层级的组件内输入过的文字能活着

var good={
    template:'<div><h1>俺是good页面</h1><br><input type="text" value="点击搜索商品"></div>',
    data(){
        return{}
    }
}

_____________________________________

<keep-alive>
    <component :is="choose"></component>
</keep-alive>

非指定插槽

子组件中设置好插槽,就可以在使用子组件时随意对插槽插入东西

命名插槽

​ 插槽上写name属性,然后想插入的时候,要给插入的标签属性+slot='名字'

方法当属性用,一定要有返回值

只要计算属性的函数内部使用的数据发生变化,就会触发计算函数

只有函数体的相关数据发生变化时才会重新执行计算的函数集合

        computed: {
            sumList() {
                console.log('计算属性函数执行了')
                let total = 0
                for (let num of this.numList) {
                    total += num
                }
                return total
            }
        }

简单理解就是对data数据进行一个change事件绑定,当数据发生变化时会触发一个函数的执行。

new Vue({
    watch:{
        属性名(){
          // 属性变化时触发的代码
        },
    }
})

一个vue组件就是一个文件

Vue-CLI项目搭建

vue脚手架 可以创建vue

vue脚手架必须要按照 node js 解释型语言

 node js 是一门后端语言


props:子中接收属性中传过来的变量名,[‘’]的形式,也可以是{}


1.自定义属性,属性名不能用驼峰,不然搞不了,但是下划线可以或者小横杠-