最近在寫項目的時候,總是遇到在html中使用vue.js的情況,且頁面邏輯較多,之前的項目經驗都是使用腳手架等已有的項目架構,使用.vue
文件完成組件注冊,及組件之間的調用,還沒有過在html中創建組件的經驗,所以借此機會學習總結一下。
方法一:Vue.extend( options )
- 用法:使用基礎 Vue 構造器,創建一個“子類”。參數是一個包含組件選項的對象。data 選項是特例,需要注意 - 在 Vue.extend() 中它必須是函數
- extend 創建的是 Vue 構造器,而不是我們平時常寫的組件實例,所以不可以通過 new Vue({ components: testExtend }) 來直接使用,需要通過 new Profile().$mount('selector選擇器') 來掛載到指定的元素上。
- Vue.extend + vm.$mount 組合
// 借用官網的例子,小小改動了一下
// 在父組件中,創建一個子組件,並調用
<div id='app'>
<button>{{message}}</button>
<div id="mount-point"></div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:"#app",
data:{
message:'父組件'
},
});
// 創建構造器
var Profile = Vue.extend({
template: '<p>{{firstName}} {{lastName}} {{alias}}</p>',
data: function () {
return {
firstName: 'N',
lastName: 'H',
alias: 'Y'
}
}
})
// 創建 Profile 實例,並掛載到一個元素上。
new Profile().$mount('#mount-point')
</script>
方法二:Vue.component( id, [definition] ) + Vue.extend( options )
- 用法:Vue.component()注冊或獲取全局組件。注冊還會自動使用給定的 id 設置組件的名稱
<div id="app">
<!-- 如果要使用組件,直接把組件的名稱以 HTML 標簽的形式,引入到頁面中-->
<todo :todo-data="todoList"></todo>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
// 構建一個子組件
var todoItem = Vue.extend({
template: ` <li> {{ text }} </li> `,
props: ['text']
})
// 構建一個父組件
var todoWarp = Vue.extend({
template: `
<ul>
<todo-item v-for="(item, index) in todoData" v-text="item.text"></todo-item>
</ul>
`,
props: ['todoData'],
// 局部注冊子組件
components: {
//使用 components 定義組件時,若組件名稱使用駝峰命名,則在引用組件時,需要把大寫改為小寫,並且用'-'將單詞連接
todoItem: todoItem
}
})
// 注冊到全局
Vue.component('todo', todoWarp) // 等同於下面這種寫法
Vue.component('todo',Vue.extend({
template : 'xxx',
props:[xxx],
components:'xxx'
}))
new Vue({
el: '#app',
data: {
todoList: [
{ id: 0, text: '工作' },
{ id: 1, text: '學習' },
{ id: 2, text: '休息' }
]
}
})
</script>
方法三:直接使用Vue.component()
<div id="app">
<mycom></mycom>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
Vue.component('mycom',{
template : '<h3>這是使用 Vue.component 創建的組件</h3>'
})
new Vue({
el: '#app'
})
</script>
- 但是這樣寫會有一個問題:在h3標簽后出現另一個標簽,就會出問題,
Vue.component('mycom',{
template : '<h3>這是使用 Vue.component 創建的組件</h3><h3>這是使用 Vue.component 創建的組件</h3>'
})
- 原因:
組件template屬性指向的模板內容,必須有且只能有唯一的一個根元素
- 解決方法: 用唯一的div作為父元素,將多個子元素包裹
方法四:使用Vue.component()
在被控制的 #app 外面使用 template 元素,定義組件的HTML模板結構
<div id="app">
<mycom></mycom>
</div>
<template id="tem1">
<h1>這是 template 元素</h1>
</template>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
Vue.component('mycom', {
template: '#tem1'
});
new Vue({
el: '#app'
})
</script>
方法五:使用Vue.component() + is
<div id="app">
<ul>
<li is="todo-item" v-for="(todo,index) in todos " :title="todo" :key="index" @remove="removeTodo(index)"></li>
</ul>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
Vue.component('todo-item', {
template: `
<li>
{{title}}
<button @click="$emit('remove')">remove</button>
</li>
`,
props: ['title']
})
new Vue({
el: "#app",
data: {
todos: ["eating", "swimming", "reading"]
},
methods: {
removeTodo: function (index) {
this.todos.splice(index, 1)
}
}
})
補充說明一下
is
屬性:
有些 HTML 元素,諸如 ul、ol、table 和 select,對於可以出現在其內部元素是有嚴格限制的。而有些元素,諸如 li、tr 和 option,只能出現在特定的元素內部。這會導致我們使用這些有約束條件的元素時遇到一些問題。例如
<table>
<blog-post-row></blog-post-row>
</table>
這個自定義組件
<table>
<tr is="blog-post-row"></tr>
</table>