1.vue組件
1.1局部組件的使用
var App = {
tempalte:`
<div class='app'></div>`
};
//2.掛子
<App />單閉合 雙閉合均可以
new Vue({
el:"#app",
//用子
template:<App />
components:{
App
}
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
body{
color: #fff;
}
.main{
width: 100%;
}
.head{
width: 100%;
height: 70px;
background-color: purple;
text-align: center;
font-size: 20px;
line-height: 70px;
}
.wrap{
width: 100%;
height: 1200px;
}
.wrap .aside{
width: 30%;
height: 1200px;
background-color: green;
float: left;
}
.wrap .content{
width: 70%;
height:1200px;
background-color:yellowgreen;
float: left;
}
</style>
</head>
<body>
<div id="app">
</div>
<script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script>
<script type="text/javascript">
// 打油詩: 先聲子 掛子 用子
// 1.先聲明頭部組件
var Vheader = {
template:`
<header class='head'>
我是頭部
<span>{{count}}</span>
<button @click = 'count+=1'>點擊</button>
</header>
`,
data(){
return {
count: 0
}
},
methods:{
}
};
var Vaside = {
template:`
<div class='aside'>
我是側邊欄
</div>
`
};
var Vcontent = {
template:`
<div class='content'>
我是內容區域
</div>
`
}
// 1.聲明入口組件
/*
1.頭部組件
2.側邊欄
3.內容組件
4.腳步組件
*/
// 局部組件 我是入口組件
//<Vheader></Vheader>雙閉合
//<Vaside />單閉合
var Vmain = {
template:`
<div class='main'>
<Vheader></Vheader>
<div class='wrap'>
<Vaside />
<Vcontent />
</div>
</div>
`,
components:{
// 等價於Vheader:Vheader 2.掛載子
Vheader,
Vaside,
Vcontent
}
}
new Vue({
el:"#app",
// 3.使用子組件
template:`<Vmain />`, //入口組件
data:{
},
components:{
// 2.掛載子組件 key表示組件名 value:組件對象
Vmain:Vmain
}
});
</script>
</body>
</html>
1.2父組件向子組件傳遞數據:經過Prop
1.在子組件自定義特性。props:['自定義的屬性1','自定義屬性2']
當一個值傳遞給一個 prop 特性的時候,它就變成了那個組件實例的一個屬性,那麼咱們就能夠像訪問data中的值同樣
2.要在父組件中導入的子組件內部 綁定自定義的屬性 <Vheader :title = '父組件中data聲明的數據屬性'/>
注意:一個組件默承認以擁有任意數量的 prop,任何值均可以傳遞給任何 prop。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
body{
color: #fff;
}
.main{
width: 100%;
}
.head{
width: 100%;
height: 70px;
background-color: purple;
text-align: center;
font-size: 20px;
line-height: 70px;
}
.wrap{
width: 100%;
height: 1200px;
}
.wrap .aside{
width: 30%;
height: 1200px;
background-color: green;
float: left;
}
.wrap .content{
width: 70%;
height:1200px;
background-color:yellowgreen;
float: left;
}
</style>
</head>
<body>
<div id="app">
</div>
<script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script>
<script type="text/javascript">
// 打油詩: 先聲子 掛子 用子
// 1.先聲明頭部組件
var Vheader = {
template:`
<header class='head'>
<span>{{title}}</span>
<span>{{count}}</span>
<button @click = 'count+=1'>點擊</button>
</header>
`,
data(){
return {
count: 0
}
},
props:['title'],
methods:{
}
};
var Vaside = {
template:`
<div class='aside'>
我是側邊欄
</div>
`
};
//自定義組件時,使用v-for,必需要有:key = 'post.id'
var Vcontent = {
template:`
<div class='content'>
<ul>
<li v-for = 'post in posts' :key = 'post.id'>
<h3>個人博客標題:{{post.title}}</h3>
<p>個人博客內容:{{post.content}}</p>
</li>
</ul>
<button @click='changeSize'>改變字體大小</button>
</div>
`,
props:['posts'],
methods:{
changeSize(){
// 經過$emit()方法來觸發自定義的事件
// 第一個參數是自定義的事件名字 第二個參數就是傳遞的值
// this指的vue實例化對象的子類
this.$emit('postChangeSize',3)
}
}
};
var Vmain = {
data(){
return{
fontsize:18
}
},
template:`
<div class='main' :style = '{fontSize:fontsize+"px"}'>
<Vheader v-bind:title = 'title'></Vheader>
<div class='wrap'>
<Vaside />
<Vcontent v-bind:posts = "appPosts" @postChangeSize = 'clickHandler'/>
</div>
</div>
`,
methods:{
clickHandler(value){
this.fontsize = this.fontsize+value;
}
},
components:{
// 等價於Vheader:Vheader 2.掛載子
Vheader,
Vaside,
Vcontent
},
props:['title','appPosts']
}
new Vue({
el:"#app",
// 3.使用子組件
template:`<Vmain :title = "text" :appPosts = "posts"/>`,
data:{
text:"vita熱愛學習,想要成爲大牛!!加油加油gogogo!",
posts:[
{id:1,title:"組件中的傳值",content:"經過Prop傳遞數據"},
{id:2,title:"組件中的傳值2",content:"經過Prop傳遞數據2"},
{id:3,title:"組件中的傳值3",content:"經過Prop傳遞數據3"},
]
},
components:{
// 2.掛載子組件 key表示組件名 value:組件對象
Vmain:Vmain
}
});
</script>
</body>
</html>
1.3子組件傳遞數據到父組件
1.給子組件中的某個按鈕綁定原聲事件,。咱們能夠調用內建的 this.$emit('自定義的事件名','傳遞的數據'),來向父級組件觸發一個自定義的事件.
2.在父組件中的子組件標籤中 要綁定自定義的事件,
上面的例子中,更改字體大小的按鈕事件,就使用了 this.$emit
1.4全局組件.slot組件
Vue.component('全局組件的名字',{
跟new Vue() 實例化對象中的options是同樣,可是要注意:
無論是公共組件仍是局部組件 data必須是個函數 函數必定要返回 {}
})
#slot
Vue.component('Vbtn', {
template: `<button class='defalut' :class='type'>
<slot></slot>
</button>`,
props: ['type']
});
//全局組件使用的時候,不須要components:注入
var Vheader = {
data() {
return {
}
},
template: `<div id='head'>
<Vbtn>登陸</Vbtn>
<Vbtn>註冊</Vbtn>
<Vbtn>提交</Vbtn>
<Vbtn>默認的按鈕</Vbtn>
<Vbtn type='primary'>主要的按鈕</Vbtn>
<Vbtn type='success' >成功的按鈕</Vbtn>
</div>`
};
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
* {
padding: 0;
margin: 0;
}
#head {
width: 100%;
height: 80px;
background-color: purple;
}
.defalut {
display: inline-block;
line-height: 1;
white-space: nowrap;
cursor: pointer;
background: #fff;
border: 1px solid #dcdfe6;
border-color: #dcdfe6;
color: #606266;
text-align: center;
box-sizing: border-box;
outline: none;
margin: 0;
transition: .1s;
font-weight: 500;
padding: 12px 20px;
font-size: 14px;
border-radius: 4px;
}
.primary {
color: #fff;
background-color: #409eff;
border-color: #409eff
}
.success {
color: #fff;
background-color: #67c23a;
border-color: #67c23a;
}
</style>
</head>
<body>
<div id="app">
</div>
<script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script>
<script type="text/javascript">
// 建立公共組件
// 第一個參數是公共組件的名字,第二個參數options
Vue.component('Vbtn', {
template: `<button class='defalut' :class='type'>
<slot></slot>
</button>`,
props: ['type']
});
//全局組件使用的時候,不須要components:注入
var Vheader = {
data() {
return {
}
},
template: `<div id='head'>
<Vbtn>登陸</Vbtn>
<Vbtn>註冊</Vbtn>
<Vbtn>提交</Vbtn>
<Vbtn>默認的按鈕</Vbtn>
<Vbtn type='primary'>主要的按鈕</Vbtn>
<Vbtn type='success' >成功的按鈕</Vbtn>
</div>`
};
// 局部組件的使用
var App = {
template: `<div>
<Vheader></Vheader>
</div>`,
components: {
Vheader
}
}
new Vue({
el: '#app',
data() {
},
template: `<App />`,
components: {
App
}
});
</script>
</body>
</html>
2.過濾器
###局部過濾器
//1.註冊局部過濾器 在組件對象中定義
filters:{
'過濾器的名字':function(value){
}
}
//2.使用過濾器 使用管道符 |
{{price | '過濾器的名字'}}
##### 全局過濾器
// 註冊全局的過濾器
//第一個參數是過濾器的名字,第二個參數是執行的操做
Vue.filter('reverse',function(value) {
return value.split('').reverse().join('');
});
//使用跟 局部過濾器同樣
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
</style>
</head>
<body>
<div id="app">
<input type="text" v-model = 'price'>
<h3>{{ price | currentPrice}}</h3>
<h4>{{msg | reverse}}</h4>
</div>
<script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script>
<script type="text/javascript">
// 註冊全局的過濾器
Vue.filter('reverse',function(value) {
return value.split('').reverse().join('');
})
new Vue({
el: '#app',
data() {
return{
price:0,
msg:"hello vita"
}
},
// 局部過濾器 在當前 組件中聲明過濾器
filters:{
currentPrice:function (value) {
// 參數1就是純滌的元數據
console.log(value);
return '$' + value;
}
}
});
</script>
</body>
</html>
3.計算屬性
3.1偵聽多個屬性:計算屬性watch
偵聽的是單個屬性
watch:{
數據屬性的名字:function(value){
},
數據屬性的名字2:function(value){
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<input type="text" v-model='myName'>
<h3>{{ myName}}</h3>
<button @click='clickHandler'>修改</button>
</div>
<script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script>
<script type="text/javascript">
new Vue({
el:'#app',
template:``,
data(){
return {
myName:'',
firtName:'VV'
}
},
methods:{
clickHandler(){
this.myName = 'vita';
}
},
watch:{
// 檢測單個屬性 命令式
myName:function(value) {
console.log(value);
if (value === 'vita') {
console.log(value +' '+this.firtName+'愛學習,想要成爲大牛,加油gogogogogogo!!!')
}
}
}
});
</script>
</body>
</html>
3.2偵聽多個屬性:計算屬性 computed
計算屬性 :默認只有getter方法
compuetd:{
key:value
計算屬性的方法名:funtion(){
return ${this.name}他的年齡是${this.age}
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<h4>{{vitaDesc}}</h4>
<button @click='clickHandler'>修改</button>
</div>
<script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script>
<script type="text/javascript">
new Vue({
el:'#app',
template:``,
data(){
return {
myName:'vita',
age:18
}
},
methods:{
clickHandler(){
this.myName = 'VITA';
this.age = 28;
}
},
computed:{
vitaDesc:function() {
var str = `${this.myName}它的年齡是${this.age},努力成爲大牛,加油加油,gogogo!`;
// 默認只有getter
return str;
}
}
});
</script>
</body>
</html>
3.3計算屬性的setter方法
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<h4>{{vitaDesc}}</h4>
<button @click='clickHandler'>修改</button>
</div>
<script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script>
<script type="text/javascript">
new Vue({
el:'#app',
template:``,
data(){
return {
myName:'vita',
age:18
}
},
methods:{
clickHandler(){
console.log(this.vitaDesc);
this.vitaDesc = 'VITA !!!';
}
},
computed:{
vitaDesc:{
set:function(newValue) {
console.log(newValue);
this.myName = newValue;
},
get:function() {
var str = `${this.myName}它的年齡是${this.age}歲了,努力學習,成爲大牛,加油gogogo!`;
// 默認只有getter
return str;
}
}
}
});
</script>
</body>
</html>
3.4setter的用途
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="app">
<input type="text" v-model = 'alexDesc'>
<h4>{{alexDesc}}</h4>
<!-- <button @click='clickHandler'>修改</button> -->
</div>
<script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script>
<script type="text/javascript">
new Vue({
el:'#app',
template:``,
data(){
return {
myName:'',
}
},
computed:{
alexDesc:{
set:function(newValue) {
this.myName = newValue;
},
get:function() {
return this.myName;
}
}
}
});
</script>
</body>
</html>
3.5計算屬性之音樂播放器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
ul{
list-style: none;
}
ul li {
margin: 30px 20px;
padding: 10px;
}
ul li.active{
background-color: #20FFFF;
}
</style>
</head>
<body>
<div id="music">
<audio :src="currentSrc" controls autoplay></audio>
<ul>
<li v-for = '(item,index) in musics' @click = 'clickHandler(index)' :class = '{active:currentIndex == index}'>
<h2>{{item.id}}--歌曲爲:{{item.name}}</h2>
<p>歌手:{{item.author}}</p>
</li>
</ul>
</div>
<script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script>
<script type="text/javascript">
var musicData = [{
id: 1,
name: '於榮光 - 少林英雄',
author: '於榮光',
songSrc: './static/於榮光 - 少林英雄.mp3'
},
{
id: 2,
name: 'Joel Adams - Please Dont Go',
author: 'Joel Adams',
songSrc: './static/Joel Adams - Please Dont Go.mp3'
},
{
id: 3,
name: 'MKJ - Time',
author: 'MKJ',
songSrc: './static/MKJ - Time.mp3'
},
{
id: 4,
name: 'Russ - Psycho (Pt. 2)',
author: 'Russ',
songSrc: './static/Russ - Psycho (Pt. 2).mp3'
}
];
new Vue({
el: '#music',
data() {
return {
musics:musicData,
currentIndex:0
// musicSrc:'./static/於榮光 - 少林英雄.mp3'
}
},
methods:{
clickHandler(index){
// alert(index);
this.currentIndex = index;
}
},
computed:{
currentSrc(){
// 監聽了兩個屬性 musics currentIndex
return this.musics[this.currentIndex].songSrc;
}
},
template: ``
});
</script>
</body>
</html>
4.生命週期
4.1生命週期的方法
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app">
<App></App>
</div>
<script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script>
<script type="text/javascript">
// 鉤子函數
// beforeCreate
// created
// beforeMount
// mounted
// beforeUpdate
// updated
// activated
// deactivated
// beforeDestroy
// destroyed
// 建立 銷燬
var Test = {
data(){
return{
msg:"哈哈哈"
}
},
template:`
<div>
<div>{{msg}}</div>
<button @click = 'changeHandler'>修改</button>
</div>
`,
methods:{
changeHandler(){
this.msg = this.msg + 'vita'
}
},
beforeCreate(){
// 組件建立以前
console.log("beforeCreate-----------", this.msg);
},
created(){
// 組件建立以後
// 使用該組件,就會觸發以上的鉤子函數,created中能夠操做數據,發送ajax,而且能夠實現vue==》頁面的影響 應用:發送ajax請求
console.log("created-----------", this.msg);
// this.msg = '嘿嘿黑';
},
beforeMount(){
// 裝載數據到DOM以前會調用
console.log("beforeMount-----------", document.getElementById('app'));
},
mounted(){
// 這個地方能夠操做DOM
// 裝載數據到DOM以後會調用 能夠獲取到真實存在的DOM元素,vue操做之後的DOM
console.log("mounted-----------", document.getElementById('app'));
},
beforeUpdate(){
// 在更新以前,調用此鉤子,應用:獲取原始的DOM
console.log("beforeUpdate-----------", document.getElementById('app').innerHTML);
},
updated(){
// 在更新以前,調用此鉤子,應用:獲取最新的DOM
console.log("updated-----------", document.getElementById('app').innerHTML);
},
//因爲性能問題,咱們都不會使用消除組件和建立組件的方式,而是使用is-show的方式
beforeDestroy(){
console.log("beforeDestroy-----------", 'beforeDestroy');
},
destroyed(){
console.log("destroyed-----------", 'destroyed');
},
//
activated(){
console.log("activated-----------", '組件被激活了');
},
deactivated(){
console.log("deactivated-----------", '組件被停用了');
}
}
var App = {
data(){
return {
isShow : true
}
},
//<keep-alive>讓當前的組件產生緩存,提升前端的性能
template:`
<div>
<keep-alive>
<Test v-if = 'isShow'></Test>
</keep-alive>
<button @click = 'changeHandler'>改變組件的生死</button>
</div>
`,
methods:{
changeHandler(){
this.isShow = !this.isShow;
}
},
components:{
Test
}
}
new Vue({
el:'#app',
template:``,
components:{
App
}
});
</script>
</body>
</html>
4.2使用$refs獲取DOM元素
// $屬性:
// $refs獲取組件內的元素
// $parent:獲取當前組件的父組件
// $children:獲取當前組件的子組件
// $root:獲取New Vue的實例化對象
//$el:獲取組件對象的DOM元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script>
<script type="text/javascript">
Vue.component('subComp',{
template:`<div></div>`
})
var App = {
template: `<div>
<subComp ref = 'subc'></subComp>
<button ref = 'btn'>我是按鈕</button>
<p ref = 'sb'>vita</p>
</div>`,
beforeCreate() {
console.log(this.$refs.btn);//undefined
},
created() {
console.log(this.$refs.btn);//undefined
},
beforeMount() {
console.log(this.$refs.btn); //undefined
},
mounted() {
console.log("this----------",this);
console.log("this.$refs.btn取到的是DOM對象----------",this.$refs.btn);
// 若是是給組件綁定的ref = 'subc'屬性那麼this.$refs.subc取到的是組件對象
console.log("this.$refs.subc取到的是組件對象----------",this.$refs.subc);
var op = this.$refs.sb;
this.$refs.btn.onclick = function() {
console.log("op.innerHTML", op.innerHTML);
}
}
}
new Vue({
el: '#app',
data() {
return {
}
},
template: `<App />`,
components: {
App
}
});
</script>
</body>
</html>
4.3使用$nextTick的特殊狀況
獲取更新以後的dom添加事件的特殊狀況
nextTick 是在下次Dom更新循環結束以後執行的延遲迴調,在修改數據以後使用$nextTick ,則能夠在回調中獲取更新以後的DOM
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="./node_modules/vue/dist/vue.min.js"></script>
<script type="text/javascript">
var App = {
data(){
return{
isShow:false
}
},
template: `<div>
<input type="text" v-if = 'isShow' ref = 'fos'/>
</div>`,
mounted() {
// vue實現響應式並非數據發生變化以後DOM馬上發生變化,而是按必定的策略進行DOM的更新
//更新DOM
this.isShow = true;
//這裏是獲取不到DOM元素的,不能設置focus()
console.log( this.$refs.fos);
// $nextTick 是在下次Dom更新循環結束以後執行的延遲迴調,在修改數據以後使用$nextTick ,則能夠在回調中獲取更新以後的DOM
this.$nextTick(function() {
// 獲取更新以後的DOM
this.$refs.fos.focus()
});
}
}
new Vue({
el: '#app',
data() {
return {
}
},
template: `<App />`,
components: {
App
}
});
</script>
</body>
</html>