Vue組件之全局組件與局部組件的使用詳解
組件 (Component) 是 Vue.js 最強大的功能之一。組件可以擴展 HTML 元素,封裝可重用的代碼。在較高層面上,組件是自定義元素,Vue.js 的編譯器為它添加特殊功能。在有些情況下,組件也可以是原生 HTML 元素的形式,以is
特性擴展。個人認為就是一個可以重復(fù)利用的結(jié)構(gòu)層代碼片段。
全局組件注冊方式:Vue.component(組件名,{方法})
eg:
<body> <div id="app"> <my-component></my-component> </div> <div id="app1"> <my-component></my-component> </div> <script> Vue.component("my-component",{ template:"<h1>我是全局組件</h1>" }); new Vue({ el:"#app" }); new Vue({ el:"#app1" }) </script> </body>
渲染結(jié)果:
<div id="app"> <h1>我是全局組件</h1> </div> <div id="app1"> <h1>我是全局組件</h1> </div>
這里需要注意:
1.全局組件必須寫在Vue實例創(chuàng)建之前,才在該根元素下面生效;
eg:
<body> <div id="app"> <my-component></my-component> </div> <div id="app1"> <my-component></my-component> </div> <script> new Vue({ el: "#app" }); Vue.component("my-component", { template: "<h1>我是全局組件</h1>" }); new Vue({ el: "#app1" }) </script> </body>
這樣只會渲染app1根元素下面的,并不會渲染app根元素下面的,并且會報錯。
2.模板里面第一級只能有一個標簽,不能并行;
<body> <div id="app"> <my-component></my-component> </div> <script> new Vue({ el: "#app" }); Vue.component("my-component", { template: "<h1>我是全局組件</h1>" + "<p>我是全局組件內(nèi)標簽</p>" }); new Vue({ el: "#app1" }) </script> </body>
這樣子會報錯,并且只會渲染第一個標簽h1;我們應(yīng)該這樣子寫:
<body> <div id="app"> <my-component></my-component> </div> <script> new Vue({ el: "#app" }); Vue.component("my-component", { template: "<h1>我是全局組件<p>" + "我是全局組件內(nèi)標簽</p></h1>" }); new Vue({ el: "#app1" }) </script> </body>
局部組件注冊方式,直接在Vue實例里面注冊
eg:
<body> <div id="app1"> <child-component></child-component> </div> <script> new Vue({ el: "#app1", components:{ "child-component":{ template:"<h1>我是局部組件</h1>" } } }); </script>
局部組件需要注意:
1.屬性名為components,s千萬別忘了;
2.套路比較深,所以建議模板定義在一個全局變量里,代碼看起來容易一點,如下:(模板標簽比較多的時候,這樣子寫更加簡潔規(guī)整)
<body> <div id="app1"> <child-component></child-component> </div> <script> var child={ template:"<h1>我是局部組件</h1>" }; new Vue({ el: "#app1", components:{ "child-component":child } }); </script> </body>
關(guān)于組件中的其他屬性,可以和實例中的一樣,但是data屬性必須是一個函數(shù):
eg:
<body> <div id="app1"> <child-component></child-component> </div> <script> var child={ template:"<button @click='add2'>我是局部組件:{{m2}}</button>", data:function(){ return {m2:1} }, methods:{ add2:function(){ this.m2++ } } }; new Vue({ el: "#app1", components:{ "child-component":child } }) </script> </body>
顯示結(jié)果:
全局組件和局部組件一樣,data也必須是一個函數(shù):
<body> <div id="app1"> <my-component></my-component> </div> <script> Vue.component("my-component",{ template:"<button @click='add1'>全局組件:{{m1}}</button>", data:function(){ return { m1:10 } }, methods:{ add1:function(){ this.m1++ } } }); new Vue({ el:"#app1" }) </script> </body>
顯示結(jié)果:
當使用 DOM 作為模板時 (例如,將el
選項掛載到一個已存在的元素上),你會受到 HTML 的一些限制,因為 Vue 只有在瀏覽器解析和標準化 HTML 后才能獲取模板內(nèi)容。尤其像這些元素<ul>
,<ol>
,<table>
,<select>
限制了能被它包裹的元素,而一些像<option>
這樣的元素只能出現(xiàn)在某些其它元素內(nèi)部。
自定義組件<my-row>
被認為是無效的內(nèi)容,因此在渲染的時候會導(dǎo)致錯誤。變通的方案是使用特殊的is
屬性:
eg:
<body> <div id="app1"> <ul> <li is="my-component"></li> </ul> </div> <script> Vue.component("my-component",{ template:"<h1>{{message}}</h1>", data:function(){ return { message:"hello world" } } }); new Vue({ el:"#app1" }) </script> </body>
渲染結(jié)果為:
對于全局與局部的作用域問題,我們可以這樣理解,只要變量是在組件內(nèi)部用的,這些變量必須是組件內(nèi)部的,而在外部html結(jié)構(gòu)中引用的變量,都引用的是該掛載下的實例里面的變量
eg:
<body> <div id="app1"> <my-component></my-component> </div> <script> Vue.component("my-component",{ template:"<button @click='add3'>" + "{{message}}</button>", data:function(){ return { message:"hello world" } }, methods:{ add3:function(){ alert("我是局部") } } }); new Vue({ el:"#app1", methods:{ add3:function(){ alert("我是全局") } } }) </script> </body>
彈出框顯示:我是局部
Vue中所謂的全局指的是該掛載下的區(qū)域;
下面這種做法是錯誤的,按我的想法覺得應(yīng)該會彈出:我是全局,但是卻報錯,也就是說組件處于全局下不可以添加默認事件,要用全局的事件函數(shù),必須父子通信
<body> <div id="app1"> <my-component @click="add3"></my-component> </div> <script> Vue.component("my-component",{ template:"<button @click='add3'>" + "{{message}}</button>", data:function(){ return { message:"hello world" } } }); new Vue({ el:"#app1", methods:{ add3:function(){ alert("我是全局") } } }) </script> </body>
額外話題:
1.函數(shù)return后面必須跟返回的內(nèi)容,不能換行寫
eg:
下面這種寫法不會返值回來:
2.Vue和小程序等一樣,采用es6的函數(shù)寫法,this指向是不一樣的
<body> <div id="app1"> <button @click="f">ES5</button> <button @click="f1">ES6</button> </div> <script> new Vue({ el:"#app1", methods:{ f:function(){ console.log(this) }, f1:()=>{ console.log(this) } } }) </script> </body>
結(jié)果:
第一個this指的是Vue實例
第二個this指的是Window
由于它和小程序不一樣,我發(fā)現(xiàn)在data里面this指的是window,在methods里面this才是Vue實例
所以建議大家用es5寫吧
new Vue({ el:"#app1", data:{that:this}, })
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Vue OptionsAPI與CompositionAPI的區(qū)別與使用介紹
OptionsAPI和CompositionAPI是Vue.js框架中兩種不同的組件編寫方式,OptionsAPI通過對象字面量定義組件,以屬性分隔不同功能,響應(yīng)式數(shù)據(jù)通過data屬性定義,本文給大家介紹Vue OptionsAPI與CompositionAPI的區(qū)別,感興趣的朋友一起看看吧2024-10-10Vue給?elementUI?中的?this.$confirm、this.$alert、?this.$promp
這篇文章主要介紹了Vue給?elementUI?中的?this.$confirm、this.$alert、?this.$prompt添加按鈕的加載效果,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-07-07解決vue組件中使用v-for出現(xiàn)告警問題及v for指令介紹
這篇文章主要介紹了解決vue組件中使用v-for出現(xiàn)告警問題,在文中給大家介紹了v for指令,需要的朋友可以參考下2017-11-11vue+element-ui+axios實現(xiàn)圖片上傳
這篇文章主要為大家詳細介紹了vue+element-ui+axios實現(xiàn)圖片上傳,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-08-08Vue中@keyup.enter?@v-model.trim的用法小結(jié)
這篇文章主要介紹了Vue中@keyup.enter?@v-model.trim的用法,本文給大家介紹的非常詳細,對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-12-12vue項目下npm或yarn下安裝echarts多個版本方式
這篇文章主要介紹了vue項目下npm或yarn下安裝echarts多個版本方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-06-06vue3結(jié)合ts從零實現(xiàn)vueuse的useRouteQuery方法
這篇文章主要為大家詳細介紹了如何使用vue3與ts從零實現(xiàn)一個類vueuse的useRouteQuery方法,并解決vueuse的useRouteQuery方法存在的一些問題,感興趣的可以了解下2024-03-03