Vue-组件系统(1)

1、插槽

(1)插槽:slot

//设计组件
<div class="content1">
    <slot></slot>
    <h2>{{contentData.title}}</h2>
</div>

//使用组件
<Content1 :contentData="arr[0]">
    <p>我是插槽插进去的数据</p>
</Content1>

(2)具名插槽:v-slot:插槽名 或 #插槽名

slot,slot-scope过时了 2.6.0使用v-slot

没有指定插槽名就是默认插入到插槽,不给插槽插入数据的话,就会使用组件的slot中的数据​ 插槽名不用使用引号引起来,直接写变量名​ 插入的内容必须是template标签或者组件 不能是原生的元素

//设计组件
<div class="content2">
    <slot></slot>	<!-- 不写插槽名默认插入位置 -->
    <slot name="slot1"></slot>
    <h3>{{contentData.title}}</h3>
    <slot name="slot3">你不给我数据到3号插槽中,我就会默认显示出来</slot><!--不写数据,默认显示数据-->
    <h3>{{contentData.text}}</h3>
    <slot name="slot2"></slot>
</div>

//使用组件
<Content2 :contentData="arr[0]">
    <template v-slot:slot1>
        <img src="../assets/girl.png" />
    </template>
    <template v-slot:slot2>
        <p>我是具名插槽插进去的数据</p>
    </template>
    <p>不写插槽名默认插入位置</p>
</Content2>

2、组件的data 设计成function的用义(重点!!!)

组件和挂载到界面的vm对象的区别,vm挂载到页面上时,触发了钩子函数的,data生成了,页面上使用的数据就是data容器中渲染上去的,所有的vm生成时data得有。

组件是引入和注册以后不一定使用的,比如for循环0次就是组件对象生成了的,但是使用0次,所以组件对象并没有使用自己的data容器去渲染数据,造成资源浪费,解决方案就是懒加载:当使用data时去调用,才生成data对象

组件可以多次使用,每使用一次,函数被调用一次则创建出不同的数据对象,实现同名组件的数据可以相互独立 

3、组件传值(重点!!!)

(1)父向子传值props

//父组件
<Prop :mydata="msg"/>

//子组件
<div>{{mydata}}</div>
<script>
    export default {
        props: ["mydata"]
    }
</script>

(2)子向父传值$emit

通过在父组件上定义自定义事件,在子组件中通过$emit 来触发事件;子组件的事件被触发并传参,事件处理函数可以接收到子组件的数据;事件绑定的事件处理函数在父节点上,故可在事件处理函数中用到子组件的数据值来修改父节点的数据。

//给父组件绑定自定义事件myclick
<SearchBtn @myclick="change" />
<script>
    export default {
        methods:{
            change(arg){
                console.log(arg);
            }
        }
    }
</script>

//子组件
<input type="search" v-model="keywords" /><button @click="send">发表</button>
<script>
    export default {
        methods:{
            send(){
                //子组件用过$emit触发事件传参给父组件
                this.$emit("myclick",{text:this.keywords,time:new Date().toLocaleString()});
            }
        }
    }
</script>

计算属性如果数组里面某个值变换是不能监听到的,只有整个数组变换才能监听到,所以必须加上下面这句

this.goods = [...this.goods];

在自定义组件中,如果想要绑定原生事件,如下所示:

<SearchBtn @click.native="change" />

(3)访问根组件的值$root

访问根组件vm对象,所有的子组件都可以将这个实例作为一个全局 store 来访问或使用,现在有更好的技术vuex代替。

//设置
this.$root.count = this.count;

//访问
this.msg= this.$root.count;

(4)$parent 和$children

$parent 访问父组件对象,直接操作父组件的data数据,不需要再使用属性传值,但是容易出现渲染混乱之后只渲染一个的情况。

this.title = this.$parent.title;

$children​ 访问子组件对象数组,不能保证顺序,也不是响应式的。

this.sondata = this.$children[1].sondata;

(5)$refs

如果在普通的DOM元素上使用,引用指向的就是DOM元素;如果用在子组件上,引用就指向组件实例,可以使用组件的所有方法

<Son :mydata="msg" ref="son" />
<h1 ref="myhe">我是测试数据</h1>
<button @click="getel">点击访问组件或者节点</button>

methods: {
    getel() {
        console.log(this.$refs.son, this.$refs.son.msg);    //Son实例对象
        console.log(this.$refs.myhe);    //dom元素
        this.$refs.son.fn();    //执行Son组件的fn方法
        this.$refs.myhe.style.color = "red";   //dom元素字体变红
    }
}

(6)中央事件总线bus

通过创建一个新的vm对象,专门统一注册事件,供所有组件共同操作,达到所有组件随意隔代传值的效果

//bus.js文件
const install = function(Vue) {
    const Bus = new Vue({
        methods: {
            emit(event, ...args) {
                this.$emit(event, ...args);
            },
            on(event, callback) {
                this.$on(event, callback);
            },
            off(event, callback) {
                this.$off(event, callback);
            }
        }
    });
    //由于这个新的vm放在与界面绑定的那个vm的原型上,因此页面上的所有组件都能通过this.$bus访问这个新vm对象
    Vue.prototype.$bus = Bus;
};
export default install;


//组件文件中:
//任意业务中都可以通过调用来绑定事件,触发事件并传值,和销毁事件 
this.$bus.on(event,callback) 	//绑定事件
this.$bus.off(event,callback) 	//销毁事件
this.$bus.emit(event, ...args)	//触发事件

//示例
//组件1绑定事件:
created() {
    this.$bus.on("myevent", (arg) => {
        console.log(arg)
        this.msg = arg;
    })
}
//组件2触发事件
methods: {    
    send(){        
        this.$bus.emit("myevent","中央控制总线传过来的值")    
    }
}

(7)多层组件传值$attrs/$listeners

$attrs、$listeners可以实现跨级组件通信。$listeners进行事件传递,$attrs进行属性传递。

//爷爷组件
<p>{{msg}}</p>
<One v-bind:title="title" v-bind:title2="title2" v-on:myclick="fn" />
methods: {
    fn(arg) {
        this.msg = arg;
    }
},
  
//父级组件
<Two v-bind="$attrs" v-on="$listeners" />
  
//子级组件
<p>{{$attrs.title}}</p>
<p>{{$attrs.title2}}</p>
<input v-model="v1" type="text" /><button @click="send">点击传给爷爷使用</button>
methods: {
    send() {
        this.$emit("myclick", this.v1)
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值