目錄
組件
組件創建方式
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>創建組件1</title>
<script src="../../../thirdlib/vue/vue.min.js"></script>
</head>
<body>
<div id="app">
<!--如果要使用組件,直接把組件的名稱以HTML標籤的形式引入到頁面中即可-->
<!--駝峯樣式需要將字母小寫,然後用-分隔-->
<my-com1></my-com1>
</div>
<script>
//1.1使用Vue.extend來創建全局Vue組件
/*var com1 = Vue.extend({
//通過template屬性,指定了組件要展示的html結構
template: '<h3>這是用Vue.extend創建的組件</h3>'
})*/
//1.2使用Vue.component('組建的名稱', 創建出來的組件模板對象)
//Vue.component('myCom1', com1);
//這裏也可以不用分開
Vue.component('myCom1', Vue.extend({
template: '<h3>這是用Vue.extend創建的組件</h3>'
}));
var vm = new Vue({
el:"#app",
data:{
},
methods:{
}
})
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>創建組件2</title>
<script src="../../../thirdlib/vue/vue.min.js"></script>
</head>
<body>
<div id="app">
<my-com1></my-com1>
</div>
<script>
Vue.component('myCom1', {
template:'<div><h3>這是直接使用Vue.component創建的組件</h3><span>123</span></div>'
});
var vm = new Vue({
el:"#app",
data:{
},
methods:{
}
})
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>用template創建組件</title>
<script src="../../../thirdlib/vue/vue.min.js"></script>
</head>
<body>
<div id="app">
<my-com1></my-com1>
</div>
<div id="app2">
<my-com2></my-com2>
</div>
<!--在被控制的#app外面 使用template元素,定義組件的模板元素-->
<template id="tmpl">
<div>
<h1>這是通過template在外部定義的組件結構,這個方式有代碼的提示</h1>
<h4>好用</h4>
</div>
</template>
<script>
Vue.component('myCom1', {
template:'#tmpl'
});
var vm = new Vue({
el:"#app",
data:{
},
methods:{
}
});
var vm2 = new Vue({
el:"#app2",
data:{
},
methods:{
},
components:{
//定義實例內部私有組件
myCom2:{
template:'#tmpl'
}
}
})
</script>
</body>
</html>
組件中的data和methods
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>組件中data和methods</title>
<script src="../../../thirdlib/vue/vue.min.js"></script>
</head>
<body>
<div id="app">
<mycom1></mycom1>
<hr />
<mycom1></mycom1>
<hr />
<mycom1></mycom1>
<hr />
</div>
<template id="temp">
<div>
<input type="button" value="+1" @click="add" />
<h3>{{ count }}</h3>
</div>
</template>
<script>
//1.組件可以有自己的data數據,
//2.組件的data和實例的data不一樣。實例 的data是一個對象;組件中的data是一個function,並且return一個對象。
//3.組件中的data和實例中的data使用方式完全一樣
Vue.component('mycom1', {
template:'#temp',
data:function(){
return {
count:0
}
},
methods:{
add(){
this.count ++;
}
}
});
var vm = new Vue({
el:"#app",
data:{
},
methods:{
}
})
</script>
</body>
</html>
組件切換方式
<div id="app">
<a @click.prevent="flag = true" href="">登錄</a>
<a @click.prevent="flag = false" href="">註冊</a>
<login v-if="flag"></login>
<regest v-else></regest>
</div>
<script>
Vue.component('login', {
template:'<h3>登錄組件</h3>'
});
Vue.component('regest', {
template:'<h3>註冊組件</h3>'
});
var vm = new Vue({
el:"#app",
data:{
flag:false
},
methods:{
}
})
</script>
<div id="app">
<a @click.prevent="flag = 'login'" href="">登錄</a>
<a @click.prevent="flag = 'regest'" href="">註冊</a>
<!--Vue提供了component, 來展示對應名稱的組件-->
<!--component是一個 佔位符 ,:is屬性 , 可以用來指定要展示的組件名稱-->
<component :is="flag"></component>
</div>
<script>
//組件名稱是字符串
Vue.component('login', {
template:'<h3>登錄組件</h3>'
});
Vue.component('regest', {
template:'<h3>註冊組件</h3>'
});
var vm = new Vue({
el:"#app",
data:{
flag:'login'
},
methods:{
}
})
</script>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>組件切換動畫</title>
<script src="../../../thirdlib/vue/vue.min.js"></script>
<style>
.v-enter,
.v-leave-to {
opacity: 0;
transform: translateX(150px);
}
.v-enter-active,
.v-leave-active {
transition: all 0.5s ease;
}
</style>
</head>
<body>
<div id="app">
<a @click.prevent="flag = 'login'" href="">登錄</a>
<a @click.prevent="flag = 'regest'" href="">註冊</a>
<!--Vue提供了component, 來展示對應名稱的組件-->
<!--component是一個 佔位符 ,:is屬性 , 可以用來指定要展示的組件名稱-->
<!--通過mode屬性設置組件切換時候的 方式-->
<transition mode="out-in">
<component :is="flag"></component>
</transition>
</div>
<script>
//組件名稱是字符串
Vue.component('login', {
template:'<h3>登錄組件</h3>'
});
Vue.component('regest', {
template:'<h3>註冊組件</h3>'
});
var vm = new Vue({
el:"#app",
data:{
flag:'login'
},
methods:{
}
})
</script>
</body>
</html>
父組件向子組件傳值
<div id="app">
<!--父組件可以在引用子組件的時候,通過自定義屬性綁定的形式v-bind將數據傳遞到子組件-->
<com1 v-bind:parentmsg="msg"></com1>
</div>
<script>
var vm = new Vue({
el:"#app",
data:{
msg:"123 父組件中的數據"
},
methods:{},
components:{
com1:{
//結論:子組件中默認無法訪問到父組件中data中的數據和methods中的方法
template:"<h1 @click='change'>處理這是子組件---{{ parentmsg }}</h1>",
//data數據並不是父組件傳遞過來的,而是自身私有的
//比如,組件通過ajax請求的數據,都可以放在data身上
//data中的數據,都是可讀可寫的,props中的數據都是隻讀的
data:function(){
return {
title:"123",
content:"111"
}
},
//組件中的所有props中的數據,都是通過父組件傳遞給子組件的
props : [//把父組件傳遞過來的parentmsg,在props中定義一下,這樣才能使用這個數據
'parentmsg'
],
methods:{
change(){
}
}
}
}
})
</script>
父組件把方法傳遞給子組件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>父組件把方法傳遞給子組件</title>
<script src="../../../thirdlib/vue/vue.js"></script>
</head>
<body>
<div id="app">
{{ msg }}
<!--父組件向子組件傳遞方法使用的是 事件綁定機制v-on-->
<!--這裏不用帶括號,直接將方法的引用傳給子組件-->
<com2 v-on:func="show"></com2>
</div>
<template id="temp">
<div>
<h1>這是子組件</h1>
<input type="button" @click="myclick" value="父組件傳遞的func方法"/>
</div>
</template>
<script>
var com2 = {
template:'#temp',
data(){
return {
sonmsg:{name:'小頭兒子', age:6}
}
},
methods:{
myclick(){
//如何拿到父組件的show方法,拿到func方法
//emit 英文原意 : 是觸發、調用的意思
//參數依次寫在後面
this.$emit('func', this.sonmsg, 321);
}
}
}
var vm = new Vue({
el:"#app",
data:{
msg : null
},
methods:{
show(data, data2){
this.msg = data;
console.log('調用了父組件身上的show方法:' + data + data2);
}
},
components:{
com2:com2
}
})
</script>
</body>
</html>
案例:評論添加及列表顯示
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>評論列表</title>
<script src="../../../thirdlib/vue/vue.js"></script>
<link rel="stylesheet" href="../../../thirdlib/css/bootstrap.min.css" />
</head>
<body>
<div id="app">
<cmtbox @fresh="loadComments" @test="test"></cmtbox>
<ul class="list-group">
<li v-for="item in list" :key="item.id" class="list-group-item">
<span class="badge">{{ item.user }}</span>
{{ item.content}}
</li>
</ul>
</div>
<template id="tmpl">
<div>
<div class="form-group">
<label>評論人:</label>
<input v-model="user" type="text" class="form-control" />
</div>
<div class="form-group">
<label>評論內容:</label>
<textarea v-model="content" class="form-control"></textarea>
</div>
<div class="form-group">
<input @click="add" type="button" value="發表評論" class="btn btn-primary" />
</div>
</div>
</template>
<script>
var commentBox = {
template : "#tmpl",
data(){
return {
user:"",
content:""
}
},
methods:{
add(){
var comment = {id:Date.now(), user : this.user, content:this.content};
//從localstorage獲取所有評論
var list = JSON.parse(localStorage.getItem('cmts') || '[]');
list.push(comment);
//保存最新的評論數據
localStorage.setItem('cmts', JSON.stringify(list));
this.user = this.content = "";
//觸發父組件的刷新數據方法
//可以同時綁定多個父組件方法
this.$emit('fresh');
this.$emit('test');
}
}
}
var vm = new Vue({
el:"#app",
data:{
list:[
{id:Date.now(), user:'李白', content:'天生我材必有用'},
{id:Date.now(), user:'白居易', content:'蜀道之難'},
{id:Date.now(), user:'江小白', content:'勸君更盡一杯酒'}
]
},
methods:{
loadComments(){
//從本地localStorage中加載評論
var locallist = JSON.parse(localStorage.getItem('cmts') || '[]');
this.list = locallist;
},
test(){
console.log("ok");
}
},
components:{//組件
cmtbox:commentBox
},
created(){
this.loadComments();
}
})
</script>
</body>
</html>
ref獲取dom和組件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ref獲取dom和組件</title>
<script src="../../../thirdlib/vue/vue.js"></script>
</head>
<body>
<div id="app">
<input type="button" ref="btn" value="獲取元素" @click="getele" />
<h3 ref="myh3">哈哈哈</h3>
<hr />
<login ref="mylogin"></login>
</div>
<script>
var login = {
template:'<h1>登錄組件</h1>',
data(){
return {
msg:"組件msg"
}
},
methods:{
show(){
console.log("調用子組件的方法");
}
}
}
var vm = new Vue({
el:"#app",
data:{
},
methods:{
getele(){
//ref 是 reference 引用
//console.log(this.$refs.myh3.innerText);
console.log(this.$refs.mylogin.msg);
this.$refs.mylogin.show();
}
},
components:{
login : login
}
})
</script>
</body>
</html>