1. 內聯模板
即將要說的是一個很有意思的Vue邊界應用。
Vue開發者,通常都有着很敏感的組件規則。 我們寫的組件全部都是以一個個組件組裝到一起的。
當涉及組件之間通信,調用時,會出現各種招數應對各種場景。 如果你要寫一個嵌套組件。
你必然會先創建兩個單獨的組件,然後在其中一個引入註冊另一個(當然,我們剛說過了組件的互相循環調用)。 註冊好之後,爲了我們的組件易於維護。 我們嚴格的分清,什麼應該寫在調用組件中, 哪些內容又應該寫在子組件中,我們會考慮數據怎麼傳遞,嵌套組件的是怎麼協同工作的。
但是,假如,你可以在父組件中,寫子組件的dom呢?
這麼說,可能很疑惑,我一開始因爲完全不明白,因爲這種模式,以往我們從未遇見過。
以下是一個示例,看完就知道了:
//index
<template>
<div>
<Child></Child>
</div>
</template>
<script>
import Child from "./comps/index.vue";
export default {
components: {
Child,
},
};
</script>
<template>
<div>
<p>
<progress :value="count" max="100"> </progress>
</p>
<button @click="count++">click download</button>
</div>
</template>
<script>
export default {
data() {
return {
count: 0,
};
},
};
</script>
這是一個再簡單不過的父子組件了:
我們在子組件中定義了一個進度條元素,這是H5的原生元素,然後我們通過點擊,讓進度條變化。
現在,我們子組將中dom 上<template><template/>
包裹的所有內容,都叫做這個子組件的模板,我們跟習慣叫他dom, 即便它實際上編譯成html文件中真正的dom還需要很複雜底層Vue實現的過程。
Vue 允許我們有一種邊界的應用方式,可以將模板內容不寫在子組件,而寫到父組件中去。
要做到這樣只需要:
- 在父組件中需要調用的地方,給子組件註冊標籤元素,指定
inine-template
屬性,將其標記爲一個行內模板。 - 將子組件中模板內容盡數剪切到
template
元素中間。
即:
//index
<template>
<div>
<Child inline-template>
<div>
<p>
<progress :value="count" max="100"> </progress>
</p>
<button @click="count++">click download</button>
</div>
</Child>
</div>
</template>
<script>
import Child from "./comps/index.vue";
export default {
components: {
Child,
},
};
</script>
//Child
<template> </template>
<script>
export default {
data() {
return {
count: 0,
};
},
};
</script>
<style></style>
它完全能夠如期運行。
是不是非常神奇且有意思?
注意,你僅能在<Child></Child>
標籤內方式 該子組件的實例內容。但是不能訪問父組件中的實例內容。 也不能在父組件中訪問這個子組件實例的內容。
這意味着,直接想當然的像下面這樣操作是不行的哦:
<template>
<div>
<Child inline-template>
<div>
<p>
<progress :value="count" max="100"> </progress>
</p>
<!-- vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in render: "TypeError: Cannot read properties of undefined (reading 'toString')" -->
{{ name.toString }}
<button @click="count++">click download</button>
</div>
</Child>
<!-- [Vue warn]: Property or method "count" is not defined -->
<button @click="count++">click download outside</button>
</div>
</template>
<script>
import Child from "./comps/index.vue";
export default {
components: {
Child,
},
data() {
return {
num: 123,
};
},
};
</script>
想想看,是不是表現的就像是,除了把子組件的模板內容換到了父組件中去寫,似乎沒有任何差異?
就是如此,父子組件依然是不能直接互相訪問彼此實例的
是不是想問, 那這樣寫有個球用 ? 我幹嘛還單獨寫個子組件? 直接寫一個組件裏不就好了?
實際上,確實一般情況下是用不着的。 Vue 文檔也提醒我們,這樣使用會讓我們閱讀起來不友好,不易維護,作用域甚至可能會用的很混亂。 但是好處是,如果你的子組件數據處理邏輯很龐大,這麼寫,就可以滿足在父組件中寫子組件模板的同時,又能分隔開來父子組件的數據處理。
用不用是一回事,知不知道是另一回事嘛。
2. X-Template
<script type="text/x-template" />
實際上,這並不是一個官方的MIME type , stackoverflow 有大佬給出瞭如下解釋:
Vue 文檔中,使用了這種特例。
實際上,被標記爲type="text/x-template"
的script 標籤並不會被標準解析執行。
Vue 會在dom渲染後再對其進行額外處理,注意,是Vue 處理。
Vue 提供這樣一個接口的目的是怎麼被使用的?
其實,這是在你不使用webpack 、gulp 等工具的時候纔會用得到,爲了方便在那種模式下在js 中寫模板繁瑣而出現的。 假如組件的template的內容很冗長,如果都在JavaScript裏面拼接腳本,效率是非常低的,因爲不能像寫HTML那樣舒服。因此,Vue 提供了另外一種定義模板的方法:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="Generator" content="EditPlus®">
<meta name="Author" content="">
<meta name="Keywords" content="">
<meta name="Description" content="">
<title>Vue之X-Templates的使用</title>
</head>
<body>
<div id="app">
<my-component></mycomponent>
<script type="text/x-template" id="my-component">
<div>這是組件的內容</div>
</script>
</div>
<!-- 開發環境版本,包含了有幫助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
Vue.component('my-component',{
template:'#my-component'
});
var app = new Vue({
el:'#app'
})
</script>
</body>
參考自 link