1.1 模塊與組件、模塊化與組件化 1.1.1 模塊 理解:向外提供特定功能的 js 程式,一般就是一個 js 文件 為什麼:js 文件很多很複雜 作用:復用 js,簡化 js 的編寫,提高 js 運行效率 1.1.2 組件 理解:用來實現局部(特定)功能效果的代碼集合( html/css/js/i ...
1.1 模塊與組件、模塊化與組件化
1.1.1 模塊
- 理解:向外提供特定功能的
js
程式,一般就是一個js
文件 - 為什麼:
js
文件很多很複雜 - 作用:復用
js
,簡化js
的編寫,提高js
運行效率
1.1.2 組件
- 理解:用來實現局部(特定)功能效果的代碼集合(
html/css/js/image
.....) - 為什麼:一個界面的功能很複雜
- 作用:復用編碼,簡化項目編碼,提高運行效率
1.1.3 模塊化
當應用中的 js
都以模塊來編寫的,那這個應用就是一個模塊化的應用。
1.1.4 組件化
當應用中的功能都是多組件的方式來編寫的,那這個應用就是一個組件化的應用。
1.2 非單文件組件
1.2.1 說明
- 模板編寫沒有提示
- 沒有構建過程,無法將
ES6
轉換成ES5
- 不支持組件的
CSS
- 真正開發中幾乎不用
1.2.2 基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>基本使用</title>
<script src="../js/vue.js"></script>
</head>
<body>
<!--
Vue中使用組件的三大步驟:
一、定義組件(創建組件)
二、註冊組件
三、使用組件(寫組件標簽)
一、如何定義一個組件?
使用 Vue.extend(options) 創建,其中 options 和 new Vue(options) 時傳入的那個 options 幾乎一樣,但也有點區別;
區別如下:
1.el 不要寫,為什麼? ——— 最終所有的組件都要經過一個 vm 的管理,由 vm 中的 el 決定服務哪個容器。
2.data 必須寫成函數,為什麼? ———— 避免組件被覆用時,數據存在引用關係。
備註:使用 template 可以配置組件結構。
二、如何註冊組件?
1.局部註冊:靠 new Vue 的時候傳入 components 選項
2.全局註冊:靠 Vue.component('組件名',組件)
三、編寫組件標簽:
<school></school>
-->
<div id="root">
<!-- <h2>學校名稱:{{schoolName}}</h2>
<h2>學校地址:{{schoolAddress}}</h2>
<h2>學生姓名:{{studentName}}</h2>
<h2>學生年齡:{{studentAge}}</h2> -->
<!-- 第三步:使用組件 -->
<xuexiao></xuexiao>
<hr></hr>
<student></student>
</div>
<div id="root2">
<xuexiao></xuexiao>
<hr></hr>
<student></student>
</div>
<script>
// 阻止 vue 在啟動時生成生產提示
Vue.config.productionTip = false
// 第一步:創建組件
const school = Vue.extend({
template: `
<div>
<h2>學校名稱:{{schoolName}}</h2>
<h2>學校地址:{{schoolAddress}}</h2>
</div>`,
data() {
return {
schoolName: "廈門大學",
schoolAddress: "廈門",
}
}
})
// 第一步:創建組件
const student = Vue.extend({
template: `
<div>
<h2>學生姓名:{{studentName}}</h2>
<h2>學生年齡:{{studentAge}}</h2>
</div>`,
// 組件定義時,一定不要寫 el 配置項,因為最終所有的組件都要被一個 vm 管理,由 vm 決定服務於哪個容器
// el: "#rtoot",
data() {
return {
studentName: "李四",
studentAge: 22,
}
}
})
// 全局註冊組件
Vue.component("xuexiao", school)
Vue.component("student", student)
new Vue({
el: "#root",
data: {
schoolName: "北京大學",
schoolAddress: "北京",
studentName: "張三",
studentAge: 18,
},
// 第二步:註冊組件
components: {
xuexiao: school,
student
}
})
new Vue({
el: "#root2",
data: {
}
})
</script>
</body>
</html>
1.2.3 註意事項
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>幾個註意點</title>
<script src="../js/vue.js"></script>
</head>
<body>
<!--
幾個註意點:
1.關於組件名:
一個單片語成:
第一種寫法(首字母小寫):school
第二種寫法(首字母大寫):School
多個單片語成:
第一種寫法( kebab-case 命名):my-school
第二種寫法(CamelCase 命名):MySchool (需要 Vue 腳手架支持)
備註:
(1).組件名儘可能迴避 HTML 中已有的元素名稱,例如:h2、H2 都不行。
(2).可以使用 name 配置項指定組件在開發者工具中呈現的名字。
2.關於組件標簽:
第一種寫法:<school></school>
第二種寫法:<school/>
備註:不用使用腳手架時,<school/> 會導致後續組件不能渲染。
3.一個簡寫方式:
const school = Vue.extend(options) 可簡寫為:const school = options
-->
<div id="root">
<h2>{{ message }}</h2>
<!-- 寫法一:首字母小寫 -->
<school></school>
<!-- 寫法二:首字母大寫 -->
<School></School>
<!-- 寫法三 -->
<!-- 不用腳手架時,當使用多個組件,會導致後續組件不能渲染 -->
<school />
<school />
</div>
<script>
// 阻止 vue 在啟動時生成生產提示
Vue.config.productionTip = false
// 定義組件
// const school = Vue.extend({
// name: "MySchool",
// template: `
// <div>
// <h2>學校名稱:{{ name }}</h2>
// <h2>學校地址:{{ address }}</h2>
// </div>
// `,
// data() {
// return {
// name: "北京大學",
// address: "北京"
// }
// }
// })
// 定義組件
const school = {
name: "MySchool",
template: `
<div>
<h2>學校名稱:{{ name }}</h2>
<h2>學校地址:{{ address }}</h2>
</div>
`,
data() {
return {
name: "北京大學",
address: "北京"
}
}
}
new Vue({
el: "#root",
data: {
message: "歡迎學習 Vue!"
},
// 註冊組件
components: {
school
}
})
</script>
</body>
</html>
1.2.4 組件的嵌套
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>組件的嵌套</title>
<script src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<!-- <h2>{{ message }}</h2>
<hello></hello>
<school></school> -->
</div>
<script>
// 阻止 vue 在啟動時生成生產提示
Vue.config.productionTip = false
// 定義學生組件
const student = Vue.extend({
template: `
<div>
<h2>學生名稱:{{ name }}</h2>
<h2>學生年齡:{{ age }}</h2>
</div>
`,
data() {
return {
name: "北京大學",
age: 20
}
}
})
// 定義組件
const school = Vue.extend({
name: "MySchool",
template: `
<div>
<h2>學校名稱:{{ name }}</h2>
<h2>學校地址:{{ address }}</h2>
<student></student>
</div>
`,
data() {
return {
name: "北京大學",
address: "北京"
}
},
components: {
student
}
})
// 定義 hello 組件
const hello = Vue.extend({
template: `
<div>
<h2> Hello World </h2>
</div>
`,
})
const app = ({
template: `
<div>
<h2>{{ message }}</h2>
<school></school>
<hello></hello>
</div>
`,
data() {
return {
message: "歡迎學習 Vue!"
}
},
// 註冊組件
components: {
school, hello
}
})
new Vue({
el: "#root",
template: `
<app></app>
`,
// data: {
// message: "歡迎學習 Vue!"
// },
// 註冊組件
components: {
app
}
})
</script>
</body>
</html>
1.2.5 VueComponent
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>VueComponent</title>
<script src="../js/vue.js"></script>
</head>
<body>
<!--
關於VueComponent:
1.school 組件本質是一個名為 VueComponent 的構造函數,且不是程式員定義的,是 Vue.extend 生成的。
2.我們只需要寫 <school/> 或 <school></school>,Vue 解析時會幫我們創建 school 組件的實例對象,即 Vue 幫我們執行的:new VueComponent(options)。
3.特別註意:每次調用 Vue.extend,返回的都是一個全新的 VueComponent
4.關於this指向:
(1).組件配置中:
data 函數、methods 中的函數、watch 中的函數、computed 中的函數 它們的 this 均是【 VueComponent 實例對象】。
(2).new Vue(options)配置中:
data 函數、methods 中的函數、watch 中的函數、computed 中的函數 它們的 this 均是【 Vue 實例對象】。
5.VueComponent 的實例對象,以後簡稱 vc(也可稱之為:組件實例對象)。
Vue的實例對象,以後簡稱vm。
-->
<div id="root">
<school></school>
</div>
<script>
// 阻止 vue 在啟動時生成生產提示
Vue.config.productionTip = false
//定義school組件
const school = Vue.extend({
name: "school",
template:`
<div>
<h2>學校名稱:{{ name }}</h2>
<h2>學校地址:{{ address }}</h2>
<button @click="showName">點我提示學校名</button>
</div>
`,
data(){
return {
name: "北京大學",
address: '北京'
}
},
methods: {
showName(){
// 組件中的 this 是 VueComponent 實例
console.log('showName', this)
}
},
})
const test = Vue.extend({
template: `<span>atguigu</span>`
})
//定義hello組件
const hello = Vue.extend({
template:`
<div>
<h2>{{ msg }}</h2>
<test></test>
</div>
`,
data(){
return {
msg: '你好啊!'
}
},
components:{ test }
})
console.log('@', school)
console.log('#', hello)
// false 說明兩個是不同的 VueComponent 實例
console.log(school === hello);
const vm = new Vue({
el: "#root",
data: {
},
components: {
school, hello
}
})
</script>
</body>
</html>
1.2.6 內置關係
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>一個重要的內置關係</title>
<script src="../js/vue.js"></script>
</head>
<body>
<!--
1.一個重要的內置關係:VueComponent.prototype.__proto__ === Vue.prototype
2.為什麼要有這個關係:讓組件實例對象(vc)可以訪問到 Vue 原型上的屬性、方法。
-->
<div id="root">
<school></school>
<hello></hello>
</div>
<script>
// 阻止 vue 在啟動時生成生產提示
Vue.config.productionTip = false
// 定義 school 組件
const school = Vue.extend({
template: `
<div>
<h2>學校名稱:{{ name }}</h2>
<h2>學校地址:{{ address }}</h2>
</div>
`,
data() {
return {
name: "北京大學",
address: "北京"
}
}
})
const hello = Vue.extend({
template: `
<div>
<h2>Hello World</h2>
</div>
`,
data() {
return {
}
}
})
console.log(school.prototype.__proto__ === Vue.prototype);
new Vue({
el: "#root",
data: {
},
components: {
school, hello
}
})
// 定義一個構造函數
function Demo() {
this.a = 1
this.b = 2
}
const d = new Demo()
// 顯示原型屬性
console.log(Demo.prototype);
// 隱式原型屬性高
console.log(d.__proto__);
console.log(Demo.prototype === d.__proto__);
Demo.prototype.x = 99
console.log(d.__proto__.x);
</script>
</body>
</html>
1.3 單文件組件
1.3.1 一個 .vue
文件的組成( 3 個部分)
-
模板頁面
<template> 頁面模板 </template>
-
JS
模塊對象<script> export default{ data(){ return{} }, methods:{}, computed:{}, components:{} } </script>
-
樣式
<style> 樣式定義 </style>
-
示例代碼
<template> <div> <h2>學生姓名:{{ name }}}</h2> <h2>學生年齡:{{ age }}}</h2> </div> </template> <script> export default { name: "Student", data() { return { name: "張三", age: 18 } } } </script> <style> </style>
1.3.2 基本使用
-
引入組件
<script> import School from "./School.vue"; import Student from "./Student.vue"; export default { name: "App", components: { School, Student, }, }; </script>
-
使用組件標簽
<template> <div> <School></School> <Student></Student> </div> </template>