Vue 起步
Vue 作爲MVVM框架,極大的減少了 對 dom 元素的操作。
一、數據的雙向綁定,2s之後hello vue 變爲 bye vue
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">{{message}}</div>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
message: 'hello Vue'
}
});
setTimeout(function(){
app.$data.message='bye world';
},2000)
</script>
</body>
</html>
二、利用jquery 實現傳統的 todolist demo
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>todolist jquery</title>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<div>
<input id="input" type="text" />
<button id="btn">提交</button>
<ul id="list"></ul>
</div>
<script>
//m v p 設計模式,很多時候都是在操作dom,面向dom開發
function Page() {
}
$.extend(Page.prototype, {
init: function() {
this.bindEvents();
},
bindEvents: function() {
var btn = $("#btn");
btn.on("click", $.proxy(this.handleBtnClick, this))
},
handleBtnClick: function() {
//alert('123');
//獲取input輸入框的值
var input = $("#input");
var inputValue = input.val();
//獲取ul元素
var ul = $("#list");
//構造li ,將li添加到ul中國
ul.append("<li>" + inputValue + "</li>");
input.val('');
}
});
var page = new Page();
page.init();
</script>
</body>
</html>
三、使用vue 實現 todolist demo
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>TodoList</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!-- v-model 雙向綁定 -->
<input type="text" v-model="inputValue" />
<!--
作者:offline
時間:2019-03-22
描述:v-on 綁定一個事件
-->
<button v-on:click="handleBtnClick">提交</button>
<ul>
<!-- <li>第一課的內容</li>
<li>第二課的內容</li>-->
<!--<li v-for="item in list">{{item}}</li>-->
<!--1.父組件將獲取到的item和index通過v-bind的形式傳遞給子組件-->
<!--5.父組件 通過@delete監聽子組件的點擊時間,監聽到了子組件的點擊事件之後調用父組件的
handleItemDelete函數
-->
<todo-item v-bind:content="item" v-bind:index="index" v-for="(item,index) in list" @delete="handleItemDelete">
</todo-item>
</ul>
</div>
<script type="text/javascript">
//定義全局組件
// Vue.component("TodoItem",{
// props:['content'],
// template:"<li>{{content}}</li>"
// });
//局部組件
var TodoItem = {
//2.子組件通過props接收到父組件傳來的item和index參數
props: ['content', 'index'],
//3.當子組件被點擊的時候,觸發子組件的點擊事件函數
template: "<li @click='handleItemClick'>{{content}}</li>",
methods: {
handleItemClick: function() {
//4.子組件觸發點擊事件之後,通過emit函數通知父組件,並回傳list數組的下標
this.$emit("delete", this.index);
}
}
};
//mvvm 框架 數據和視圖雙向綁定,面向數據開發
var app = new Vue({
el: '#app',
data: {
list: ['第一課的內容', '第二課的內容', '3333'],
inputValue: ''
},
methods: {
handleBtnClick: function() {
if(this.inputValue) {
this.list.push(this.inputValue);
this.inputValue = '';
}
},
//6.父組件拿到子組件回傳的index下標進行移除操作
handleItemDelete: function(index) {
this.list.splice(index, 1);
}
},
//上面定義的局部組件需要在此將它加入到vue組件中
components: {
TodoItem: TodoItem
}
});
</script>
</body>
</html>
vue的每個組件其實也是vue的實例,vue的實例有很多實例屬性和實例方法,在調用的時候加上$符號來區別用戶自定義的屬性和方法。
三、vue 的 生命週期鉤子
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue生命週期鉤子</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
</div>
<script type="text/javascript">
//生命週期函數就是vue實例在某一個時間節點自動執行的函數,並且vue的
//生命週期函數並不放在vue實例的methods對象中。
var app = new Vue({
el:"#app",
beforeCreate: function(){
console.log(" 基礎的初始化 ");
},
created: function(){
console.log("created");
},
beforeMount: function(){
console.log("beforeMount");
},
mounted: function(){
console.log("mounted")
},
// 調用app.$destroy()方法時函數被調用
beforeDestroy: function(){
console.log("beforeDestroy");
},
destroyed: function(){
console.log("destroyed");
},
//數據被修改的時候被調用
beforeUpdate: function(){
console.log("beforeUpdate");
},
updated:function () {
console.log("updated");
},
template:"<div>{{test}}</div>",
data:{
test: "hellllllllllll......"
}
});
setTimeout(function() {
app.$data.test = 'worlddddddddd.....';
},2000);
// setInterval(function(){
// alert('123');
// },5000)
</script>
</body>
</html>
四、vue的 v-text 、v-html、計算屬性
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>v-text,v-html,計算屬性</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<div id="a">{{test+' lee'}}</div>
<div id="b" v-text="test + ' lee' "></div>
<div id="c" v-html="test +' lee'"></div>
<div v-text="firstName"></div>
<div v-html="lastName"></div>
<div>計算屬性:{{fullName}}</div>
<!--<div>methods方法計算屬性:{{fullName()}}</div>-->
</div>
<script type="text/javascript">
var app = new Vue({
el: "#app",
data: {
test: '<h1>dzx</h1>',
firstName: "d",
lastName: "zx",
fullName: "dzx"
},
//計算屬性,解決屬性冗餘,
computed: {
fullName: function() {
console.log("計算 了一次");
//計算屬性具有緩存的作用,當計算的值被修改的時候纔會重新計算。
return this.firstName + " " + this.lastName;
}
//計算屬性的get set用法
// fullName:{
// get:function(){
// return this.firstName+" "+this.lastName;
// },
// set: function(value){
// var arr = value.split(" ");
// this.firstName = arr[0];
// this.lastName = arr[1];
// }
// }
},
//普通方法
// methods:{
// fullName:function(){
// return this.firstName+" "+this.lastName;
// }
// },
//watch 監聽 某個屬性的變化,進而改變另外一個 屬性的值
// watch:{
// firstName:function(){
// this.fullName = this.firstName+" "+this.lastName;
// },
// lastName:function(){
// this.fullName = this.firstName+" "+this.lastName;
// }
// }
});
</script>
</body>
</html>
五、樣式綁定
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>樣式綁定</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<style type="text/css">
.activated{
color: red;
}
.activatedOne{
font-size: 20px;
}
</style>
</head>
<body>
<div id="app">
<div @click="handleDivClick" :class="{activated: isActivated}">
{{msg}}
</div>
</div>
<script type="text/javascript">
var app = new Vue({
el: "#app",
data:{
msg:"hello world",
isActivated: false
},
methods:{
handleDivClick: function () {
this.isActivated = !this.isActivated;
}
}
});
</script>
<div id="app1">
<div @click="handleDivClick" :class="[activated,activatedOne]">
{{msg}}
</div>
</div>
<script type="text/javascript">
var app1 = new Vue({
el:"#app1",
data:{
msg:"hello world",
activated:"",
activatedOne: "",
},
methods:{
handleDivClick: function () {
this.activated = this.activated ==='activated'?'':'activated';
this.activatedOne = this.activatedOne === 'activatedOne'?'':'activatedOne';
}
}
})
</script>
<div id="app2">
<div :style="[styleObj,{fontSize:'20px'}]" @click="handleDivClick">
{{msg}}
</div>
</div>
<script type="text/javascript">
var app2 = new Vue({
el:"#app2",
data:{
msg:"hello world",
activated:"",
activatedOne: "",
styleObj:{
color: "blue"
}
},
methods:{
handleDivClick:function () {
this.styleObj.color = this.styleObj.color==="blue"?"red":"blue";
}
}
})
</script>
</body>
</html>
六、v-if 和 v-show 的使用
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>v-if,v-show</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!--v-if 相當於 是對 dom元素的 刪除 和 添加-->
<div v-if="show">hello world</div>
<!--
作者:offline
時間:2019-03-24
描述:v-if v-else-if v-else 在使用的時候一定要放在一起,中間不能有其他的元素
隔斷,否則瀏覽器編譯報錯
-->
<div v-if="x === 'a'">this is a </div>
<div v-else-if="x === 'b'">this is b</div>
<div v-else>this is other</div>
<!--
作者:offline
時間:2019-03-24
描述:給input 輸入框添加一個唯一標識key,這樣可以防止在改變show的時候
將清空之前輸入框中的值
-->
<div v-if="show">
用戶名:<input type="text" key="username"/>
</div>
<div v-else>
郵箱: <input type="text" key="password"/>
</div>
<!--
作者:offline
時間:2019-03-24
描述:v-show則是沒有真正的將dom元素進行刪除添加操作,僅僅只是對style樣式的
display屬性的改變。來讓dom元素實現顯示和隱藏。因此在 頻繁顯示和隱藏的功能上
我們更加推薦使用v-show
-->
<div v-show="show">hello world!!</div>
</div>
<script type="text/javascript">
var vm = new Vue({
el:"#app",
data:{
show: false,
x: "a"
}
});
</script>
</body>
</html>
七、v-for 的用法
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>v-for</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!--數組的操作 push、 pop、 shift、 unshift、 splice、 sort、 reverse-->
<!--當我們使用app.list[3] = {id:"004",title:"redis"} 向數組中添加元素的時候
發現頁面上面不會動態 的更新,我們需要用 上面的數組操作函數才行。
app.list.splice(1,1,{id:"004",title:"redis"})
或者我們直接更改整個 list的引用對象即可。
-->
<template v-for="(item,index) of list" :key="item.id">
<div>
{{item.title}}---{{index}}
</div>
<span>
{{item.title}}
</span>
</template>
<!--
作者:offline
時間:2019-03-24
描述:v-for 也可以用來循環遍歷對象
當我們直接使用app.userInfo.address ="北京"時發現對象 確實
新增了一個address屬性,但是頁面上也沒有動態更新顯示,
我們可以直接更改 整個對象的引用地址。
app.userInfo = {
name:"Dell",
age:28,
gender:"male",
address:"北京"
}
-->
<div v-for="(item,key,index) of userInfo">
{{item}}---{{key}}---{{index}}
</div>
<button @click="insertAddress">給用戶添加一個屬性</button>
</div>
<script type="text/javascript">
var app = new Vue({
el: "#app",
data: {
list: [{
id: "001",
title: "hadoop"
},
{
id: "002",
title: "spark"
},
{
id: "003",
title: "flink"
}
],
userInfo: {
name: "Dell",
age: 28,
gender: "male"
}
},
methods:{
insertAddress:function(){
//還有一種最簡單的方式就是使用 vue 的全局set 函數直接修改或添加屬性到
//數組或者對象中
//vue 全局set 方法
Vue.set(this.userInfo,"address","北京");
Vue.set(this.list,"1",{id:"0020",title:"spark0"});
//vue 實例 set方法
this.$set(this.userInfo,"address1","湖北");
this.$set(this.list,"2",{id:"0030",title:"spark3"});
}
}
});
</script>
</body>
</html>
八、組件使用細節
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>組件使用細節</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<table>
<tbody>
<!--<row></row>
<row></row>
<row></row>-->
<!--因爲在tbody中必須時tr標籤,瀏覽器才能識別
所以我們不能直接寫成定義的row組件,需要用到is屬性-->
<tr is="row"></tr>
<tr is="row"></tr>
<tr is="row"></tr>
</tbody>
</table>
</div>
<script type="text/javascript">
Vue.component("row", {
data: function(){
return {
content:"this is a row"
}
},
template: "<tr><td>{{content}}</td></tr>"
});
var app = new Vue({
el: "#app"
});
</script>
<div id="app1">
<!--
作者:offline
時間:2019-03-24
描述:ref的用法
1.當ref 作用在普通標籤上面的時候,
this.$refs.引用名稱 獲取到的是這個dom元素
2.當red作用在 vue組件上面的時候,
this.$refs.引用名稱 獲取到的是組件實例的引用對象
-->
<div ref="my" @click="clickDiv">hello my lala lala !!!</div>
<counter ref="one" @change="handleChange" ></counter>
<counter ref="two" @change="handleChange" ></counter>
<div>{{total}}</div>
</div>
<script type="text/javascript">
//定義一個counter子組件
Vue.component("counter",{
data: function() {
return {
number:0
}
},
template:"<div @click='handlerSubClick'>{{number}}</div>",
methods:{
handlerSubClick:function () {
this.number++;
this.$emit("change")
}
}
});
var app1 = new Vue({
el:"#app1",
data:{
total:0
},
methods:{
clickDiv: function(){
alert(this.$refs.my.innerHTML);
},
handleChange:function () {
//獲取子組件的引用對象中的 number值
this.total = this.$refs.one.number+this.$refs.two.number;
}
}
});
</script>
</body>
</html>
九、父子組件傳值
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>父子組件傳值</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!--
作者:offline
時間:2019-03-24
描述:父組件通過屬性的形式向子組件傳值
,子組件通過事件通知的形式向父組件傳值
-->
<counter :count="3" @change="add"></counter>
<counter :count="2" @change="add"></counter>
<div>{{total}}</div>
</div>
<script type="text/javascript">
var counter = {
props: ['count'],
data: function() {
return {
number: this.count
}
},
template: "<div @click='handleClick'>{{number}}</div>",
methods: {
handleClick: function() {
this.number += 2;
this.$emit("change", 2);
}
}
};
var app = new Vue({
el: "#app",
components: {
counter: counter
},
data: {
total: 5
},
methods: {
add: function(step) {
this.total += step;
}
}
});
</script>
</body>
</html>
十、組件參數校驗與非props特性
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>組件參數校驗與非props特性</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<child content="hello world"></child>
</div>
<script type="text/javascript">
Vue.component("child",{
props:{
//參數校驗,只接受string或者number型的值
content:{
type:String,
required:true,
default:"default value", //默認值
validator:function(value){ //自定義校驗器
return value.length>5;
}
}
},
template:"<div>{{content}}</div>"
});
var app = new Vue({
el: "#app",
data: {
},
methods: {
}
});
</script>
</body>
</html>
十一、給組件綁定原生事件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>組件參數校驗與非props特性</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!--
作者:offline
時間:2019-03-24
描述:給組件 綁定原生事件,只需要加一個native 關鍵字即可
-->
<child @click.native="handleClick"></child>
</div>
<script type="text/javascript">
Vue.component("child", {
template: "<div>hello</div>"
});
var app = new Vue({
el: "#app",
data: {},
methods: {
handleClick: function() {
alert("123");
}
}
});
</script>
</body>
</html>
十二、 非父子組件之間的傳值
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>非父子組件之間的傳值(Bus總線/發佈訂閱/觀察者模式)</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<child content="Dell"></child>
<child content="Lee"></child>
</div>
<script type="text/javascript">
//使每個組件bus屬性上面都掛載一個vue實例
Vue.prototype.bus = new Vue();
Vue.component("child", {
props:{
content:String
},
data:function(){
return {
selfContent:this.content
}
},
template: "<div @click='handleClick'>{{selfContent}}</div>",
methods:{
handleClick:function () {
//alert(this.content);
this.bus.$emit('change',this.selfContent);
}
},
mounted:function () {
var this_ = this;
this.bus.$on('change',function(msg){
alert(msg);
this_.selfContent = msg;
});
}
});
var app = new Vue({
el: "#app",
data: {},
methods: {
handleClick: function() {
alert("123");
}
}
});
</script>
</body>
</html>
十三、在vue中使用插槽
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<body-content>
<!--
作者:offline
時間:2019-03-24
描述:組件中的dom元素就相當於插槽
-->
<div class="header" slot="header">header</div>
<div class="footer" slot="footer">footer</div>
</body-content>
</div>
<script type="text/javascript">
Vue.component("body-content", {
//通過slot標籤就可以使用插槽,如果父組件中的插槽,指定了slot屬性,這裏使用的時候
//通過slot標籤的name屬性就可以選擇使用插槽
template: `<div><slot name='header'>
<h1>default value</h1>
</slot>
<div class='content'>content</div>
<slot name='footer'></slot></div>`
});
var app = new Vue({
el: "#app"
});
</script>
</body>
</html>
十四、 vue中的作用域插槽
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue中的作用域插槽</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<child>
<template slot-scope="props">
<h1>{{props.item}}</h1>
</template>
</child>
<child>
<template slot-scope="props">
<h2>{{props.item}}</h2>
</template>
</child>
<child>
<template slot-scope="props">
<h3>{{props.item}}</h3>
</template>
</child>
</div>
<script type="text/javascript">
Vue.component("child", {
data: function() {
return {
list: [1, 2, 3, 4]
}
},
template: `<div>
<ul>
<slot v-for="item of list" :item=item>
</ul>
</div>`
});
var app = new Vue({
el: "#app"
});
</script>
</body>
</html>
十五、動態組件與v-once指令
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!--
作者:offline
時間:2019-03-24
描述:動態組件,component 標籤,type是child-one 頁面上
就顯示child-one ,是child-two就顯示child-two
-->
<component :is="type"></component>
<!--<child-one v-if="type==='child-one'">
</child-one>
<child-two v-if="type==='child-two'">
</child-two>-->
<button @click="handleClick">change</button>
</div>
<script type="text/javascript">
Vue.component("child-one", {
// v-once使組件內容不變的情況下只加載一次,提高性能
template:"<div v-once>child-one</div>"
});
Vue.component("child-two", {
template:"<div v-once>child-two</div>"
});
var app = new Vue({
el: "#app",
data:{
type:"child-one"
},
methods:{
handleClick:function () {
this.type= this.type==='child-one'?'child-two':'child-one';
}
}
});
</script>
</body>
</html>