vue官方api教程:https://cn.vuejs.org/v2/guide/
vue官方api文檔:https://cn.vuejs.org/v2/api/#watch
一、下載vue 專用開發工具HbuilderX(也可以使用其他)
傻瓜式下載安裝即可
HbuilderX下載:https://www.dcloud.io/hbuilderx.html
二、vue的第一個例子
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<!-- 開發環境版本,包含了有幫助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
{{ message }}
</div>
<body>
<script>
var vm = new Vue({
// 綁定 id="app" 的元素
el: "#app",
// 定義數據
data: {
message : "vue的第一個例子"
}
})
</script>
</body>
</html>
三、v- 指令
v- 指令作用一覽
v-text 顯示文本
v-html 顯示 html
v-show 元素隱藏/顯示
v-if 邏輯判斷並執行對應的代碼塊
v-else 邏輯判斷並執行對應的代碼塊
v-else-if 邏輯判斷並執行對應的代碼塊
v-for 循環data 數據
v-on 事件
v-bind 賦值(任何屬性)
v-model 數據雙向綁定
v-slot 插槽
v-pre 跳過這個元素和它的子元素的編譯過程
v-cloak 閃爍問題處理(元素加載順序可能導致頁面展示未渲染的數據)
v-once 只渲染元素和組件一次
v-text
1、v-text 會已文本的方式輸出
2、v-text 會已文本的方式輸出完整的 html 數據
3、v-text 會已文本的方式輸出完整的 script 數據
<!-- 開發環境版本,包含了有幫助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<!-- 使用v-text 指令 -->
<span v-text="message"></span><br />
<!-- v-text 會已文本的方式輸出完整的 html 數據 -->
<span v-text="msg_html"></span><br />
<!-- v-text 會已文本的方式輸出完整的 script 數據 -->
<span v-text="msg_script"></span><br />
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
message: "v-text 指令,會已文本的方式輸出",
msg_html: "<h1>我是html文本</h1>",
msg_script: "\<script\>alert(1)\</script\>",
}
})
</script>
輸出結果
v-html
1、v-html 會輸出 普通的文本信息
2、v-html 會已 html 標籤的方式輸出 html文本
3、v-html 會屏蔽 script的輸出
<!-- 開發環境版本,包含了有幫助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<!-- 使用v-html 指令 -->
<span v-html="message"></span><br />
<!-- v-html 會已html 的方式輸出html文本 -->
<span v-html="ms_html"></span><br />
<!-- v-html 會屏蔽script的輸出 -->
<span v-html="msg_script"></span><br />
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
message: "v-html 指令,會已html的方式輸出",
ms_html: "<h1>我是html文本</h1>",
msg_script: "\<script\>alert(1)\</script\>",
}
})
</script>
輸出結果
v-show
v-show=true 直接給元素添加 style=“display: none;” 屬性
v-show=false 移除 style=“display: none;” 屬性
v-show是隱藏代碼塊,讓用戶看不見,html中依然存在
注意:如果已存在值,設置值爲當前值結果取反
<!-- 開發環境版本,包含了有幫助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<!--
v-show=true直接給元素添加 style="display: none;" 屬性
v-show=false 移除 style="display: none;" 屬性
-->
<div v-show="isshow1 ">
isshow1=true 顯示
</div>
<div v-show="isshow2">
isshow2=false 不顯示
</div>
<!-- 如果已存在值,設置值爲當前值結果取反,當前值 isshow1 =true -->
<div v-show="isshow1 === true">
isshow1 =true ,直接設置isshow1 =true (顯示),直接設置 isshow1 =false (不顯示)
</div>
<!-- 如果已存在值,設置值爲當前值結果取反,當前值 isshow2 =false -->
<div v-show="isshow2 === false">
isshow2 =false,直接設置isshow2 =false (顯示),直接設置 isshow2 =true (不顯示)
</div>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
isshow1: true,
isshow2: false,
}
})
</script>
輸出結果
v-if
v-if=true 進入代碼塊
v-if=false 不進入代碼塊
v-if 是直接從html 移除代碼塊 , v-if=false 會在頁面提供一個佔位符,當v-if=true 時會找到這個佔位符
<!-- 開發環境版本,包含了有幫助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<!-- v-if=false 會在頁面提供一個佔位符,當v-if=true 時會找到這個佔位符 -->
<span v-if="is_exist1"> v-if=true 顯示</span>
<span v-if="is_exist2"> v-if=false 不顯示 </span>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
is_exist1: true,
is_exist2: false,
}
})
</script>
輸出結果
v-else-if || v-else
<!-- 開發環境版本,包含了有幫助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
num1= {{num1}}
<div>=============v-else================</div>
<div v-if="num1 > 0.5">
隨機數 0.5-1.0
</div>
<div v-else>
隨機數 0.0-0.5
</div>
<br />
<div>=============v-else-if================</div>
num2= {{num2}}
<div v-if="num2 > 0.3 && num2 <= 0.5">
隨機數 0.3--0.5
</div>
<div v-else-if="num2 > 0.5 && num2 <= 0.7">
隨機數 0.5--0.7
</div>
<div v-else-if="num2 > 0.7">
隨機數 0.7--1.0
</div>
<div v-else>
隨機數 0.0--0.3
</div>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
num1: Math.random(),
num2: Math.random(),
}
})
</script>
輸出結果
v-for (遍歷數組,對象,Set,Map)
預期:Array | Object | number | string | Iterable (2.6 新增)
用法
<div v-for="item in items">
{{ item.text }}
</div>
另外也可以爲數組索引指定別名 (或者用於對象的鍵):
<div v-for="(item, index) in items"></div>
<div v-for="(val, key) in object"></div>
<div v-for="(val, name, index) in object"></div>
測試案例代碼
<!-- 開發環境版本,包含了有幫助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
遍歷數組
<ui>
<li v-for="(item, index) in arr">
索引-{{index}} ---- {{item}}
</li>
</ui>
<hr />
遍歷對象
<ui>
<li v-for="(val, key,index) in obj">
索引-{{index}} ---- {{key}} = {{val}}
</li>
</ui>
<hr />
遍歷set
<ui>
<li v-for="(val,index) in set">
索引-{{index}} ---- {{val}}
</li>
</ui>
<hr />
遍歷map
<ui>
<li v-for="(item,index) in map">
索引-{{index}} ---- {{item}} ---- value={{item[1]}}
</li>
</ui>
<hr />
</div>
<script>
//set 數據
var set = new Set();
set.add("set1");
set.add("set2");
//map 數據
var map = new Map();
map.set("id",1);
map.set("name","wangsong");
map.set("age","24");
var vm = new Vue({
el: "#app",
data: {
arr: [1, 2, 3, 4], //數組
obj: {
"id": 1,
"name": "wangsong",
"age": 24
},
set: set,
map: map,
//map 可簡寫
}
})
</script>
效果展示
v-on (定義方法 methods)
1、事件直接修改data數據
2、事件簡寫 v-on:click --> @click
3、事件名已變量方式傳入
4、定義方法處理事件邏輯
<!-- 開發環境版本,包含了有幫助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
{{message}}
<!-- 1、點擊直接修改message 參數 -->
<button v-on:click="message='world'"> 點擊值變--world</button>
<!-- 2、簡寫 -->
<button @click="message='hello'"> 點擊值變--hello</button>
<!-- 3、事件名已變量方式傳入 -->
<button @[event]="message='你好'"> 點擊值變--妳好</button>
<!-- 4、點擊執行邏輯處理方法methods.plus 方法 -->
<button @click="plus(1,'wangsong')"> 點擊</button>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
message: "hello",
event: "click", //3
},
//定義方法
methods: {
// 4、點擊事件處理邏輯
plus: function(id, name) {
this.message = "我被點擊啦 id=" + id + " ,name=" + name;
}
}
})
</script>
效果展示
v-bind
賦值
<!-- 開發環境版本,包含了有幫助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<!-- 使用v-bind 賦值 -->
<input v-bind:value="message"/> <br />
<!-- 簡寫 -->
<input :value="message"/>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
message: "hello",
},
})
</script>
修改展示
v-model
<!-- 開發環境版本,包含了有幫助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
{{message}} <hr />
<!-- 使用v-bind 賦值 -->
<input v-bind:value="message"/> <hr />
<!-- 數據雙向綁定,一但此次的該值發生變化,所有引用了該值的數據都會發生改變 -->
<input v-model:value="message"/>
</div>
<script>
var vm = new Vue({
el: "#app",
data: {
message: "hello",
},
})
</script>
效果展示
v-slot
v-pre
v-cloak
v-once
四、生命週期
官方文檔生命週期示例圖:https://cn.vuejs.org/v2/guide/instance.html#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B%BE%E7%A4%BA
1、生命週期流程圖(官方)
2、生命週期代碼示例參考
<!-- 開發環境版本,包含了有幫助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
{{text}}
</div>
<script>
Vue.component('app', {
template: '<h3>生命週期示例</h3>',
// 在實例初始化之後
beforeCreate: function() {
console.log("beforeCreate=實例初始化")
},
// 在實例創建完成後被立即調用,
created: function() {
console.log("created=實例創建完成")
},
// 在掛載開始之前被調用:相關的 render 函數首次被調用。
beforeMount: function() {
console.log("beforeMount=掛載開始")
},
// 實例被掛載後調用
mounted: function() {
console.log("mounted=實例已被掛載")
},
// 數據更新時調用
beforeUpdate: function() {
console.log("beforeUpdate=數據更新")
},
// DOM 更新時調用
updated: function() {
console.log("updated=DOM 更新")
},
// 被 keep-alive 緩存的組件激活時調用
activated: function() {
console.log("activated= keep-alive 緩存激活")
},
// 被 keep-alive 緩存的組件停用時調用。
deactivated: function() {
console.log("deactivated= = keep-alive 緩存停用")
},
// 實例銷燬之前調用
beforeDestroy: function() {
console.log("beforeDestro= 實例銷燬前")
},
// 實例銷燬後調用
destroyed: function() {
console.log("destroyed= 實例已銷燬")
},
// 當捕獲一個來自子孫組件的錯誤時被調用。此鉤子會收到三個參數:錯誤對象、發生錯誤的組件實例以及一個包含錯誤來源信息的字符串。此鉤子可以返回 false 以阻止該錯誤繼續向上傳播。
errorCaptured: function() {
console.console.log("errorCaptured= 發生異常")
},
});
var vm = new Vue({
// 定義了template ,el 將無效
el: "#app",
data: {
text: "生命週期",
},
// template會替換 el 綁定的html內容, 可以直接定義或加載Vue.component
template: '<app/>',
})
五、組件(template)
一個字符串模板作爲 Vue 實例的標識使用。模板將會 替換 掛載的元素。掛載元素的內容都將被忽略,除非模板的內容有分發插槽。
如果值以 # 開始,則它將被用作選擇符,並使用匹配元素的 innerHTML 作爲模板。常用的技巧是用 <script type="x-template">
包含模板。
1、全局組件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<!-- 開發環境版本,包含了有幫助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<div id="app">
{{text}}
</div>
<script type="text/javascript">
/**
* 全局組件的html字符串
*/
var son_html = "<div style='background-color: violet;height: 40px;width: 80%;margin-top: 28%;'> "+
" 我是全局的子組件 | 消息 | 好友列表 | 動態 | 個人中心 " +
" </div>";
/**
* 全局組件,任何地方可使用(必須先加載)
*/
Vue.component('son', {
template: son_html
});
/**
* 一個字符串模板作爲 Vue 實例的標識使用。模板將會 替換 掛載的元素。掛載元素的內容都將被忽略,除非模板的內容有分發插槽。
*
*如果值以 # 開始,則它將被用作選擇符,並使用匹配元素的 innerHTML 作爲模板。常用的技巧是用 <script type="x-template"> 包含模板。
*/
var vm = new Vue({
el: "#app",
data: {
text: "模板"
},
// 定義了template會,el 綁定的html內容將被取代
template: "<div style='background-color: salmon;height: 500px;'>" +
"<h1>我是主組件</h1>" +
"<son>" + //插槽,引入各種模板(如:上菜單,下菜單,左菜單,頁面)
"</div>"
})
</script>
</body>
</html>
展示效果
2、獨立組件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<!-- 開發環境版本,包含了有幫助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<div id="app">
{{text}}
</div>
<script type="text/javascript" style="width: ;">
/**
* 組件的html字符串
*/
var sp_son_html = "<div style='background-color: violet;height: 200px;width: 200px;'> "+
" 我是獨立的子組件" +
" </div>";
var vm = new Vue({
el: "#app",
data: {
text: "模板"
},
// 定義了template會,el 綁定的html內容將被取代
template: "<div style='background-color: salmon;height: 500px;'>" +
"我是主組件" +
"<sp_son>" + //插槽,引入各種模板(如:上菜單,下菜單,左菜單,頁面)
"</div>"
,
//當前Vue示例的子組件,其他地方不可用
components: {
'sp_son':{
template: sp_son_html
}
}
})
</script>
</body>
</html>
展示效果
六、數據監聽操作
1、v-model + watch數據監聽
淺層數據(watch無法直接監聽深層的數據,如 json嵌套數據)
<!-- 開發環境版本,包含了有幫助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
{{num}}
<input type="text" v-model:value="num" />
</div>
<body>
<script>
var vm = new Vue({
el: "#app",
data: {
num: 1,
message : "vue的第一個例子"
},
watch:{
//newNum = 新值,舊值
num:function(newNum, oldNum){
console.log(newNum,oldNum);
}
}
})
</script>
效果展示
深層數據
<!-- 開發環境版本,包含了有幫助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
{{obj.name}}
<input type="text" v-model:value="obj.name" />
</div>
<body>
<script>
var vm = new Vue({
el: "#app",
data: {
obj:{name:"wangsong"}
},
watch:{
obj:{
deep:true, //深度監聽
handler:function(){
console.log("數據被修改了");
}
}
}
})
</script>
效果展示
2、v-model 雙向綁定,動態數據計算
模擬 a+b = c
a和b 都採用雙向數據綁定
c 採用方法動態計算結果
<!-- 開發環境版本,包含了有幫助的命令行警告 -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<input type="number" v-model:value="a" /> x
<input type="number" v-model:value="b" /> = {{calc}}
</div>
<body>
<script>
var vm = new Vue({
el: "#app",
data: {
a: 0,
b: 0,
},
computed: {
calc: function() {
return parseInt(this.a) * parseInt(this.b);
}
}
})
</script>
效果展示,輸入數字會動態計算結果
3、數據驅動原理(Object.defineProperty)
可參考文檔:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
監聽data 數據中的name 屬性的修改與調用,實現數據操作
<script>
var data ={};
Object.defineProperty(data, "name", {
set: function(newV) {
console.log("有人給name 賦值了-"+newV)
},
get: function() {
console.log("有人獲取了name 值")
return "測試返回"
}
})
</script>