目录
组件
组件创建方式
<!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>