模塊與組件
模塊
- 向外提供特定功能的js程式-- 一般就是一個js檔案
- 作用--復用js、簡化js的撰寫、提高js運行效率
- 模塊化--當應用中的js都是以模塊來撰寫的 -- 這個應用就是一個模塊化的應用
組件
- 用來實作區域(特定)功能效果的代碼集合
- 作用--復用編碼 -- 簡化專案編碼、提高運行效率
- 組件化 -- 當應用中的功能都是以組件來撰寫的 -- 這個應用就是一個組件化的應用
非單檔案組件
一個檔案中包含有n個組件
基本使用
定義組件--創建組件
- 使用Vue.extend(options)創建 -- 其中options和new Vue(options)時的區別
- 不寫el -- 最終所有組件都要經過一個vm的管理 -- 由vm中的el決定服務哪個容器
- data必須寫為函式 -- 避免組件復用時--資料存在參考關系
- 使用template可以配置組件結構
const school = Vue.extend({
template: `
<div>
<h2>學校:{{name}}</h2>
<h2>地址:{{address}}</h2>
</div>
`,
data() {
return {
name: '鄭輕',
address: '鄭州'
}
}
});
//創建student組件
const student = Vue.extend({
template: `
<div>
<h2>姓名:{{name}}</h2>
<h2>年齡:{{age}}</h2>
</div>
`,
data() {
return {
name: 'lhd',
age: 21
}
}
})
注冊組件
- 區域注冊 -- 在new Vue時傳入components選項
- 全域注冊 -- Vue.component('組件名',組件)
//全域注冊
//創建hello組件
const hello = Vue.extend({
template: `
<div>
<h2>{{msg}}</h2>
</div>
`,
data() {
return {
msg: '你好'
}
}
});
//注冊hello組件---全域注冊
// 'hello', hello -- '組件名',創建組件時使用的變數名
Vue.component('hello', hello);
//區域注冊
new Vue({
el: '#root',
//注冊組件--區域
components: {
//school: school -- 組件名,創建組件時使用的變數名
// school: school,--前后一致可簡寫
school,
// student: student
student
}
})
使用組件
- 在body標簽里寫組件標簽
<div id="root">
<!-- 使用組件 -->
<hello></hello>
<hr>
<school></school>
<hr>
<student></student>
</div>
注意事項
組件名
- 一個單詞組成
- 寫法1 -- 首字母小寫
- 寫法2 -- 首字母大寫
- 多個單詞組成
- 寫法1 -- kebab-case命名
- 寫法2 -- CamelCase命名 -- 需要vue腳手架支持
- 組件名盡可能回避HTML中已有的元素名稱
- 可使用name配置項指定組件在開發者工具中呈現的名字
const student = Vue.extend({
name: 'xuesheng',
template: `
<div>
<h2>姓名:{{name}}</h2>
<h2>年齡:{{age}}</h2>
</div>
`,
data() {
return {
name: 'lhd',
age: 21
}
}
})
new Vue({
el: '#root',
components: {
student
}
})

組件標簽
- 寫法1 --
- 寫法2 --
- 不使用腳手架時 --
會導致后續組件不能渲染
<div id="root">
<student />
<student />
<student />
</div>

簡寫方式
const student = Vue.extend(options) -- const student = options
const student = ({
name: 'xuesheng',
template: `
<div>
<h2>姓名:{{name}}</h2>
<h2>年齡:{{age}}</h2>
</div>
`,
data() {
return {
name: 'lhd',
age: 21
}
}
})
組件嵌套
- school里嵌套student
- 先創建student組件 -- 再創建school組件
- school組件內部 -- 定義components屬性
- components內部寫入student組件名
- school組件的template內寫入student標簽
//創建student組件
const student = Vue.extend({
template: `
<div>
<h2>姓名:{{name}}</h2>
<h2>年齡:{{age}}</h2>
</div>
`,
data() {
return {
name: 'lhd',
age: 21
}
}
});
//創建school組件
const school = Vue.extend({
template: `
<div>
<h2>學校:{{name}}</h2>
<h2>地址:{{address}}</h2>
//寫入student標簽
<student></student>
</div>
`,
data() {
return {
name: '鄭輕',
address: '鄭州'
}
},
//寫入components屬性
components: {
student
}
});
需在vm下創建app組件 -- 管理所有的組件
<script>
//創建student組件
const student = Vue.extend({
template: `
<div>
<h2>姓名:{{name}}</h2>
<h2>年齡:{{age}}</h2>
</div>
`,
data() {
return {
name: 'lhd',
age: 21
}
}
});
//創建school組件
const school = Vue.extend({
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>{{msg}}</h2>
</div>
`,
data() {
return {
msg: '你好'
}
}
});
//創建app組件
const app = Vue.extend({
template: `
<div>
<hello></hello>
<hr>
<school></school>
</div>
`,
data() {
return {
msg: '你好'
}
},
components: {
school,
hello
}
});
new Vue({
el: '#root',
template: `
<app></app>
`,
components: {
app
}
})
</script>

VueCpmpotent
以上述代碼為例--分析VueCompotent
school組件本質是一個名為VueCompotent的建構式 -- 是Vue.extend生成的

使用組件時 --只需寫組件標簽 --Vue決議時會自動創建school組件的實體物件
每次呼叫Vue.extend -- 都會回傳一個新的VueCompotent
關于this指向
組件配置中 -- data中的函式、method中的函式、watch中的函式、computed中的函式 -- this均是VueCompotent實體物件
const school = Vue.extend({
template: `
<div>
<button @click='schoolName'>點擊回傳this</button>
</div>
`,
methods: {
schoolName() {
console.log('school', this);
}
}
});

new Vue(options)配置中 -- data中的函式、method中的函式、watch中的函式、computed中的函式 -- this均是Vue實體物件

VueCompotent可簡稱為vc
Vue簡稱為vm
內置關系
- 一個重要的內置關系 -- VueCompotent.prototype._ _proto _ _ = Vue.prototype
- 目的 -- 讓vc可以訪問到vm原型上的屬性和方法

單檔案組件
基本結構

組件內部標簽
- template --- 寫入組件所需結構
<template>
<!-- 組件的結構 -->
<div id="demo">
<h2>學校:{{ name }}</h2>
<h2>地址:{{ address }}</h2>
</div>
</template>
- script --- 寫入組件互動相關內容 --- 通過ES6語法暴露將代碼出去
<script>
// 組件互動相關的代碼--資料、方法等
// export default --- ES6語法-向外暴露 -- 簡寫形式
export default {
name: "School",
data() {
return {
name: "鄭輕",
address: "鄭州",
};
},
};
/* --不用簡寫的形式
const School = Vue.extend({
})
export default School
*/
</script>
- style --- 寫入組件的樣式 --- 沒有可不寫
<style>
/* 組件的樣式 */
#demo {
background-color: aquamarine;
}
</style>
app組件內部結構
- template --- 內部寫入引入的組件標簽
<template>
<!-- 組件的結構 -->
<div>
<School></School>
<Student></Student>
</div>
</template>
- script --- 引入組件
<script>
//引入組件
//檔案后綴可寫可不寫
import School from "./School.vue";
import Student from "./Student.vue";
// 組件互動相關的代碼--資料、方法等
// export default --- ES6語法-向外暴露 -- 簡寫形式
export default {
name: "App",
components: {
School,
Student,
},
};
</script>
js內部結構
- 引入app組件
import App from './App.vue'
new Vue({
el: '#root',
//該標簽可寫入html檔案下的#root下
tempate:`<App></App>`
components: { App }
})
html內部結構
- 引入js檔案
<body>
<div id="root">
//該標簽可寫入js檔案的vm下
<App></App>
</div>
<script src="https://www.cnblogs.com/Liu-h/archive/js/vue.js"></script>
<script src="https://www.cnblogs.com/Liu-h/archive/2023/05/20/main.js"></script>
</body>
Vue腳手架
簡介
- Vue腳手架是Vue官方提供的標準化開發工具
- 最新版本是4
- 檔案 -- https://cli.vuejs.org/zh/
具體步驟
全域安裝 -- npm install -g @vue/cli -- 安裝完后--輸入vue --出現下圖內容表示安裝成功

切換到需要創建vue腳手架的檔案夾下 --- 創建腳手架專案

輸入提示的命令

點擊網址 -- http://localhost:8080/ -- 出現下圖頁面

內部有vue自動創建的helloword組件

腳手架結構

相關檔案
- babel.config.js --- es6轉換為es5代碼
- package.json、package-lock.json --- nodejs
- README.md --- 對專案進行說明解釋 --- 用來寫筆記
命令列輸入 npm run serve 后
- 自動跳到main.js檔案下 --- main.js檔案引入了App.vue組件
- 跳轉到App.vue --App.vue組件下 引入了Student.vue和School.vue
- 跳轉到Student.vue和School.vue檔案
- 之后再跳轉回main.js檔案 -- index.html檔案引入了main.js
- 跳轉至 index.html --- 就可以輸出頁面了
不同版本的vue
- vue.js與vue.runtime.xxx.js的區別
- vue.js -- 完整版vue --- 包含核心功能+模板決議器
- vue.runtime.xxx.js -- 運行版vue --- 只包含核心功能 --- 沒有模板決議器
- 不能使用template配置項
- 需使用render函式接收到的createElement函式去指定具體內容
//該檔案是整個專案的入口檔案
// 引入vue -- 殘缺版vue -- 缺少模板決議器 -- 不能使用template配置項
// 解決方法 -- 1、引入完整版vue 2、使用render函式
// 完整版vue -- vue/dist/vue
import Vue from 'vue'
// 引入app組件 -- 是所有組件的父組件
import App from './App.vue'
// 關閉vue的生產提示
Vue.config.productionTip = false
// 創建vue實體
new Vue({
// 將app組件放入容器中
/**
* render--是一個函式 -- vue自動呼叫 -- render里傳入一個createElement函式--創建具體元素
* createElement('h1','你好') --- 標簽名 ,標簽里的內容
* render(createElement){
* return createElement('h1','你好')
* }
*
* 簡寫為箭頭函式
* render:(createElement)=>{
* return createElement('h1','你好')
* }
* render:createElement=> createElement('h1','你好')
*render:c=> c('h1','你好')
函式內為組件時--只寫一個標簽名就行
render: h => h(App)
*/
render: h => h(App),
// 寫入容器的id --- 相當于 el:'#app'
}).$mount('#app')
修改默認配置
- vue腳手架隱藏了所有webpack相關的配置 -- 查看具體webpack配置
- 執行 vue inspect > output.js --- 查看vue腳手架的默認配置
- vue.config.js--對腳手架進行個性化定制 --- https://cli.vuejs.org/zh
ref屬性
- 用來給元素或子組件注冊參考資訊 --- id的替代者
- 應用在html標簽上獲取的是真實DOM元素 --- 應用在組件標簽上獲取的是組件實體物件
使用方式
<template>
<div>
<h1 v-text="msg" ref="title"></h1>
<button ref="btn" @click="showDom">點擊輸出DOM</button>
<School ref="sch"></School>
</div>
</template>
<script>
import School from "./components/School.vue";
export default {
components: { School },
data() {
return {
msg: "我在學習Vue",
};
},
methods: {
showDom() {
console.log(this.$refs.title); //真實DOM元素
console.log(this.$refs.btn); //真實DOM元素
console.log(this.$refs.sch); //School組件的實體物件--vc
},
},
};
</script>

props配置
讓組件接收外部傳來的資料
- 傳遞資料
//App.vue
<template>
<div>
<Student name="lhd" age="21" sex="女" />
</div>
</template>
- 接收資料
//School.vue
//簡單接收
props: ["name", "age", "sex"],
// 限制型別
// props: {
// name: String,
// age: Number,
// sex: String,
// },
//限制型別、必要性、指定默認值
props: {
name: {
type: String,
required: true,
},
age: {
type: Number,
default: 21,
},
},
-
注意點
-
props是只讀的--Vue底層會監測對props的修改 --- 若進行了修改會發出警告
-
若一定要修改 --- 復制props的內容到data中 --- 修改data中的資料
-
mixin混入
把多個組件共用的配置提取成一個混入物件
使用方法
創建一個js檔案 -- 定義混合
//將該檔案暴露出去
export const mix = {
methods: {
showName() {
alert(this.name);
},
}
}
在需要使用該配置的檔案下引入--區域混入
/引入檔案
import { mix } from "../mix";
//通過mixins配置使用 -- 必須寫為陣列形式
mixins: [mix],
全域混入--在main.js檔案下引入 -- Vue.mixin(mix)
插件
用于增強Vue
本質 -- 包含install方法的一個物件 --- install的第一個引數是Vue -- 第二個以后的引數是插件使用者傳遞的資料
定義插件
export default{
install(Vue){
}
}
添加全域指令
Vue.prototype.hello=() =>{alert('你好呀')}
使用插件
//main.js
//引入插件
import plugin from "./plugin";
//使用插件
Vue.use(plugin);
//Student.vue
<button @click="demo">點擊輸出你好</button>
methods: {
demo() {
this.hello();
},
},

scoped樣式
讓樣式在區域生效 --- 放置沖突
<style scoped>
</style>
組件化編碼流程
-
拆分靜態組件 --- 組件要按功能點拆分,命名不要與html元素沖突
-
實作動態組件 -- 考慮好資料的存放位置,資料是單個組件用還是多個組件用
- 單個組件用 --- 放在組件自身
- 多個組件用 --- 放在所用組件共同的父組件上 - 狀態提升
-
實作互動 --- 從系結事件開始
-
props適用于
- 父組件 --> 子組件 通信
- 子組件 --> 父組件 通信 -- 要求父組件先給子一個函式
- 使用v-model時 -- v-model系結的值不能是props傳過來的值 -- props是不能修改的
- props傳過來的值若是物件型別 -- 修改物件中的屬性時Vue不會報錯 -- 但不推薦
補充--瀏覽器本地存盤
webStrorage
- 存盤大小一般支持5MB左右
- 瀏覽器端通過window.localStorage和window.sessionStorage屬性來實作本地存盤機制
相關API
- .setItem("key","value") --- 接收一個鍵和值作為引數 -- 把鍵值對添加到存盤中 --- 若鍵名存在 -- 更新其對應的值
<button onclick="saveData()">點擊保存一個資料</button>
<button onclick="saveData()">點擊保存一個物件資料</button>
<script>
let person = { name: "wzh", age: 22 };
function saveData() {
localStorage.setItem('name', 'lhd');
localStorage.setItem('p', JSON.stringify(person));
}
</script>


- .getItem('key') --- 接收一個鍵名作為引數 --- 回傳對應的值
<button onclick="readData()">點擊讀取一個資料</button>
function readData() {
console.log(localStorage.getItem('name'));
const result = localStorage.getItem('p');
console.log(JSON.parse(result));
}

- .removeItem('key') --- 接收一個鍵名作為引數 --- 并把該鍵名從存盤中洗掉
<button onclick="deleteData()">點擊洗掉一個資料</button>
function deleteData() {
localStorage.removeItem('name');
}
- .clear() --- 清空存盤中所有資料
<button onclick="clearData()">點擊清空資料</button>
function clearData() {
localStorage.clear();
}
注意
- sessionStorage --- 存盤的內容會隨著瀏覽器視窗關閉而消失
- localStorage --- 存盤的內容需手動清除才能消失
- .getItem('key') --- 若獲取不到對應的value -- getItem的回傳值為null
- JSON.parse(null) --- 結果依然是null
組件自定義事件
- 一種組件間通信的方式 --- 適用于 子組件給父組件傳遞資料
- 使用場景 --- 子組件給父組件傳遞資料---- 要在父組件中給子組件系結自定義事件 --- 事件的回呼在父組件中
- 系結自定義事件
- 方法一 ---- 通過v-on/@
<!-- 通過父組件給子組件系結一個自定義事件--實作子組件給父組件傳遞內容--方法一通過v-on/@ -->
<Student @name="getStudentName" @demo="mul"></Student>
methods: {
getStudentName(name) {
console.log("App收到了學生名", name);
},
//傳遞多個引數
// getStudentName(name, ...params) {
// console.log("App收到了學生名", name, params);
// },
},
- 方法二 ---- 通過ref
<!-- 通過父組件給子組件系結一個自定義事件--實作子組件給父組件傳遞內容--方法二通過ref -->
<Student ref="student"></Student>
mounted() {
// 系結自定義事件
this.$refs.student.$on("name", this.getStudentName);
// 只能使用一次
// this.$refs.student.$on.once("name", this.getStudentName);
},
-
若想讓事件只觸發一次 --- 使用once修飾符或$once方法
-
觸發自定義事件
this.$emit("name", this.name);
- 解綁自定義事件
//解綁單個事件
this.$off("name");
//解綁多個事件
this.$off(["name", "demo"]);
//解綁全部事件
this.$off();
- 組件可系結原生DOM事件 --- 需使用native修飾符
<Student @click.native="mul"></Student>
- 注意
- 通過 ref系結自定義事件時 --- 回呼要么配置在methods中;要么使用箭頭函式;否則this指向會出問題 --- 默認this指向的是被系結自定義事件的組件
全域事件總線
一種組件間通信的方式 --- 適用于任意組件間通信
安裝全域事件總線 ---- 在vm的原型上
new Vue({
...
beforeCreate() {
Vue.prototype.$bus = this
}
})
使用事件總線
接收資料--在接收資料的組件中給$bus系結自定義事件 --- 事件的回呼留在該組件本身
//寫法一
methods: {
getStudentName(name) {
console.log(name);
},
},
mounted() {
this.$bus.$on("stu", this.getStudentName);
},
寫法二
mounted() {
this.$bus.$on("stu", (name) => {
console.log(name);
});
},
提供資料 --- 在需要獲取資料的組件上添加自定義組件
methods: {
sendSchoolName(name) {
this.$bus.$emit("stu", this.name);
},
},
最好在beforeDestroy鉤子中 --- 用$off解綁當前組件所用到的事件
訊息訂閱與發布
- 一種組件間通信的方式 --- 適用于任意組件間通信
- 需使用第三方庫 ---- pubsub-js
- 在需要接收資料和需要傳遞資料的組件上引入該庫 --- import pubsub from "pubsub-js";
- 接收資料 ---- 接收資料的組件需訂閱資訊 --- 訂閱的回呼留在該組件自身
- 最好在beforeDestroy鉤子中 ---- 取消訂閱
mounted() {
this.pubId = pubsub.subscribe("msg", (msgName, data) => {
console.log("訂閱號msg發布了訊息", msgName, data);
});
},
beforeDestroy() {
pubsub.unsubscribe(this.pubId);
},
- 提供資料 ---- 提供資料的組件需發布資訊
methods: {
sendSchoolName() {
pubsub.publish("msg", "你好呀");
},
},
nextTick( )
- 語法 --- this.$nextTick(回呼函式)
- 作用 ---- 下次DOM更新結束后執行其指定的回呼
- 使用場景 ---- 改變資料后 -- 基于更新后的新DOM進行某些操作時 -- 在nextTick所指定的回呼函式中執行
過渡與影片
作用 --- 在插入、更新和移除DOM元素時 --- 在合適的時候給元素添加樣式類名

寫法
- 元素進入的樣式
- v-enter ---- 進入的起點
- v-enter-active ---- 進入的程序
- v-enter-to ---- 進入的終點
// 進入的起點 --- 若transition配置了name屬性--則寫name的值 --- 若沒有配置則寫v
.hello-enter {
transform: translateX(-100%);
}
// 進入的影片效果
.hello-enter-active {
transition: 0.5s linear;
}
// 進入的終點
.hello-enter-to {
transform: translateX(0px);
}
- 元素離開的樣式
- v-leave ---- 進入的起點
- v-leave-active ---- 進入的程序
- v-leave-to ---- 進入的終點
//離開的起點
.hello-leave {
transform: translateX(0px);
}
//離開的影片效果
.hello-leave-active {
transition: 0.5s linear;
}
//離開的終點
.hello-leave-to {
transform: translateX(-100%);
}
- 使用
包裹要過渡的元素 ---- 并配置name屬性
<button @click="isShow = !isShow">點擊顯示/隱藏</button>
<transition appear name="hello">
<h1 v-show="isShow" >HELLO</h1>
</transition>
- 若有多個元素要進行過渡 --- 使用
,且每個元素都要指定key值
<button @click="isShow = !isShow">點擊顯示/隱藏</button>
<transition appear name="hello">
<h1 v-show="isShow" >HELLO</h1>
<h1 v-show="isShow" >你好</h1>
</transition>
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/552992.html
標籤:其他
上一篇:常見前端安全問題總結
下一篇:返回列表
