web前端技术开发之vue组件基础(二)

kano个人技术博客 web前端开发 1,620 次浏览 没有评论

kano在上一篇关于vue组件基础的个人博客文章中讲了4点关于组件的基础知识点,今天这篇则是一个延续,kano将继续为大家讲解剩下的vue组件知识点。希望能给需要的同学提供一定的帮助。序号也延续上一篇。

vue组件基础

五、通过事件向父组件发送消息

父组件通过向子组件传入props来传递数据和选项,子组件要如何与父组件沟通呢?可以利用自定义事件。

来看一个例子:

<div class="parent-box" :style="pb_obj">
  <zu @make_tall="tall"></zu>
</div>
 
Vue.component('zu', {
  template:
    `<div>
      子组件内容子组件内容子组件内容子组件内容
      <button @click="$emit('make_tall')">增高</button>
    </div>`
});

let app = new Vue({
  el: '#app',
  data: {
    pb_obj: {
      border: '1px solid #ddd',
      padding: '30px',
      height: '50px',
      width: '400px'
    }
  },
  methods: {
    tall() {
      this.pb_obj.height = (parseInt(this.pb_obj.height) + 30) + 'px';
    }
  }
});

子组件中有一个按钮,我们希望在每次点击它时父组件可以增高,问题是我们无法操作父组件,这时kano个人技术博客调用了内建的$emit方法,它的作用是用来触发自定义事件,参数即为自定义参数名。然后像监听普通的事件那样监听这个事件(代码中的@make_tall),然后事件的处理函数实际上是写在父组件中的。

vue组件案例1

vue组件案例2

vue组件案例3

每次点击父组件都会增加30px。

现在每次增加30px是写死在父组件的方法中的,如果增加多少能让子组件决定的话显然更灵活,实际上,$emit可以接受多个参数,而从第二个参数之后即做为可以在监听事件的处理函数中的参数。

<div class="parent-box" :style="pb_obj">
  <zu @make_tall="tall"></zu>
</div>
 
Vue.component('zu', {
  template:
    `<div>
      子组件内容子组件内容子组件内容子组件内容
      <button @click="$emit('make_tall', 10)">增高</button>
    </div>`
});

let app = new Vue({
  el: '#app',
  data: {
    pb_obj: {
      border: '1px solid #ddd',
      padding: '30px',
      height: '50px',
      width: '400px'
    }
  },
  methods: {
    tall(add_height) {
      this.pb_obj.height = (parseInt(this.pb_obj.height) + add_height) + 'px';
    }
  }
});

可以看到$emit的第二个参数为10,这样每次点击增高父组件都会增加10px了,这里只是举一个例子,实际上你当然可以把增加的输入写一个输入框,这样就更加灵活了。

六、在组件上使用v-model

你可能会对这个操作感到迷惑——v-model难道不应该是表单元素的专属么?为了解释这一点,需要先看一下v-model在普通的表单元素上的实现:{

<input v-model="some_text">

实际等价于

<input
    v-bind:value="some_text"
    v-on:input="some_text= $event.target.value"
>

}

在这里,我们似乎发现了一个惊天大咪咪:神奇的v-model原来只是一个语法糖,实际的实现是由操作事件的监听和数据绑定完成的!(当然这个语法糖还是帮助我们省去了不少操作的)

当把v-model用在组件上,则会:

<diy-input
    v-bind:value="some_text"
    v-on:input="some_text = $event"
></diy-input>

理解了这一点,我们就明白v-model是如何在自定义组件上运作的了,为了让v-model在自定义组件上工作正常,我们需要:

1. 将value属性绑定在名为value的props上

2. input事件发生时,触发自定义事件input且传递一个新值作为参数

例:

<my-input v-model="a"></my-input>
Vue.component('my-input', {
  props: ['value'],
  template: `
  <input
    v-bind:value="value"
    v-on:input="input_trans($event)"
  >
`,
  methods: {
    input_trans(e) {
      this.$emit('input', e.target.value.toUpperCase());
    }
  }
});

let app = new Vue({
  el: '#app',
  data: {
    a: 'HELLO'
  },
  methods: {
  }
});

利用上述特性写的一个自定义输入框组件,将输入的内容一律转为大写。

自定义输入框组件

输入:abCDefg

自定义输入框组件

如果大家用过基于vue的组件库,如element,就会发现里面有很多的自定义组件也可以绑定v-model,我们现在知道它们是基于什么原理了。

七、自定义组件插槽

到目前为止,我们写的自定义组件的模板都是写好的html,但是普通的html的开始结束标签内可是可以放东西的。假如我们现在写了一个容器类的自定义组件,里面会放很多内容——难道就只能将内容作为大段的html字符串,然后作为变量插到模板里么?那也太不灵活了!实际上,我们可以通过插槽功能——slot轻松的实现这一点。

<my-wraper :style="wraper_style">
  <div>
    哈哈哈哈哈
  </div>
</my-wraper>

<my-wraper :style="wraper_style">
  <div class="content">
    <h1>这是一篇文章</h1>
    <div>咩哈哈哈呵呵呵红红红红火火恍恍惚惚</div>
  </div>
</my-wraper>
Vue.component('my-wraper', {
  template: `
  <div>
    这是一个容器,下面是内容:<br >
    <slot></slot>
  </div>
`,
  methods: {
    input_trans(e) {
      this.$emit('input', e.target.value.toUpperCase());
    }
  }
});

let app = new Vue({
  el: '#app',
  data: {
    wraper_style: {
      border: '3px solid red',
      marginBottom: '10px',
      padding: '10px',
      width: '300px'
    }
  },
  methods: {
  }
});

所以实际上就是在组件中想要插入内容的地方加入slot,然后就可以在自定义标签中写内容啦。

八、动态组件

kano个人博客曾经遇到过一个需求:循环一个列表,但是列表元素的样式排版有很大的不同——总共有3种样式,所以写了3个组件。这种情况下我们怎么判断循环的时候使用哪个组件呢?用v-if可以解决,但是需要将3个组件都写在页面中,然后根据条件判断,稍显有些混乱。这时候我们就可以使用vue的动态切换组件特性了。

可以使用component元素加上is特性实现这一点:

<component :is="com_name"></component>

com_name是一个已注册的组件的字符串,我们可以在其中加入条件,以返回不同的组件名称,这里就不再举例子了。

以上就是vue组件基础的全部内容了!相信大家通过kano前端技术博客的讲解已经了解了组件的好处,可以使用组件做很多事情了。组件是模块化开发的基础,希望大家可以多多利用。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

Go