[笔记][Vue.js]打开Vue.js世界的大门(11)-压轴登场的组件基础和Props使用方式篇

Hello!大家好!前几天突然看到铁人赛在十月开始,实在来的太快,让小弟我感到非常错愕XD,去年因为害怕所以没有参加,但那时候也立志了今年要参加的决心!所以之后会好好準备那三十篇或以上的文章,Vue.js的更新可能就不会那么频繁,这一次真的真的真的不是偷懒的藉口XD,铁人赛开幕时,再请各位大大多多指教了!


好的,题外话再分隔线以上结束,那来谈谈所谓的组件吧!组件在Vue中是个很重要的应用,所以我会分成几个篇幅来说明,避免一篇文章中的资讯量太大让人看了就想放弃XD。

1.什么是组件?

组件类似于创建一个HTML的标籤,而该标籤的内容是在Vuecomponent属性中设定的,在设定的同时我们他一个名称,该名称能够在所有透过new Vue建立的实体中使用,听起来很抽象吗?让我们来看看以下例子:
HTML

<div id="ex1">    <!--直接下在component中设定的名称为标籤-->    <input-name></input-name></div>

JavaScript

//透过Vue的component创建一个组件,第一个值为该组件的名称,第二个值为组件内容的物件Vue.component('inputName',{    data:()=>{        return {            inputType:'姓名',            place:'Name',        }    },    template:`<div>                  <span>请输入{{inputType}}:</span>                  <input :placeholder="place" />              </div>`})//创建一个Vue的实体let ex1 = new Vue({    el:'#ex1',})

http://img2.58codes.com/2024/201069356pemH4l7ab.jpg
值得注意的有几个地方:

第一个是我在Vue.component('inputName',{...})设定的组件名称和我在HTML标籤中的名称不同,那是因为DOM的标籤只支援短横线命名法,但是Vue.js并不会阻止你在创建组建的时候一定要用短横线命名法,所以即使用驼峰命名法创建新组件,在HTML中还是要把他转成短横线命名法才行。

第二个是Vue.component和其他Vue物件一样,都拥有datamethodscomputedwatch,但是他并不是对某个DOM建立实体,所以他不会有el。此外,data的值必须要是方法的回传值;而回传的是一个物件,这样会让每次创建一个组件实体的时候,都会重新new一个新的data,让每次使用的相同组件都拥有自己独立的data,这个部份可以参考下方的官方例子:
HTML

<div id="demoCounter">    <!--一个组件可多次使用-->    <button-counter></button-counter>    <button-counter></button-counter>    <button-counter></button-counter></div>

JavaScript

Vue.component('button-counter', {  data:function () {    return {      count: 0    }  },  template:`<div>                <button @click="count++">请点我</button>                <span>目前点了{{count}}下</span>            </div>`})let counter = new Vue({    el:'#demoCounter' })

http://img2.58codes.com/2024/20106935ARx7QtmUl3.jpg
上图中重複使用了三次同一个组件,但是他们的count却不是共用,而是独立的。

第三个是上方的例子都是在全域中使用Vue.component('inputName',{...})建立组件,在全域中建立组件的话,不管是在页面中任一个被new Vue过的DOM中都可以使用,但是组件并不是只能在全域中建立而已,他也可以针对某一个Vue物件建立,而用这种方式的话,该组件就只能够在该DOM使用而已,可以看一下下方的例子:
HTML

<!--在被new Vue的DOM使用该组件--><div id="ex1">    <input-name></input-name></div><!--inputName组件并不在ex2的new Vue物件中--><div id="ex2">    <input-name></input-name></div>

JavaScript

//建立一个组件的物件let componentsInputName = {    data:()=>{        return {            inputType:'姓名',            place:'name',        }    },    template:`<div>                  <span>请输入{{inputType}}:</span>                  <input :placeholder="place" />             </div>`}let ex1 = new Vue({    el:'#ex1',    /*在new Vue中也可以使用components属性,      key为组件名称,值为组件内容*/    components:{        inputName:componentsInputName    }})let ex2 = new Vue({    el:'#ex2',})

http://img2.58codes.com/2024/20106935dJnGguiFYk.jpg
在某个Vue物件中创建组件时,就只有对应该物件的DOM中可以使用组件而已,所以上方HTML中第二个div``ex2内虽然也有input-name,但设定的组件并不会出现,因为他只能在id="ex1"DOM中使用。

再来提的是如果要在组件内使用另一个组件该怎么做,其实很简单,只需要在该组件的物件中增加一个components属性,并设定该子组件的资料即可,让我们看看以下的例子:
HTML

<div id="ex1">    <red-div></red-div></div>

JavaScript

//建立一个组件的物件,一个蓝色的divlet componentsBlueDiv = {    data:()=>{        return {           blueStyle:{                height:'50px',                width:'100px',                backgroundColor:'blue',            },        }    },    template:`<div :style="blueStyle"></div>`}//建立一个组件的物件,是红色的divlet componentsRedDiv = {    /*在该组件中用components,    指定一个组件名称blueDiv为上面建立的componentsBlueDiv*/    components:{        blueDiv:componentsBlueDiv,    },    data:()=>{        return {            redStyle:{                height:'100px',                width:'200px',                backgroundColor:'red',            },        }    },    //在template中直接使用上述设定的组件    template:`<div :style="redStyle"><blue-div></blue-div></div>`,}let ex1 = new Vue({    el:'#ex1',    components:{        //所以这时候的redDiv会有componentsBlueDiv和componentsRedDiv两个div        redDiv:componentsRedDiv,    },})

http://img2.58codes.com/2024/20106935A56zKjIeV2.jpg
像上方程式那样设定就能建立一个有父子关係的组件,但是他并不能像以下使用(小弟我一开始这样写,卡到一个天荒地老,拯救我的文章是这篇):

<div id="ex1">    <red-div><blue-div></blue-div></red-div></div>

题外话是看到画面突然发现有点像国旗XD

关于建立组件最后要提的一点是,当组件中不只有一个DOM时,必须包在一个div或任何父元素内,因为每个组件都只能拥有一个根元素,这部分在一开始也卡了很久http://img2.58codes.com/2024/emoticon16.gif

2.透过Props传递数据

好的,出现的东西越来越多,这又是做什么用的呢?先让我们来看看以下程式码:
HTML

<div id="ex1">    <input-name></input-name>    <input-nickname></input-nickname></div>

JavaScript

Vue.component('inputName',{    data:()=>{        return {            inputType:'姓名',            place:'Name',        }    },    template:`<div>                  <span>请输入{{inputType}}:</span>                  <input :placeholder="place" />              </div>`})Vue.component('inputNickname',{    data:()=>{        return {            inputType:'暱称',            place:'Nickname',        }    },    template:`<div>                  <span>请输入{{inputType}}:</span>                  <input :placeholder="place" />              </div>`})let ex1 = new Vue({    el:'#ex1',})

http://img2.58codes.com/2024/201069356yH1lgamys.jpg
虽然只是两个组件,但是他们明明就差不多却因为某些地方不同,就要再另外新建立一个组件,看起来是不是很受不了?这时候我们就需要Props这个属性来协助我们处理这个问题,先看一下加入Props后的程式码:
HTML

<div id="ex1">    <!--在使用组件时可依属性传递参数的值-->    <input-data title="姓名" place="Name"></input-data>    <input-data title="暱称" place="Nicename"></input-data></div>

JavaScript

Vue.component('input-data',{    //使用props接收参数的值,阵列中的值是key对应属性传过来的资料,顺序没关係    props:['title','place'],    //可在组件中直接使用props内的key,会带入组件使用时的属性值    template:`<div>                  <span>请输入{{title}}:</span>                  <input :placeholder="place" />              </div>`})let ex1 = new Vue({    el:'#ex1',})

http://img2.58codes.com/2024/20106935xh3ppjL95K.jpg
最后得到的结果会和上方一样,但是程式码的部分明显的差很多!个人私心认为这个属性还满酷的,主要是在组件的props属性内先设定key值,之后在HTML上使用的时候依照阵列中的key传入值。

但是Don't repeat yourself,重複的事情我们就不做了,所以既然长的差不多,就用迴圈吧!最后加上迴圈v-for的样子:
HTML

<div id="ex1">    <input-data v-for="type in types" :title="type.title" :place="type.place"></input-data></div>

JavaScript

Vue.component('input-data',{    props:['title','place'],    template:`<div>                  <span>请输入{{title}}:</span>                  <input :placeholder="place" />              </div>`})let ex1 = new Vue({    el:'#ex1',    data:{        types:[            {title:'姓名',place:'Name'},            {title:'暱称',place:'Nicename'}        ]    }})

但是这么做的话,当一个组件的key越来越多,使用组件的时候就必须设定更多的属性和值,这个时候我们可以直接对某个key传入整个物件,让我们再重构一下程式:
HTML

<div id="ex1">    <input-data v-for="type in types" :data="type"></input-data></div>

JavaScript

Vue.component('input-data',{    //用data接收阵列内的每一个物件内容    props:['data'],    //传进来的物件会跑进data中,所以data也会是物件    template:`<div>                  <span>请输入{{data.title}}:</span>                  <input :placeholder="data.place" />              </div>`})let ex1 = new Vue({    el:'#ex1',    data:{        types:[            {title:'姓名',place:'Name'},            {title:'暱称',place:'Nicename'}        ]    }})

这几个例子中,使用props简略了JavaScript的部分,接着用v-for和传入data内的整个物件再一次简略了HTML的部分,而实务上每个方式都应该会有适合使用的地方,所以学会运用还是最重要的!

下一篇会继续说明有关组件的事件使用和v-model双向绑定,希望可以把组件基础的部分补完,之后会有组件的进阶篇,那时候一定会更烧脑,不过文章中会尽量把每个讲到的东西都举例出来,让大家不会和我一样因为不熟悉而卡关XD,但是说不定还是会有漏掉的地方,只能请大大们留言指导我一下了,谢谢!


那分隔线下面的地方,也感谢各位大大观看这篇文章,如果以上有理解错误或是解释不清楚的地方,再麻烦留言告诉我,我会尽快修正文章内容的,谢谢大家http://img2.58codes.com/2024/emoticon41.gif


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章