[vuejs掛載點(diǎn)妄讯,模板與實(shí)例的關(guān)系]
<body>
<div id='root'>
<h1>{{msg}}</h1>
</div>
<script>
new Vue({
el:'#root',
data:{
msg:'hello world'
}
})
</script>
</body>
掛載點(diǎn):element對應(yīng)的標(biāo)簽
上面的html中{{msg}}去掉
<div id='root'></div>
這個(gè)標(biāo)簽就稱之為vue實(shí)例的掛載點(diǎn)岳掐,因?yàn)橄旅娴膃l董习,也就是element正好與上面的標(biāo)簽的id對應(yīng)的上
模板:掛載點(diǎn)內(nèi)部的內(nèi)容
<h1>{{msg}}</h1>
這個(gè)就是模板枫慷,模板也可以有多種方式
new Vue({
el:'#root',
template:'<h1>{{msg}}</h1>',
data:{
msg:'hello world'
}
})
這種寫在實(shí)例里面也可以,所以模板就是掛載點(diǎn)內(nèi)部的內(nèi)容丑念,模板可以寫在掛載點(diǎn)內(nèi)部涡戳,也可以寫在實(shí)例里面template屬性里面
首先我們知道vue中有很多自定義指令,以v- 開頭脯倚,例如:v-text渔彰,v-bind,v-model, v-if,等
在這些指令中推正,部分指令之間是很容易被混淆胳岂,所以今天決定自己總結(jié)一下以下幾個(gè)相似指令之間的異同:
<!--區(qū)別:v-text打印出來包含標(biāo)簽 v-html不包含標(biāo)簽-->
<div class="root" v-text="number"></div>
<div class="root1" v-html="number"></div>
<!--點(diǎn)擊事件用v-on方法-->
<div id="root" v-on:click="tomyclick">{{number}}</div>
<!--點(diǎn)擊事件用@方法-->
<div id="root1" @click="tomyclick">{{number}}</div>
<script>
new Vue({
el:".root",
data:{
number:"<h1>這是v-text方法</h1>"
},
})
new Vue({
el:".root1",
data:{
number:"<h1>這是v-html方法</h1>"
},
})
new Vue({
el:"#root",
data:{
number:"這是v-on:click方法"
},
methods:{
tomyclick : function(){
this.number = "點(diǎn)擊之后的效果用v-on方法"
}
}
})
new Vue({
el:"#root1",
data:{
number:"這是v-on:click方法"
},
methods:{
tomyclick : function(){
this.number = "點(diǎn)擊之后的效果用@方法"
}
}
})
</script>
</body>
1、屬性綁定
v-bind :
<div id="root">
<div v-bind:title="title">hello world</div>
</div>
<script>
new Vue({
el:"#root",
data:{
title:"this is hello world"
}
})
</script>
v-bind可以縮寫為“:”
即<div v-bind:title="title">hello world</div>可以寫為
<div :title="title">hello world</div>
單向綁定:數(shù)據(jù)決定頁面的顯示舔稀,但頁面不能決定數(shù)據(jù)的內(nèi)容
雙向綁定:數(shù)據(jù)決定頁面的顯示乳丰,但頁面也能修改數(shù)據(jù)的內(nèi)容
用v-model實(shí)現(xiàn)雙向綁定
<div id="root">
<input type="text" v-model:value="content">//當(dāng)修改input的值時(shí),content的值也會(huì)做相應(yīng)修改
<div>{{content}}</div>
</div>
<script>
new Vue({
el:"#root",
data:{
content: "this is content"
},
})
</script>
2内贮、vue中的計(jì)算屬性和偵聽器
2.1計(jì)算屬性computed:一個(gè)屬性通過其他屬性計(jì)算而來
fullName由firstName和lastName計(jì)算而來.
當(dāng)firstName和lastName不發(fā)生變化時(shí)产园,fullName不會(huì)重新計(jì)算而是調(diào)用緩存值汞斧,提高了程序效率。
<div id="root">
姓:<input type="text" v-model:value="firstName">
名:<input type="text" v-model:value="lastName">
<div>{{fullName}}</div>
<div>{{count}}</div>
</div>
<script>
new Vue({
el: "#root",
data: {
firstName: '',
lastName: '',
},
//計(jì)算屬性
computed:{
fullName: function () {
return this.firstName+" "+this.lastName
}
},
})
</script>
2.1偵聽器watch:監(jiān)聽某個(gè)數(shù)據(jù)的變化什燕,一旦數(shù)據(jù)發(fā)生變化粘勒,就可以在偵聽器中進(jìn)行邏輯計(jì)算
<div id="root">
姓:<input type="text" v-model:value="firstName">
名:<input type="text" v-model:value="lastName">
<div>{{fullName}}</div>
</div>
<script>
new Vue({
el: "#root",
data: {
firstName: '',
lastName: '',
fullName: ''
},
watch:{
firstName:function () {
this.fullName=this.firstName+" "+this.lastName;
},
lastName: function () {
this.fullName=this.firstName+" "+this.lastName;
}
}
})
</script>
計(jì)算屬性computed的getter和setter:
<div id="root">
{{fullName}}
</div>
<script>
var vm=new Vue({
el: "#root",
data: {
firstName: 'Dell',
lastName: 'Lee',
fullname: 'Dell Lee'
},
computed:{
fullName:{
get: function () {
return this.firstName+" "+this.lastName
},
set: function (value) {
var arr=value.split(" ");
this.firstName=arr[0];
this.lastName=arr[1];
}
}
}
})
[vuejs里面v-if,v-show和v-for]
<div id='root'>
<div v-if='show'>helle world</div>
<button @click='handleClick'>toggle</button>
</div>
<script>
new Vue({
el:'#root',
data:{
show:true
},
methods:{
handleClick:function(){
this.show = !this.show;
}
}
})
</script>
v-if,里面這個(gè)show是個(gè)變量屎即,如果是true就是顯示庙睡,如果是false就不顯示,這里是移除了dom
<div id='root'>
<div v-show='show'>helle world</div>
<button @click='handleClick'>toggle</button>
</div>
<script>
new Vue({
el:'#root',
data:{
show:true
},
methods:{
handleClick:function(){
this.show = !this.show;
}
}
})
</script>
v-show技俐,把v-show替換掉v-if乘陪,表現(xiàn)形式一樣,但是和v-if不同的是雕擂,v-show只是將dom隱藏啡邑,顯示,并沒有移除dom井赌,只是把display的樣式變了
如果顯示的頻率大谤逼,v-show比v-if要性能高一些,因?yàn)椴粫?huì)去銷毀dom仇穗,和創(chuàng)建dom,如果顯示的頻率不是那么大流部,只要一次顯示隱藏,那么v-if是更好的選擇
<div id='root'>
<ul>
<li v-for='item of list' :key='item'>{{item}}</li>
</ul>
</div>
<script>
new Vue({
el:'#root',
data:{
list:[1,2,3]
}
})
</script>
當(dāng)你給元素標(biāo)簽加key值得時(shí)候纹坐, vue會(huì)知道它是頁面上唯一的一個(gè)元素贵涵,如果兩個(gè)key不一樣,vue不會(huì)復(fù)用
v-for,當(dāng)某個(gè)數(shù)據(jù)需要循環(huán)顯示的時(shí)候恰画,可以用v-for,這里需要注意加:key宾茂,可以提升性能,但是這個(gè)item變量要是唯一的拴还,如果數(shù)組是[1,1,3]跨晴,這個(gè)item就不能作為key值,需要將
v-for='item of list'
改成
v-for='(item,index) of list'片林,
將索引index作為key值端盆,這樣是唯一的,但是index作為key值费封,在對列表排序等操作的時(shí)候可能存在問題
一個(gè)簡單的todolist
<script type="text/javascript" src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="root">
<div>
<input v-model = "inputValue"/>
<button @click = "handleSubmit">提交</button>
</div>
<ul>
<li v-for = "(item , index) of list" :key = "index">{{item}}</li>
</ul>
</div>
<script>
new Vue({
el:"#root",
data:{
inputValue:'999',
list:[]
},
methods:{
handleSubmit:function(){
this.list.push(this.inputValue),
this.inputValue = ''
}
}
})
</script>
運(yùn)用組件化的概念進(jìn)行整改
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>vue學(xué)習(xí)</title>
<script type="text/javascript" src="./vue.js"></script>
</head>
<body>
<div id = "app">
<input type="text" v-model = "interValue"/>
<button v-on:click = "handleBtnClick">提交</button>
<ul>
<!-- <li v-for = "item in list">{{item}}</li> -->
<todo-item v-bind:content="item" v-for = "item in list"></todo-item>
</ul>
</button>
</div>
<script>
Vue.component("TodoItem",{
props : ["content"],
template : "<li>{{content}}</li>",
})
var app = new Vue ({
el : '#app',
data :{
list : [],
interValue : ''
},
methods : {
handleBtnClick : function(){
this.list.push(this.interValue)
this.interValue = ''
}
}
})
setTimeout(function() {
app.$data.content = '我要改變'
// app.content = '我要改變';
}, 2000)
</script>
</body>
</html>
需要注意四點(diǎn)就是
1.Vue.component 這樣使用的是全局組件
2.TodoItem 到節(jié)點(diǎn)運(yùn)用就成了todo-item
3.v-bind:content="item" 父組件把值傳給子組件
- props : ["content"]這樣接受
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>vue學(xué)習(xí)</title>
<script type="text/javascript" src="./vue.js"></script>
</head>
<body>
<div id = "app">
<input type="text" v-model = "interValue"/>
<button v-on:click = "handleBtnClick">提交</button>
<ul>
<!-- <li v-for = "item in list">{{item}}</li> -->
<todo-item v-bind:content="item"
v-bind:index="index"
v-for = "(item, index) in list"
@delete = "handleItemDelete"
></todo-item>
</ul>
</button>
</div>
<script>
// Vue.component("TodoItem",{
// props : ["content"],
// template : "<li>{{content}}</li>",
// })
var TodoItem = {
props : ["content","index"],
template : "<li @click = 'handleItemClick'>{{content}}</li>",
methods : {
handleItemClick : function(){
this.$emit('delete',this.index)
},
}
}
var app = new Vue ({
el : '#app',
components :{
TodoItem : TodoItem,
},
data :{
list : [],
interValue : ''
},
methods : {
handleBtnClick : function(){
this.list.push(this.interValue)
this.interValue = ''
},
handleItemDelete : function(index){
this.list.splice(index,1)
}
}
})
setTimeout(function() {
app.$data.content = '我要改變'
// app.content = '我要改變';
}, 2000)
</script>
</body>
</html>
需要注意四點(diǎn)就是
1var TodoItem 這樣使用的是局部組件焕妙,創(chuàng)建了一對象
2.components :{
TodoItem : TodoItem,
},
把局部組件注冊到根實(shí)例里面。
3.template : "<li @click = 'handleItemClick'>{{content}}</li>", 這里是列表cell添加點(diǎn)擊事件
4.@delete = "handleItemDelete" 這里父組件在創(chuàng)建子組件的時(shí)候進(jìn)行監(jiān)聽
- this.開頭的都是vue的實(shí)例屬性跟實(shí)例方法
生命周期函數(shù)就是vue的實(shí)例在某一個(gè)時(shí)間點(diǎn)會(huì)自動(dòng)執(zhí)行的函數(shù)。生命周期函數(shù)并不在methosd韧献,單獨(dú)寫在實(shí)例里末患。
init-->beforeCreate -->created--> beforeMount -->mounted -->beforeDestroy -- >destroyed
大圖解析研叫,
v-xxx=""后面的字符串是js表達(dá)式¤嫡耄可以+操作
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
reversedMessage: function () {
// `this` 指向 vm 實(shí)例
return xxxx
}
}
});
關(guān)于計(jì)算屬性優(yōu)點(diǎn)就是他能緩存嚷炉,提高性能,頁面重新渲染的探橱,計(jì)算屬性依賴的值給沒有發(fā)生改變申屹,這個(gè)時(shí)候計(jì)算屬性就不會(huì)計(jì)算,提高性能.用方法的形式也可以實(shí)現(xiàn)計(jì)算的結(jié)算隧膏,但是頁面只要渲染方法就會(huì)調(diào)用哗讥,用監(jiān)聽器也可以實(shí)現(xiàn)這個(gè)功能,也會(huì)有緩存私植。
<!DOCTYPE html>
<html lang="en">
<head>
<meta content="text/html; charset=utf-8" />
<title>Vue</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="root">{{fullName}}</div>
<script>
var vm = new Vue({
el : '#root',
data :{
firstName : 'Dell',
lastName : 'Lee'
},
computed :{
fullName : {
get :function (){
return this.firstName + " " +this.lastName
},
set :function(value){
console.log(value);
var array = value.split(" ");
this.firstName = array[0];
this.lastName = array[1];
}
}
}
})
</script>
</body>
</html>
計(jì)算屬性跟set跟get方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta content="text/html; charset=utf-8" />
<title>Vue</title>
<script src="./vue.js"></script>
<style>
.acivated{
color: red
}
</style>
</head>
<body>
<div id="root" :class = "[acivated]" @click = "handleClick">{{content}}</div>
<script>
var vm = new Vue({
el : '#root',
data : {
content : '我是內(nèi)容',
acivated : ''
},
methods : {
handleClick : function(){
this.acivated = this.acivated === "acivated" ? "" : "acivated";
}
}
})
</script>
</body>
</html>
知識(shí)點(diǎn)
1.:class = "[acivated]" 這里主要是表示class這塊的東西,這是一個(gè)數(shù)組可以添加多個(gè)车酣,樣式就有這個(gè)數(shù)組里面的東西決定曲稼。
同樣的東西,這里是style的用法湖员,可以在 :style = "[styleObj {fontSize : '20px'}]"
如果是按照數(shù)組下標(biāo)的方法進(jìn)行操作數(shù)組贫悄,頁面沒有及時(shí)渲染,想要及時(shí)渲染娘摔,要用系統(tǒng)提供的七個(gè)方法窄坦。
push pop shift unshift splice sort reverse
當(dāng)然你也可以直接替換數(shù)據(jù)的引用地址,這樣也能改變渲染凳寺。
還有一個(gè)方法就是用set修改鸭津,也可數(shù)據(jù)改變之后頁面也改變
Vue.set(vm.userInfo,1,5)
一個(gè)比較重要的模板占位符 template 可以包裹 元素,但是 渲染的時(shí)候并不會(huì)真正的渲染到頁面中肠缨。
直接修改vm.userInfo.name = "Dell Lee"可以在頁面中立刻渲染
但是想添加 vm.userInfo.address = "beijing" 這樣數(shù)據(jù)是添加進(jìn)去了逆趋,但是不能立即渲染。
想立即改變要直接改變數(shù)據(jù)引用地址晒奕,就是直接改好數(shù)據(jù)闻书,直接把引用引到新數(shù)據(jù)下面。
其實(shí)用set方法修改脑慧,也能讓數(shù)據(jù)改變之后頁面也立刻改變魄眉。
例如 Vue.set(vm.userInfo,"address","beijing")
vue遇到問題解析
1.有些時(shí)候自定義的標(biāo)簽在使用起來發(fā)現(xiàn)出問題了闷袒,table--> tbody -->tr就是tbody下面必須是tr標(biāo)簽坑律,要不就就會(huì)出問題,這個(gè)時(shí)候要做的是用 is=“”來處理
2.子組件的data必須是一個(gè)函數(shù)不能是一個(gè)對象.
3,添加ref 添加引用囊骤,便于操作dom節(jié)點(diǎn)
<!DOCTYPE html>
<html lang="en">
<head>
<meta content="text/html; charset=utf-8" />
<title>Vue</title>
<script src="./vue.js"></script>
</head>
<body>
<div id="root">
<couter ref = "one" @change = "handeleChange"></couter>
<couter ref = "two" @change = "handeleChange"></couter>
<div>{{total}}</div>
</div>
<script>
Vue.component('couter',{
template : '<div @click = "handleClick">{{number}}</div>',
data :function(){
return {
number : 0
}
},
methods :{
handleClick : function(){
this.number ++;
this.$emit('change')
}
}
})
var vm = new Vue({
el : '#root',
data : {
total : 0
},
methods : {
handeleChange : function(){
this.total = this.$refs.one.number + this.$refs.two.number
}
}
})
</script>
</body>
</html>
涉及到父子組件傳值的概念
單向數(shù)據(jù)流:父組件給子組件傳遞參數(shù)脾歇,傳遞過得參數(shù)可以隨意修改蒋腮,但是子組件不能修改父組件傳遞過來的內(nèi)容。原因傳遞過來的數(shù)據(jù)如果是引用數(shù)據(jù)類型的數(shù)據(jù)藕各,如果你修改了 數(shù)據(jù)就是修改了原始數(shù)據(jù)池摧。
校驗(yàn)器
@click.nataive 這個(gè)就是監(jiān)聽的原生的click事件,并非自定義的
非父子組件進(jìn)行傳值
created:在模板渲染成html前調(diào)用激况,即通常初始化某些屬性值作彤,然后再渲染成視圖。
mounted:在模板渲染成html后調(diào)用乌逐,通常是初始化頁面完成后竭讳,再對html的dom節(jié)點(diǎn)進(jìn)行一些需要的操作。
var this_ = this 是因?yàn)樽饔糜虬l(fā)生了變化浙踢,有一個(gè)function绢慢,this變成了function了
,要保存一下
插槽語法洛波,方便插入dom元素胰舆,還可以定義默認(rèn)內(nèi)容 ,還能給插槽給一個(gè)name蹬挤,這樣可以對應(yīng)缚窿,根據(jù)name變換插槽
動(dòng)態(tài)組件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試實(shí)例 - 動(dòng)態(tài)組件</title>
<script src="https://cdn.bootcss.com/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
<button @click='toShow'>點(diǎn)擊顯示子組件</button>
<!----或者<component v-bind:is="which_to_show" keep-alive></component>也行----->
<keep-alive>
<component v-bind:is="which_to_show" ></component>
</keep-alive>
</div>
<script>
// 創(chuàng)建根實(shí)例
new Vue({
el: '#app',
data:{
which_to_show:'first'
},
methods:{
toShow:function(){
var arr = ["first","second","third"];
var index = arr.indexOf(this.which_to_show);
if(index<2){
this.which_to_show = arr[index+1];
}else{
this.which_to_show = arr[0];
} console.log(this.$children);
}
},
components:{
first:{
template:'<div>這是子組件1<div>'
},
second:{
template:'<div>這是子組件2<div>'
},
third:{
template:'<div>這是子組件3<div>'
},
}
})
</script>
</body>
</html>
v-once 指令,可以讓把組件第一次被渲染之后會(huì)放到內(nèi)存里面
這個(gè)東西很有意思焰扳,這邊整體解釋一下動(dòng)畫的東西倦零,首先就是fade-enter 跟fade-enter-active在動(dòng)畫開始的第一幀就已經(jīng)存在,然后第二幀的時(shí)候 fade-enter 被干掉吨悍,增加fade-enter-to ,到結(jié)束之后這個(gè)時(shí)候fade-enter-active扫茅,fade-enter-to被干掉。與opacity:0這個(gè)被去掉育瓜,恢復(fù)原有的默認(rèn)屬性诞帐,為1.此時(shí),監(jiān)聽到opacity變化爆雹,fade-enter-active開始運(yùn)行停蕉,會(huì)做一個(gè)漸變。