1.1 初始化腳手架 1.1.1 說明 Vue 腳手架是 Vue 官方提供的標準化開發工具(開發平臺) 最新的版本是 4.x 文檔 1.1.2 具體步驟 第一步(僅第一次執行):全局安裝 @vue/cli npm install -g @vue/cli 第二步: 切換到要創建項目的目錄 ,然後使用命 ...
1.1 初始化腳手架
1.1.1 說明
Vue
腳手架是Vue
官方提供的標準化開發工具(開發平臺)- 最新的版本是
4.x
- 文檔
1.1.2 具體步驟
-
第一步(僅第一次執行):全局安裝
@vue/cli
npm install -g @vue/cli
-
第二步: 切換到要創建項目的目錄 ,然後使用命令創建項目
vue create xxxx
xxxx: 項目名
-
第三步:啟動項目
npm run serve
-
備註:
-
如出現:下載緩慢請配置淘寶鏡像:
npm config set registry https://registry.npm.taobao.org
-
Vue
腳手架隱藏了所有webpack
相關的配置,若想查看具體的webpack
配置,請執行:vue inspect > output.js
-
1.1.3 模板項目的結構
├──node_modules
├──public
│ ├──favicon.ico:頁簽圖標
│ └──index.html:主頁面
├──src
│ ├──assets:存放靜態資源
│ │ └──logo.png
│ │──component:存放組件
│ │ └──HelloWorld.vue
│ │──App.vue:彙總所有組件
│ │──main.js:入口文件
├──.gitignore:git版本管制忽略的配置
├──babel.config.js:babel的配置文件
├──package.json:應用包配置文件
├──README.md:應用描述文件
├──package-lock.json:包版本控制文件
1.1.4 不同版本的 Vue
vue.js
與vue.runtime.xxx.js
的區別:vue.js
是完整版的Vue
,包含:核心功能 + 模板解析器。vue.runtime.xxx.js
是運行版的Vue
,只包含:核心功能;沒有模板解析器
- 因為
vue.runtime.xxx.js
沒有模板解析器,所以不能使用template
這個配置項,需要使用render
函數接收到的createElement
函數去指定具體內容
1.1.5 vue.config.js
配置文件
-
使用
vue inspect > output.js
可以查看到Vue腳手架的預設配置。 -
使用
vue.config.js
可以對腳手架進行個性化定製,詳情
1.2 ref
1.2.1 使用說明
- 被用來給元素或子組件註冊引用信息(id 的替代者)
- 應用在
html
標簽上獲取的是真實DOM
元素,應用在組件標簽上是組件實例對象(vc
) - 使用方式:
- 打標識:
<h1 ref="xxx">.....</h1>
或<School ref="xxx"></School>
- 獲取:
this.$refs.xxx
- 打標識:
1.3 props
1.3.1 使用說明
-
功能:讓組件接收外部傳過來的數據
-
傳遞數據:
<Demo name="xxx"/>
-
接收數據:
-
第一種方式(只接收):
props:['name']
-
第二種方式(限制類型):
props:{name:String}
-
第三種方式(限制類型、限制必要性、指定預設值):
props:{ name:{ type:String, //類型 required:true, //必要性 default:'老王' //預設值 } }
備註:
props
是只讀的,Vue
底層會監測你對props
的修改,如果進行了修改,就會發出警告,若業務需求確實需要修改,那麼請複製props
的內容到data
中一份,然後去修改data
中的數據。 -
1.3.2 代碼示例
父組件 App
中使用子組件 Student
,並傳參數
<template>
<div id="app">
<!-- 註意:屬性前面有沒有加 : 的區別,沒加就是表示傳的參數是字元串,加了就是表示具體的類型值 -->
<!-- <Student studentName="張三" studentSex="男" studentAge="18"/> -->
<hr />
<Student studentName="張三" studentSex="男" :studentAge="18"/>
<hr />
<Student studentSex="男" :studentAge="20"/>
</div>
</template>
<script>
import Student from "./components/Student.vue";
export default {
components: { Student }
};
</script>
Student
組件接收父組件傳來的參數
<template>
<div>
<h2>{{ msg }}</h2>
<h2>學生姓名: {{ studentName }}</h2>
<h2>學生性別: {{ studentSex }}</h2>
<!-- <h2>學生年齡: {{ studentAge + 1 }}</h2> -->
<h2>學生年齡: {{ age + 1 }}</h2>
<button @click="addAge">點我年齡 +10 </button>
</div>
</template>
<script>
export default {
name: "Student",
// 接收參數的簡要寫法
// props: ['studentName', 'studentSex', 'studentAge'],
// 接受參數 + 指定類型的寫法
// props: {
// studentName: String,
// studentSex: String,
// // 指令類型為數值類型,當傳入的類型不是數值類型時就會報錯
// // Expected Number with value 18, got String with value "18".
// studentAge: Number,
// },
// 接收參數 + 指定類型 + 指定是否必傳 + 指定預設值
props: {
studentName: {
// 指定類型是字元串
type: String,
// 指定預設值
default: "李四"
},
studentSex: {
type: String,
// 指定必傳
required: true
},
studentAge: {
type: Number
}
},
data() {
return {
msg: "我是一名學生",
age: this.studentAge
};
},
methods: {
addAge() {
// props 是只讀的,Vue 底層會監測你對 props 的修改,如果進行了修改,就會發出警告,若業務需求確實需要修改,那麼請複製 props 的內容到 data 中一份,然後去修改 data 中的數據。
// 警告
// Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders.
// this.studentAge += 10;
this.age += 10
}
}
};
</script>
1.4 混入
1.4.1 使用說明
-
功能:可以把多個組件共用的配置提取成一個混入對象
-
使用方式:
第一步定義混入:
{ data(){....}, methods:{....} .... }
第二步使用混入:
- 全局混入:Vue.mixin(xxx)
- 局部混入:mixins:['xxx']
1.4.2 代碼示例
定義混入 mixin.js
// 定義一個混入配置信息
// 說明:如果混入中配置的數據、方法,在組件中有同樣的數據定義、方法名稱,會載入組件中的數據和方法,混入中的數據和方法就不起作用
const mixin1 = {
data() {
return {
x: 200,
y: 100
}
},
methods: {
showName() {
alert(this.name)
}
},
}
// 說明:生命周期中的函數,如果混入、組件中都有配置的話,二者都會執行
const mixin2 = {
mounted() {
console.log("mixin 中的 mounted... ")
},
}
export {
mixin1,
mixin2
}
在組件中使用混入:
<template>
<div>
<h2>學校名稱: {{ name }}</h2>
<h2>學校地址: {{ address }}</h2>
<button @click="showName">點我提示信息</button>
</div>
</template>
<script>
// 引入混入
import { mixin1 } from "@/mixin";
export default {
name: "School",
// 混入配置項
mixins: [mixin1],
data() {
return {
name: "北京大學",
address: "北京",
};
},
methods: {
// showName() {
// alert(this.name);
// },
},
};
</script>
<template>
<div>
<h2>學生姓名: {{ name }}</h2>
<h2>學生性別: {{ sex }}</h2>
<h2>學生年齡: {{ age }}</h2>
<button @click="showName">點我提示信息</button>
</div>
</template>
<script>
// 引入混入
import { mixin1, mixin2 } from "../mixin";
export default {
name: "Student",
mixins: [mixin1, mixin2],
data() {
return {
name: "張三",
sex: "男",
age: 20,
x: 1000,
};
},
methods: {
showName() {
console.log("student... ");
alert(this.name + "hello world");
},
},
mounted() {
console.log("student 中的 mounted... ");
},
};
</script>
1.5 插件
1.5.1 使用說明
-
功能:用於增強
Vue
-
本質:包含
install
方法的一個對象,install
的第一個參數是Vue
,第二個以後的參數是插件使用者傳遞的數據。 -
定義插件:
對象.install = function (Vue, options) { // 1. 添加全局過濾器 Vue.filter(....) // 2. 添加全局指令 Vue.directive(....) // 3. 配置全局混入(合) Vue.mixin(....) // 4. 添加實例方法 Vue.prototype.$myMethod = function () {...} Vue.prototype.$myProperty = xxxx }
-
使用插件:
Vue.use()
1.5.2 代碼示例
定義插件 plugins.js
export default {
install(Vue) {
console.log(Vue, "@@@@@");
// 全局定義過濾器
Vue.filter("strSlice", function (value) {
return value.slice(0, 4)
})
// 全局定義指令
Vue.directive("fbind", {
// 指令與元素成功綁定時 一上來
bind(element, binding) {
element.value = binding.value
},
// 指令所在元素插入頁面時
inserted(element, binding) {
element.focus()
},
// 指令所在模板被重新解析時
updated(element, binding) {
element.value = binding.value
},
})
// 給 Vue 原型上添加一個方法 vm、vc 都能使用
Vue.prototype.hello = () => {
console.log("hello world ");
}
},
}
在 main.js
中使用插件
// 引入插件
import plugins from './plugins'
// 使用插件
Vue.use(plugins)
1.6 scoped
樣式
-
作用:讓樣式在局部生效,防止衝突。
-
寫法:
<style scoped> .demo { background-color: orange; // less 與 css 的一個區別就是 less 可以疊加寫,css 不可以 .title { font-size: 40px; } } </style>
1.7 組件化編碼流程
- 組件化編碼流程:
- 拆分靜態組件:組件要按照功能點拆分,命名不要與
html
元素衝突。 - 實現動態組件:考慮好數據的存放位置,數據是一個組件在用,還是一些組件在用:
- 一個組件在用:放在組件自身即可。
- 一些組件在用:放在他們共同的父組件上(狀態提升)。
- 實現交互:從綁定事件開始。
- 拆分靜態組件:組件要按照功能點拆分,命名不要與
props
適用於:- 父組件 ==> 子組件 通信
- 子組件 ==> 父組件 通信(要求父先給子一個函數)
- 使用
v-model
時要切記:v-model
綁定的值不能是props
傳過來的值,因為props
是不可以修改的! props
傳過來的若是對象類型的值,修改對象中的屬性時Vue
不會報錯,但不推薦這樣做。
1.8 webStorage
1.8.1 使用說明
-
存儲內容大小一般支持 5MB 左右(不同瀏覽器可能還不一樣)
-
瀏覽器端通過
Window.sessionStorage
和Window.localStorage
屬性來實現本地存儲機制 -
相關API:
-
xxxxxStorage.setItem('key', 'value');
該方法接受一個鍵和值作為參數,會把鍵值對添加到存儲中,如果鍵名存在,則更新其對應的值 -
xxxxxStorage.getItem('person');
該方法接受一個鍵名作為參數,返回鍵名對應的值 -
xxxxxStorage.removeItem('key');
該方法接受一個鍵名作為參數,並把該鍵名從存儲中刪除 -
xxxxxStorage.clear()
該方法會清空存儲中的所有數據
-
-
備註:
SessionStorage
存儲的內容會隨著瀏覽器視窗關閉而消失LocalStorage
存儲的內容,需要手動清除才會消失xxxxxStorage.getItem(xxx)
如果 xxx 對應的value
獲取不到,那麼getItem
的返回值是null
JSON.parse(null)
的結果依然是null
1.8.2 代碼示例
LocalStorage
<!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>localStorage 瀏覽器本地存儲</title>
</head>
<body>
<div>
<h2>localStorage 瀏覽器本地存儲</h2>
<button onclick="save()">點我保存一個數據</button>
<button onclick="read()">點我讀取一個數據</button>
<button onclick="remove()">點我刪除一個數據</button>
<button onclick="clearAll()">點我清空數據</button>
</div>
<script type="text/javascript">
let person = {name: "張三", age: 19}
// localStorage 保存數據時最終都是 字元串
function save() {
// 保存字元串
localStorage.setItem("name", "張三")
// 保存數字
localStorage.setItem("age", 18)
// 保存對象數據
// localStorage.setItem("person", person)
localStorage.setItem("person", JSON.stringify(person))
}
function read() {
// 讀取字元串
console.log(localStorage.getItem("name"))
// 讀取數字
console.log(localStorage.getItem("age"))
// 讀取對象
console.log(localStorage.getItem("person"))
console.log(JSON.parse(localStorage.getItem("person")))
}
function remove() {
// 刪除字元串
localStorage.removeItem("name")
// 移除數字
localStorage.removeItem("age")
// 移除對象
localStorage.removeItem("person")
}
function clearAll() {
console.log("clear...");
localStorage.clear()
}
</script>
</body>
</html>
SessionStorage
<!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>sessionStorage 瀏覽器本地存儲</title>
</head>
<body>
<div>
<h2>sessionStorage 瀏覽器本地存儲</h2>
<button onclick="save()">點我保存一個數據</button>
<button onclick="read()">點我讀取一個數據</button>
<button onclick="remove()">點我刪除一個數據</button>
<button onclick="clearAll()">點我清空數據</button>
</div>
<script type="text/javascript">
let person = {name: "張三", age: 19}
// sessionStorage 保存數據時最終都是 字元串
function save() {
// 保存字元串
sessionStorage.setItem("name", "張三")
// 保存數字
sessionStorage.setItem("age", 18)
// 保存對象數據
// sessionStorage.setItem("person", person)
sessionStorage.setItem("person", JSON.stringify(person))
}
function read() {
// 讀取字元串
console.log(sessionStorage.getItem("name"))
// 讀取數字
console.log(sessionStorage.getItem("age"))
// 讀取對象
console.log(sessionStorage.getItem("person"))
console.log(JSON.parse(sessionStorage.getItem("person")))
}
function remove() {
// 刪除字元串
sessionStorage.removeItem("name")
// 移除數字
sessionStorage.removeItem("age")
// 移除對象
sessionStorage.removeItem("person")
}
function clearAll() {
console.log("clear...");
sessionStorage.clear()
}
</script>
</body>
</html>
1.9 組件的自定義事件
1.9.1 使用說明
-
一種組件間通信的方式,適用於:子組件 ===> 父組件
-
使用場景:A 是父組件,B 是子組件,B 想給 A 傳數據,那麼就要在 A 中給 B 綁定自定義事件(事件的回調在 A 中)。
-
綁定自定義事件:
-
第一種方式,在父組件中:
<Demo @helloWorld="test"/>
或<Demo v-on:helloWorld="test"/>
-
第二種方式,在父組件中:
<Demo ref="demo"/> ...... mounted(){ this.$refs.xxx.$on('helloWorld', this.test) }
-
若想讓自定義事件只能觸發一次,可以使用
once
修飾符,或$once
方法。
-
-
觸發自定義事件:
this.$emit('helloWorld',數據)
-
解綁自定義事件
this.$off('helloWorld')
-
組件上也可以綁定原生
DOM
事件,需要使用native
修飾符。 -
註意:通過
this.$refs.xxx.$on('helloWorld',回調)
綁定自定義事件時,回調要麼配置在methods中,要麼用箭頭函數,否則this
指向會出問題!
1.9.2 代碼示例
父組件 App
<template>
<div id="app" class="app">
<h1>學校名稱是:{{ schoolName }}</h1>
<h1>學生姓名是:{{ studentName }}</h1>
<!-- 通過 props 來實現子組件給父組件傳遞數據 -->
<School :getSchoolName="getSchoolName" />
<!-- 第一種寫法:通過父組件給子組件綁定一個自定義事件來實現子組件給父組件傳遞數據 使用 @ 或者 v-on -->
<!-- <Student @getStudentName="getStudentName" /> -->
<!-- 第二種寫法:通過父組件給子組件綁定一個自定義事件來實現子組件給父組件傳遞數據 使用 ref-->
<Student ref="student" />
<!-- 通過父組件給子組件綁定一個自定義事件來實現子組件給父組件傳遞數據,只觸發一次 -->
<!-- <Student @getStudentName.once="getStudentName"/> -->
<!-- <Student ref="student" /> -->
<!-- 使用組件原生的方法 -->
<!-- <Student @click.native="show" /> -->
<!-- <Student @getStudentName="getStudentName" @getDemo="getDemo" /> -->
</div>
</template>
<script>
import School from "./components/School.vue";
import Student from "./components/Student.vue";
export default {
components: { School, Student },
data() {
return {
schoolName: "",
studentName: "",
};
},
methods: {
// 接收 School 子組件傳遞來的數據
getSchoolName(name) {
console.log("App 組件收到了學校名稱", name);
this.schoolName = name;
},
// 接收 Student 子組件傳遞來的數據
getStudentName(name) {
console.log("App 組件收到了學生姓名", name);
this.studentName = name;
},
// 接收多個數據
getDemo(...params) {
console.log(...params);
},
show() {
alert(123)
}
},
mounted() {
// 寫法一
this.$refs.student.$on("getStudentName", (name) => {
// 普通函數寫法 此時 this 是 VueComponent 實例 Student
// 箭頭函數寫法 此時 this 是 vm
console.log(this,"@@@", name);
this.studentName = name
})
// 寫法二
// this.$refs.student.$on("getStudentName", this.getStudentName)
// this.$refs.student.$once("getStudentName", this.getStudentName)
},
};
</script>
<style>
.app {
background-color: gray;
padding: 5px;
}
</style>
子組件 School
<template>
<div class="school">
<h2>學校名稱: {{ name }}</h2>
<h2>學校地址: {{ address }}</h2>
<button @click="sendSchoolName">把學校名稱給 App 組件</button>
</div>
</template>
<script>
export default {
name: "School",
props: ["getSchoolName"],
data() {
return {
name: "北京大學",
address: "北京",
};
},
methods: {
sendSchoolName() {
this.getSchoolName(this.name);
},
},
};
</script>
<style>
.school {
background-color: skyblue;
padding: 5px;
}
</style>
子組件 Student
<template>
<div class="student">
<h2>學生姓名: {{ name }}</h2>
<h2>學生性別: {{ sex }}</h2>
<h2>學生年齡: {{ age }}</h2>
<button @click="sendStudentName">把學生姓名給 App 組件</button>
<button @click="unbind">解綁自定義事件</button>
<button @click="death">銷毀當前組件實例</button>
</div>
</template>
<script>
// 引入混入
export default {
name: "Student",
data() {
return {
name: "張三",
sex: "男",
age: 20,
};
},
methods: {
sendStudentName() {
// 觸發 student 組件實例的 getStudentName 事件
this.$emit("getStudentName", this.name);
this.$emit("getDemo", 1, 2, 3, 4);
},
// 解綁自定義事件
unbind() {
// 解綁一個自定義事件
// this.$off("getStudentName");
// 解綁多個自定義事件
this.$off(["getStudentName", "getDemo"]);
},
// 銷毀當前組件實例
death() {
// 銷毀了當前Student組件的實例,銷毀後所有Student實例的自定義事件全都不奏效。
this.$destroy()
}
},
};
</script>
<style lang="less" scoped>
.student {
background-color: orange;
padding: 5px;
margin-top: 30px;
}
</style>
1.10 全局事件匯流排
1.10.1 使用說明
-
一種組件間通信的方式,適用於任意組件間通信。
-
安裝全局事件匯流排:
new Vue({ ...... beforeCreate() { Vue.prototype.$bus = this //安裝全局事件匯流排,$bus就是當前應用的vm }, ...... })
-
使用事件匯流排:
-
接收數據:A 組件想接收數據,則在 A 組件中給
$bus
綁定自定義事件,事件的回調留在 A 組件自身。methods(){ demo(data){......} } ...... mounted() { this.$bus.$on('xxxx',this.demo) }
-
提供數據:
this.$bus.$emit('xxxx',數據)
-
-
最好在
beforeDestroy
鉤子中,用$off
去解綁當前組件所用到的事件。
1.10.2 代碼示例
在 main.js
中安裝全局事件匯流排
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
el: "#app",
render: h => h(App),
beforeCreate() {
// 安裝全局事件匯流排
Vue.prototype.$bus = this
}
})
在組件 School
中掛載全局事件
<template>
<div class="demo">
<h2>學校名稱: {{ name }}</h2>
<h2>學校地址: {{ address }}</h2>
</div>
</template>
<script>
export default {
name: "School",
data() {
return {
name: "北大大學",
address: "北京",
};
},
methods: {},
// 在組件掛載時綁定一個事件
mounted() {
this.$bus.$on("getStudentName", (data) => {
// 此時 this 是 VueComponent 的實例 School
console.log(this);
console.log("School 組件收到了數據:", data);
});
},
// 在組件銷毀前解綁事件
beforeDestroy() {
this.$bus.$off("getStudentName")
}
};
</script>
<style>
.demo {
background-color: skyblue;
}
</style>
在 Student
組件中觸發全局事件
<template>
<div class="demo">
<h2 class="title">學生姓名: {{ name }}</h2>
<h2>學生性別: {{ sex }}</h2>
<h2>學生年齡: {{ age }}</h2>
<button @click="sendStudentName">把學生名字給 School 組件</button>
</div>
</template>
<script>
// 引入混入
export default {
name: "Student",
data() {
return {
name: "張三",
sex: "男",
age: 20,
};
},
methods: {
sendStudentName() {
// 觸發事件
this.$bus.$emit("getStudentName", this.name)
}
},
};
</script>
<!-- <style>
.demo {
background-color: orange;
}
</style> -->
<!-- 不指定,預設使用 css -->
<!-- scoped: 表示樣式只對指定的組件起作用-->
<!-- <style scoped>
.demo {
background-color: orange;
}
</style> -->
<!-- lang: 指定用什麼樣式 -->
<!-- less 需要引入 less-loader:npm install less-loader 指定版本:npm install less-loader@7 -->
<!-- npm view webpack versions 查看 webpack 版本命令,同理: -->
<style lang="less" scoped>
.demo {
background-color: orange;
// less 與 css 的一個區別就是 less 可以疊加寫,css 不可以
.title {
font-size: 40px;
}
}
</style>
1.11 消息訂閱與發佈
1.11.1 說明使用
-
一種組件間通信的方式,適用於任意組件間通信
-
它包含以下操作:
- 訂閱消息--對應綁定事件監聽
- 發佈消息--分發事件
- 取消消息訂閱--解綁事件監聽
-
PubSub.js
- 線上文檔
- 安裝:
- 相關語法:
import PubSub from 'pubsub-js'
: 引入PubSub.subscribe(‘msgName’, functon(msgName, data){})
: 訂閱PubSub.publish(‘msgName’,data)
: 發佈消息,觸發訂閱的回調函數調用PubSub.unsubscribe(token)
: 取消消息的訂閱
-
使用步驟:
-
安裝
pubsub
:npm i pubsub-js
-
引入:
import pubsub from 'pubsub-js'
-
接收數據:A組件想接收數據,則在A組件中訂閱消息,訂閱的回調留在A組件自身。
methods(){ demo(data){......} } ...... mounted() { this.pid = pubsub.subscribe('xxx',this.demo) //訂閱消息 }
-
提供數據:
pubsub.publish('xxx',數據)
-
最好在
beforeDestroy
鉤子中,用PubSub.unsubscribe(pid)
去取消訂閱。
-
1.11.2 代碼示例
School
組件訂閱消息
<template>
<div class="demo">
<h2>學校名稱: {{ name }}</h2>
<h2>學校地址: {{ address }}</h2>
</div>
</template>
<script>
import pubsub from "pubsub-js";
export default {
name: "School",
data() {
return {
name: "北大大學",
address: "北京",
};
},
methods: {},
mounted() {
// 訂閱消息
const pubId = pubsub.subscribe("sendStudentName", (messageName, data) => {
// 箭頭函數寫法 此時 this 是 VueComponent 實例 School
console.log(this);
console.log(messageName, data);
})
// pubsub.subscribe("sendStudentName", function (messageName, data) {
// // 普通函數寫法,此時 this undefined
// console.log(this);
// console.log(messageName, data);
// });
},
beforeDestroy() {
// 取消訂閱消息
// 取消訂閱消息時要用 pubId 去取消訂閱
pubsub.unsubscribe(this.pubId);
},
};
</script>
<style>
.demo {
background-color: skyblue;
}
</style>
Student
組件消費消息
<template>
<div class="demo">
<h2 class="title">學生姓名: {{ name }}</h2>
<h2>學生性別: {{ sex }}</h2>
<h2>學生年齡: {{ age }}</h2>
<button @click="sendStudentName">把學生姓名給 School 組件</button>
</div>
</template>
<script>
// 引入消息訂閱
import pubsub from "pubsub-js";
export default {
name: "Student",
data() {
return {
name: "張三",
sex: "男",
age: 20,
};
},
methods: {
sendStudentName() {
// 發佈消息
// 第一個參數是消息名
pubsub.publish("sendStudentName", this.name);
},
},
};
</script>
<!-- <style>
.demo {
background-color: orange;
}
</style> -->
<!-- 不指定,預設使用 css -->
<!-- scoped: 表示樣式只對指定的組件起作用-->
<!-- <style scoped>
.demo {
background-color: orange;
}
</style> -->
<!-- lang: 指定用什麼樣式 -->
<!-- less 需要引入 less-loader:npm install less-loader 指定版本:npm install less-loader@7 -->
<!-- npm view webpack versions 查看 webpack 版本命令,同理: -->
<style lang="less" scoped>
.demo {
background-color: orange;
// less 與 css 的一個區別就是 less 可以疊加寫,css 不可以
.title {
font-size: 40px;
}
}
</style>
1.12 nextTick
- 語法:
this.$nextTick(回調函數)
- 作用:在下一次
DOM
更新結束後執行其指定的回調 - 什麼時候用:當改變數據後,要基於更新後的新
DOM
進行某些操作時,要在nextTick
所指定的回調函數中執行
1.13 過度與動畫
1.13.1 使用說明
-
作用:在插入、更新或移除
DOM
元素時,在合適的時候給元素添加樣式類名 -
寫法:
-
準備好樣式:
- 元素進入的樣式:
v-enter
:進入的起點v-enter-active
:進入過程中v-enter-to
:進入的終點
- 元素離開的樣式:
v-leave
:離開的起點v-leave-active
:離開過程中v-leave-to
:離開的終點
- 元素進入的樣式:
-
使用
<transition>
包裹要過度的元素,並配置name
屬性:<transition name="hello"> <h1 v-show="isShow">你好啊!</h1> </transition>
-
備註:若有多個元素需要過度,則需要使用:
<transition-group>
,且每個元素都要指定key
值
-
1.13.2 代碼示例
transition
<template>
<div>
<button @click="isShow = !isShow">顯示/隱藏</button>
<!-- appear 表示頁面一進來就進行動畫效果 -->
<transition name="hello" appear>
<h1 v-show="isShow">Hello World</h1>
</transition>
</div>
</template>
<script>
export default {
name: "Test1",
data() {
return {
isShow: true,
};
},
};
</script>
<style scoped>
h1 {
background-color: orange;
}
.hello-enter-active {
animation: helloWorld 0.5s linear;
}
.hello-leave-active {
animation: helloWorld 0.5s linear reverse;
}
@keyframes helloWorld {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0px);
}
}
</style>
transition-group
<template>
<div>
<button @click="isShow = !isShow">顯示/隱藏</button>
<!-- appear 表示頁面一進來就進行動畫效果 -->
<!-- transition-group 包裹一組標簽,需要指定 key -->
<transition-group name="hello" appear="">
<h1 v-show="isShow" key="1">Hello</h1>
<h1 v-show="isShow" key="2">World</h1>
</transition-group>
</div>
</template>
<script>
export default {
name: "Test2",
data() {
return {
isShow: true,
};
},
};
</script>
<style scoped>
h1 {
background-color: skyblue;
}
/* 進入的起點,離開的終點 */
.hello-enter,
.hello-leave-to {
transform: translateX(-100%);
}
.hello-enter-active,
.hello-leave-active {
transition: 0.5s linear;
}
/* 離開的起點,進入的重點 */
.hello-leave,
.hello-enter-to {
transform: translateX(0);
}
</style>
使用第三方動畫庫 Animate.css
<template>
<div>
<button @click="isShow = !isShow">顯示/隱藏</button>
<!-- 使用第三方動畫庫 -->
<transition-group
appear
name="animate__animated animate__bounce"
enter-active-class="animate__swing"
leave-active-class="animate__backOutUp"
>
<h1 v-show="isShow" key="1">Hello</h1>
<h1 v-show="isShow" key="2">World</h1>
</transition-group>
</div>
</template>
<script>
// Animate.css 使用步驟
// 0.官網地址:https://animate.style/
// 1.安裝:npm install animate.css --save
// 2.引入: import "animate.css";
import "animate.css";
export default {
name: "Test3",
data() {
return {
isShow: true,
};
},
};
</script>
<style scoped>
h1 {
background-color: orange;
}
</style>
1.14 插槽
1.14.1 使用說明
-
作用:讓父組件可以向子組件指定位置插入
html
結構,也是一種組件間通信的方式,適用於 父組件 ===> 子組件 。 -
分類:預設插槽、具名插槽、作用域插槽
1.14.2 預設插槽
父組件
<Category>
<div>html結構1</div>
</Category>
子組件
<template>
<div>
<!-- 定義插槽 -->
<slot>插槽預設內容...</slot>
</div>
</template>
1.14.3 具名插槽
父組件中
<Category>
<template slot="center">
<div>html結構1</div>
</template>
<template v-slot:footer>
<div>html結構2</div>
</template>
</Category>
子組件中
<template>
<div>
<!-- 定義插槽 -->
<slot name="center">插槽預設內容...</slot>
<slot name="footer">插槽預設內容...</slot>
</div>
</template>
1.14.4 作用域插槽
-
理解:數據在組件的自身,但根據數據生成的結構需要組件的使用者來決定。(
games
數據在Category
組件中,但使用數據所遍歷出來的結構由App
組件決定) -
具體編碼:
父組件中
<Category> <template scope="scopeData"> <!-- 生成的是ul列表 --> <ul> <li v-for="g in scopeData.games" :key="g">{{g}}</li> </ul> </template> </Category> <Category> <template slot-scope="scopeData"> <!-- 生成的是h4標題 --> <h4 v-for="g in scopeData.games" :key="g">{{g}}</h4> </template> </Category>
子組件
<template> <div> <slot :games="games"></slot> </div> </template> <script> export default { name:'Category', props:['title'], //數據在子組件自身 data() { return { games:['紅色警戒','穿越火線','勁舞團','超級瑪麗'] } }, } </script>