day03_04 组件的创建
<body> <div id="app"> <my-component1></my-component1> <hr> <my-component2></my-component2> </div> <!-- 在被控制的 #app 外面,使用template元素定义组建的html模板结构 --> <template id="temp1"> <div> <h1>通过template元素定义的组建</h1> <h3>我也是</h3> </div> </template> <script> // 全局注册组建 //定义方式1: Vue.component('my-component1',{ template:'<h3>这是VUE定义的全局组建</h3>' }) //定义方式2: Vue.component('myComponent2',{ template:'#temp1' }) new Vue({ el: '#app', data: { }, methods:{ } }) </script> </body>
day03_05 组件中data
<body> <div id="app"> <mycom1></mycom1> </div> <script> Vue.component('mycom1',{ template:'<h1>这里是全局组件-----{{message}}</h1>', // 组件中的data和实例中的data不一样,实例中的data可以为一个对象,但是组建中的data必须为一个方法 // 并且组建中的data方法 中必须返回一个对象 data : function(){ return { message: '组件中的data' } } }) new Vue({ el: '#app', data: { }, methods:{ } }) </script> </body>
day03_06 组件中的methods
<body> <div id="app"> <mycom1></mycom1> <hr> <mycom1></mycom1> <hr> <mycom1></mycom1> <hr> </div> <template id="temp1"> <div> <input type="button" value="点我+1" @click="add"> {{count}} </div> </template> <script> //实现一个计数器的组建,每次点击按钮时+1 Vue.component('mycom1',{ template:'#temp1', //data必须为方法再返回一个对象的好处在于:每次返回一个对象的时候,可以创建一个新的对象,数据值不会跟其他元素调用该组件时串用 data:function(){ return {count:0} }, methods:{ add(){ this.count++ } } }) new Vue({ el: '#app', data: { }, methods:{ } }) </script> </body>
day03_07 组件切换-使用v-if和v-else
<body> <div id="app"> <a href="" @click.prevent="flag = true">登录</a> <a href="" @click.prevent="flag = flase">注册</a> <mycom1 v-if="flag"></mycom1> <mycom2 v-else="flag"></mycom2> </div> <!-- 登陆模板 --> <template id="temp1"> <div> <span>------欢迎来到登陆页面------</span><br> 账号:<input type="text"><br> 密码:<input type="text"><br> <input type="button" value="登陆"> <input type="button" value="注册"> </div> </template> <script> Vue.component('mycom1',{ template:'#temp1' }) Vue.component('mycom2',{ template:'<h1>注册组件</h1>' }) new Vue({ el: '#app', data: { flag:true }, methods:{ } }) </script> </body>
day03_08 组件切换-使用vue提供的component
<body> <div id="app"> <a href="" @click.prevent="compName = 'login'">登录</a> <a href="" @click.prevent="compName = 'register'">注册</a> <!-- vue提供了component 元素,来展示对应的组件模板 --> <!-- component元素的值如果写 组件名,需要用单引号''引起来,不然会默认为是一个对象--> <component :is="compName"></component> <!-- 目前为止,已学习VUE提供的标签有: --> <!-- 组件标签:component 组件模板标签template 动画标签transition transitionGroup--> </div> <!-- 登陆模板 --> <template id="temp1"> <div> <span>------欢迎来到登陆页面------</span><br> 账号:<input type="text"><br> 密码:<input type="text"><br> <input type="button" value="登陆"> </div> </template> <!-- 注册模板 --> <template id="temp2"> <div> <span>------欢迎来到注册页面------</span><br> 账号:<input type="text"><br> 密码:<input type="text"><br> <input type="button" value="注册"> </div> </template> <script> Vue.component('login',{ template:'#temp1' }) Vue.component('register',{ template:'#temp2' }) new Vue({ el: '#app', data: { compName:'login' }, methods:{ } }) </script> </body>
day03_09 组件切换-切换动画效果
1、给day03_08中的component 元素加上动画效果
<!-- 1、通过设置mode属性,元素先出去后再进来 --> <transition mode="out-in"> <component :is="compName"></component> </transition>
2、设置动画样式
<style> .v-enter, .v-leave-to{ opacity: 0; transform: translateX(150px); } .v-enter-active, .v-leave-active{ transition: all 0.5s ease; } </style>
效果如下:
day03_09【复习】组建定义的方式
<body> <div id="app"> <mycomp></mycomp> </div> <script> // 通过Vue.component注册一个全局的vue组件,同时为这个组件起了一个名称,可以让我们通过标签的方式 // 在页面中进行引用 // Vue.component('mycomp',{'template':{},date:{},methods:{}}) var login = { 'template':'<h1>helloworld</h1>' } //可以直接调用定义的对象 Vue.component('mycomp',login) new Vue({ el: '#app', data: { }, methods:{ } }) </script> </body>
day03_10 父组件向子组件传值
1、定义局部组件comp1 ,作为VM组件的子组件
2、尝试从父组件VM中直接用插值表达式的方式获取父组件中的值{{parentMsg}}
<script> var vm = new Vue({ el: '#app', data: { parentMsg:'父组件中的数据aaaaaaaa' }, methods: {}, components:{ comp1:{ template:'<h1>子组件的模板:---{{parentMsg}}</h1>' } } }); </script>
3、报错如下,提示找不到 parentMsg 这个属性或者方法。
4、父组件可以在引用子组件的时候,通过 属性绑定(v-bind :)的形式,自定义属性将数据传递给子组件,供子组件内部使用
5、需要在子组件中的props属性中定义从父组件传递给子组件的数据,定义为‘pMsg’ ,子组件中props所用的数据都是通过父组件传递给子组件的
6、通过插值表达式{{pMsg}}获取在props中定义的数据
<body> <div id="app"> <!-- 自定义属性 pMsg,将父组件中的数据parentMsg传过来--> <comp1 :pMsg="parentMsg"></comp1> </div> <script> var vm = new Vue({ el: '#app', data: { parentMsg:'父组件中的数据aaaaaaaa' }, methods: {}, components:{ comp1:{ template:'<h1>子组件的模板:---{{pMsg}}</h1>' }, props:['pMsg'] } }); </script> </body>
7、执行后发现报错如下:
百度后才知道踩了VUE的坑:子组件属性传值绑定时名称不能 有 大写,必须小写
于是将pMsg 改为 pmsg 后就可以了。
并且,从父组件传递过来的props中的值都是只读的,修改会报错。子组件本身的data数据都是可读可写的。
day03_11 父组件向组件传递方法(子组件向父组件中传值)
1、定义子组件模板,并在vm中引入子组件
<body> <div id="app"> <comp ></comp> </div> <!-- 组件模板 --> <template id="temp"> <div> <h1>这是子组件-----</h1> </div> </template> <script> //定义组件模板对象 var comp = { template:'#temp' } new Vue({ el: '#app', data: { }, methods:{ }, components:{ comp } }) </script> </body>
2、父组件可以在引用子组件的时候,通过事件绑定机制向子组件传递方法
①父组件中添加show方法
②在引用子组件comp 时,通过绑定事件的机制向子组件传递父组件中show 方法
<comp @func="show"></comp>
3、在子组件模板 中添加按钮触发事件’sonfunc‘用来接收 父组件传过来的方法
<!-- 组件模板 --> <template id="temp"> <div> <h1>这是子组件</h1> <input type="button" value="这是子组件的按钮,点击它触发父组件传递过来的func方法" @click="sonfunc"> </div> </template>
4、在子组件点击事件 sonfunc 中使用vue提供的$emit指令可以拿到父组件在引用子组件的时候,通过事件绑定机制传递过来的方法
//emit为触发,调用的含义
methods:{
sonfunc(){
this.$emit('func')
}
}
5、在调用父组件方法时,可以在方法中以添加参数的形式向父组件方法传递数据。
①、现在子组件中定义需要传递的数据对象
data(){
return {
person:{name:'zhangsan',age:10}
}
},
② 在 emit 指令中添加需要传递的对象数据
this.$emit('func',this.person)
③ 、在父组件方法中添加接收参数data ,用于子组件调用父组件show方法时所传过来的数据。
methods:{
show(data){
// console.log('这是父组件中的show方法:----'+data)
console.log(data)
}
},
打印结果如下:
总结:从而实现了父组件通过事件绑定机制向子组件传递方法,子组件通过调用父组件传过来的方法,以参数形式向父组件传递参数数据。
day03_12 组件案例:发表评论
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script src="../../lib/vue.js"></script> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div id="app"> <!-- 将父组件中的加载评论数据方法传递给子组件 --> <comp @parentfunc="loadComments"></comp> <ul class="list-group"> <li class="list-group-item" v-for="item in list" :key="item.id"> <span class="badge">{{item.user}}</span> {{item.content}} </li> </ul> </div> <template id ="temp1"> <div> <div class="form-group"> <label >评论人</label> <input type="text" class="form-control" v-model="user"> </div> <div class="form-group"> <label >评论内容</label> <input type="text" class="form-control" v-model="content"> </div> <div class="form-group"> <input type="button" value="发表评论" class="btn btn-primary" @click="fabiao"> </div> </div> </template> <script> var comp = { template :"#temp1", data(){ return { user:'', content:'' } }, methods:{ fabiao(){ //发表评论的逻辑 //1、评论数据存到localStorage中,模拟数据库 //2、组织出一个发表的评论对象 //3、将评论对象保存到localStorage中 // 3.1、localstrorage中只支持存放字符串,需要先调用JSON.stringfy将评论对象转成字符串 // 3.2、保存最新的数据之前,需要先从localstorage中获取之前的评论数据(String),转换为一个 // 数组对象(JSON.parse),然后把最新的评论push到这个数组 // 3.3、如果获取到的localstorage为空,则可以返回一个空数组[],防止JSON.parse报错 // 3.4 再次将最新的评论数组调用JSON.stringfy转换成字符串,然后调用localstorage.setItem() var content = {id:Date.now(),user:this.name,content:this.msg} var listConts = JSON.parse(localStorage.getItem('conts') || '[]') //unshift方法插入到最前面 listConts.unshift(content); localStorage.setItem('conts',JSON.stringify(listConts)) this.name = this.msg = '' this.$emit('parentfunc') } } } var vm = new Vue({ el: '#app', data: { list:[ {id:'1',user:'李白',content:'天生我才必有用'}, {id:'2',user:'江小北',content:'把酒问青天,天下谁人不识君'}, {id:'3',user:'张小黑',content:'草拟个dj'} ] }, created(){ this.loadComments(); }, methods:{ loadComments(){ this.list = JSON.parse(localStorage.getItem('conts') || '[]') } }, components:{ comp } }); </script> </body>
day03_13 ref获取dom元素
<body> <div id="app"> <input type="button" value="获取dom元素" @click="btn"> <!-- 通过ref来直接获取DOM元素 --> <h3 id="myh3" ref="myh3">hellow Vue</h3> <comp ref="mycomp"></comp> </div> <script> var comp = { template:'<h1>这是子组件</h1>', data(){ return { msg:'这是子组件中的date数据' } }, methods:{ func(){ console.log('这是子组件中的methods') } } } var vm = new Vue({ el: '#app', data: { }, methods:{ btn(){ //原始方法获取 //console.log(document.getElementById('myh3').innerText) //使用Vue提供给我们的ref,ref是英文单词 [reference:引用] 的缩写 // console.log(this.$refs.myh3.innerText) console.log(this.$refs.mycomp.func) } }, components:{ comp } }) </script> </body>