在html文件中創建並調用vue組件的方法


最近在寫項目的時候,總是遇到在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>

這個自定義組件 會被作為無效的內容提升到外部,並導致最終渲染結果出錯。幸好這個特殊的 is attribute 給了我們一個變通的辦法:

<table>
  <tr is="blog-post-row"></tr>
</table>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM