1 导入vue:
2 <script src="vue.min.js"></script>
3 创建vm实例
4 var vm=new Vue({
5 el:'#app',//指定要控制的元素
6 data:{},
7 methods:{}
8 })
9 在id为app的div里

一、指令学习

1.v-cloak、v-text、v-bind、v-html、v-on

 1 <div id="app">
2 <h2>1.v-cloak、-text、-bind、-HTML、-on指令</h2>
3 <p>{{msg}}</p>
4 <!--使用 v-cloak 能够解决 插值表达式闪烁的问题 ,还能对值拼接-->
5 <p v-cloak>v-cloak:+++++++++++{{msg}}----------</p>
6 <!--使用v-text没有闪烁问题,覆盖元素中的原本内容,-->
7 <p v-text="msg">v-text:======================</p>
8
9 <!--使用v-html:将msg解析为HTML格式,也会覆盖原本内容-->
10 <div>{{msg2}}</div>
11 <div v-text="msg2"></div>
12 <div v-html="msg2">111111</div>
13
14 <!--使用v-bind:vue提供的用于绑定属性的指令 简写为:,还可以拼接字符-->
15 <input type="button" value="v-bind指令" v-bind:title="mytitle +',我是拼接的'">
16
17 <!--使用v-on:绑定事件机制 简写为@-->
18 <input type="button" value="v-on指令" v-on:click="show">
19 <input type="button" value="v-on指令:mouseover" @mouseover="show2">
20 <br><br><br>
21 </div>

2.事件修饰符 :.stop   .prevent  .capture  .self  .once

 1 <h2>2.事件修饰符</h2>
2 <div class="inner" @click="divHandler">
3
4 <input type="button" value="戳它" @click.once="btnHandler"><br>
5 <!--默认:先btn的后div的-->
6 <!-- 内层加入.stop后,没有触发外层div -->
7
8 <a href="http://www.baidu.com" @click.prevent="linkclick">百度一下,你就知道</a>
9 <!-- 链接加入.prevent,阻止默认行为 -->
10
11 <!-- 外层使用.capture, 捕获机制->顺序为:先div后btn .capture加在外层-->
12
13 <!-- 外层使用.self,实现只有点击当前元素才会触发事件处理函数 -->
14
15 <!-- 使用.once,当前元素只触发一次 -->
16
17 </div>
18 <div class="outer" @click="div2Handler">
19 <div class="inner" @click.self="divHandler">
20 <input type="button" value="戳一下" @click="btnHandler">
21 <!-- 默认顺序:btn inner outer -->
22 <!-- .self只会阻止自己身上的冒泡,btn outer -->
23 </div>
24 </div>

3.v-model实现数据双向绑定

1  <h2>3.v-model实现表单数据双向绑定</h3>
2 <!-- v-bind:只能实现数据的单向绑定,从M自动绑定到V -->
3 <!-- <input type="text" v-bind:value="msg3"> -->
4 <input type="text" v-bind:value="msg3" v-model:value="msg3">
5 <!-- v-model :实现表单元素和model中数据的双向绑定,只能运用在表单元素中
6 input(radio,text,address,email...)select、CheckBox、textarea等
7 -->

4.v-for 循环遍历与迭代数字

 1 <h2>4.v-for循环遍历普通数组与对象</h3>
2 <!-- <p>{{list[0]}}</p><p>{{list[2]}}</p><p>{{list[3]}}</p> -->
3 <!-- <p v-for="item in list">{{item}}</p> -->
4 <!-- 注意:空格 -->
5 <p v-for="(user,i) in list">Id:{{user.id}} --- 名字:{{user.name}} --- 索引:{{i}}</p>
6 <p v-for="(val,key) in user">值:{{val}} --- 键:{{key}} </p>
7 <p v-for="(val,key,i) in user">值:{{val}} --- 键:{{key}} --- 索引:{{i}}</p>
8
9 <h3>4.1 v-for迭代数字</h3>
10 <!-- 从1开始迭代 -->
11 <p v-for="count in 4">这是第{{count}}次循环</p>
12 <!-- 2.20+以后, -->
13 <h4>魔道祖师</h4>
14 <div>
15 <label>
16 Id:
17 <input type="text" v-model="id">
18 </label>
19 <label >
20 Name:
22 <input type="text" v-model="name">
23 </label>
24
25 <input type="button" value="添加" @click="add">
26
27 </div>
28 <!-- 注意:v-for循环的时候,key属性只能使用number获取string -->
29 <!-- 注意:key 使用时,必须使用v-bind属性绑定的的形式 -->
30 <!-- 在组件中,使用v-for循环时,或者在一些特殊情况中,如果v-for有问题,得为它指定唯一的字符串/数字 类型 :key值 -->
31 <p v-for="item in list1" :key="item.id">
32 <input type="checkbox" >
33 {{item.id}} --- {{item.name}}
34 </p>

5.v-show与v-if

1 <h2>5. v-show与v-if</h3>
2
3 <input type="button" @click="flag=!flag" value="toggle">
4 <!-- v-if:每次都会重新删除或创建元素 ,
5 有较高的切换性能消耗,频繁切换情况不要用,用v-show-->
6 <h3 v-if="flag">这是v-if控制的元素</h3>
7 <!-- v-show:每次不会重新进行DOM的删除和创建操作,只是切换了元素的display:none样式 ,
8 有较高的初始渲染消耗,如果元素可能永远不会被显示出来被用户看到,用v-if-->
9 <h3 v-show="flag">这是v-show控制的元素</h3>

6.键盘修饰符

 1 <h2>6. 键值修饰符</h2>
2 <!-- 使用时为:@keyup.xxx="function" -->
3 <li>.enter</li>
4 <li>.tab</li>
5 <li>.delete</li>
6 <li>.esc</li>
7 <li>.space</li>
8 <li>.up</li>
9 <li>.down</li>
10 <li>.right</li>
11 <li>.left</li>
12 <li>.keycode(数字)</li>
  <!-- 测试自定义键盘修饰符 -->
  <input type="text" v-model="name" @keyup.f2="add"> 
  // 自定义全局修饰符
  Vue.config.keyCodes.f2=113;

 二、vue中的样式

1.内联样式-style

 1 <div id="app">
2 <!-- 对象就是无序的键值对的集合, 对象中有横线的不能省略单引号 -->
3 <h1 :style="{color:'red','font-weight':'200'}">这是一个h1</h1>
4 <h1 :style="styleObj">这是一个h1</h1>
5 <h1 :style=[styleObj,styleObj2]>这是一个h1</h1>
6
7 </div>
8
9 <script>
10 var vm=new Vue({
11 el:'#app',
12 data:{
13 styleObj:{color:'red','font-weight':'200'},
14 styleObj2:{'font-style':'italic'}
15 },
16 methods:{}
17 })
18 </script>

2.class样式

 1 <head><style>
2 .red{
3 color: red;
4 }
5 .thin{
6 font-weight: 200;
7 }
8 .italic{
9 font-style: italic;
10 }
11 .active{
12 letter-spacing: 0.5em;
13 }
14 .change{
15 color:green;
16 }
17 </style>
18 </head>
19 <body>
20 <div id="app">
21 <!-- 以前的使用方式 -->
22 <h1 class="red thin">大大无法想象</h1>
23 <!-- 第一种使用方式,直接传递一个数组,注意:这里的class得用v-bind绑定 -->
24 <h1 :class="['thin','italic']">很大,无法想象!!!</h1>
25 <!-- 在数组中使用三元表达式 -->
26 <h1 :class="['thin','italic',!flag?'active':'']">很大!!!</h1>
27 <!-- 在数组中使用对象来代替三元表达式提高可读性 -->
28 <h1 :class="['thin','italic',{'change':flag}]">很大!!!</h1>
29 <!-- 对象的属性是类名,可带引号也可不带,属性的值是一个标识符 -->
30 <!-- <h1 :class="{ red:true,thin:true,italic:false}">很大!!!</h1> -->
31 <h1 :class="classObj">很大!!!</h1>
32
33 </div>
34
35 <script>
36 var vm=new Vue({
37 el:'#app',
38 data:{
39 flag:true,
40 classObj:{ red:false,thin:true,italic:false,change:true}
41 },
42 methds:{}
43 })
44 </script>

三、过滤器filter

过滤器的定义语法:
       Vue.filter('过滤器的名称',function(){});// 过滤器中的function第一个参数,永远都是过滤器(管道符前面)传递过来的数据

 1   <div id="app">
4 <p v-html='msg'></p>
5
6 <!-- <p>{{ msg | msgFormat }}</p> -->
7 <!-- <p>{{ msg | msgFormat(' *****') }}</p> -->
8 <p>{{ msg | msgFormat('夷陵老祖',' *****','魏无羡') }}</p>
9 </div>
10 <script>
11
12 //定义一个全局过滤器:msgFormat
13 Vue.filter('msgFormat',function(msg,arg,arg2,arg3){
14 //字符串的 replace方法,第一个参数,除了可写一个字符串外,还可以定义正则
15 return msg.replace(/<br>/g,arg+arg2+arg3);//将换行符换成三个参数相连的样子
16 });
17
18 var vm=new Vue({
19 el:'#app',
20 data:{
21 msg:'魔道祖师:'+'<br>'+'<br>'
22 },
23 methods:{},
24 })
25 </script>

四、vue-resource

 1 <head>
2 <meta charset="UTF-8">
3 <title>Document</title>
4 <script src="../lib/vue.js"></script>
5 <!--1. 注意:vue-resource依赖于Vue,注意先后顺序 -->
6 <!-- this.$http. -->
7 <script src="../lib/vue-resource.js"></script>
8 </head>
9 <body>
10 <div id="app">
11 <input type="button" value="Get请求" @click="getInfo">
12 <input type="button" value="Post请求" @click="postInfo">
13 <input type="button" value="Jsonp请求" @click="jsonpInfo">
14 </div>
15 <script>
16 var vm=new Vue({
17 el:'#app',
18 data:{
19
20 },
21 methods:{
22 getInfo(){//发起get请求
23 // 当发起get请求之后,通过 .then来设置成功的回调函数
24 this.$http.get('http://www.liulongbin.top:3005/api/getlunbo').then(function(result){
25 console.log(result)
26 // 通过 result.body 拿到服务器返回的数据
27 });
28 // this.$http.jsonp("http://vue.studyit.io/api/getlunbo").then(result => {
29 // console.log(result.body);
30 // });
31 },
32 postInfo(){
33 // 手动发起的表单请求默认没有表单格式,有的服务器处理不了
34 // 通过post的第三个参数,设置,提交内容为普通表单数据格式
35 this.$http.post('http://www.liulongbin.top:3005/api/post',{},{emulateJSON:true}).then(result=>{
36 console.log(result.body)
37 })
38 },
39 jsonpInfo(){//发起jsonp请求
40 this.$http.jsonp('http://www.liulongbin.top:3005/api/jsonp').then(result=>{
41 console.log(result.body)
42 })
43 }
44 }
45 })
46 </script>

 六、生命周期函数

beforeCreate()、created()、beforeMount()、mounted()、beforeUpdate()

 1 <div id="app">
2 <input type="button" value="修改msg" @click="msg='NO'">
3 <h3 id="h3">{{msg}}</h3>
4 </div>
5
6 <script>
7
8 var vm=new Vue({
9 el:'#app',
10 data:{
11 msg:'----ok',
12 },
13 methods:{
14 show(){
15 console.log('执行了show方法')
16 }
17 },
18 beforeCreate() {//遇到第一个生命周期函数,表示示例被完全创建出来之前会执行它
19 console.log('beforeCreate:'+this.msg)
20 // this.show() is not a function
21 // 在beforeCreate()生命周期函数执行的时候,data 和 methods 中的数据都还没有被初始化
22 },
23 created() {//遇到的第二个生命周期函数
24 console.log('created:'+this.msg),
25 this.show()
26 // 在created函数中,data 和 methods都已被初始化好了
27 // 如果要调用methods里的方法,最早在created里执行
28
29 },
30 beforeMount() {//遇到的第三个生命周期函数,表示模板已经在内存中编辑完成了,但尚未把 模板 渲染到页面中
31 var a= document.getElementById("h3").innerText
32 console.log('beforeMount:'+a)
33 // 在beforeMount函数执行的时候,页面中的元素还没有被真正替换过来,只有之前写的一些模板字符串
34 },
35 mounted() {//遇到的第四个生命周期函数,表示内存中的模板已经真实的挂载到页面中,用户已经可以看到 渲染好的页面了
36 var a= document.getElementById("h3").innerText
37 console.log('mounted:'+a)
38 // 注意:mounted 是实例创建期间最后一个生命周期函数,当执行完mounted就表示,实例已经完全被创建好了,
39 // 此时如果没有其他操作的话 这个实例静静的躺在内存中
40 },
41 // 接下来是运行中的两个事件
42 beforeUpdate() {//这时候 表示 我们的界面还没被更新
43 console.log('beforeUpdate:界面上元素的内容'+document.getElementById('h3').innerText)//无效果,
44 //加button试试 --可以看出来了
45 console.log('data 中的 msg是'+this.msg)
46 // 结论:
47 // 当执行beforeUpdate的时候,页面中显示的数据还是旧的,此时 data数据是最新的,页面尚未和data保持同步
48 },
49 })
50 //结果:beforeCreate:undefined
        created:----ok
        执行了show方法
        beforeMount:{{msg}}
        mounted:----ok
     点击按钮之后打印新增:
        beforeUpdate:界面上元素的内容----ok
        data 中的 msg是NO
51 </script>

七、动画

1.不使用动画

 1 <div id="app">
2 <input type="button"value="toogle" @click="flag=!flag">
3 <!-- 需求:点击按钮,让h3显示,再次点击,隐藏 -->
4 <h3 v-if="flag">春风吹不倒,我的杨柳腰</h3>
5 </div>
6 <script>
7 var vm=new Vue({
8 el:'#app',
9 data:{flag:false},
10 })
11 </script>

2.使用过渡类名实现

 1 <!-- 自定义两组样式,来控制transition内部的元素实现动画 -->
2 <style>
3 .v-enter,
4 /* .vue-enter【这是一个时间点】是进入之前元素的起始状态,此时还没有开始进入 */
5 .v-leave-to{
6 /* 是动画离开之后,离开的终止状态,此时,元素动画已经结束了 */
7 opacity: 0;
8 transform: translateX(80px);
9 }
10
11 .v-enter-active,
12 /* [入场动画的时间段]*/
13 .v-leave-active{
14 /* [离场动画的时间段] */
15 transition: all 0.4s ease;
16 }
17 </style>
18 </head>
19 <body>
20 <div id="app">
21 <input type="button"value="toogle" @click="flag=!flag">
22 <!-- 需求:点击按钮,让h3显示,再次点击,隐藏 -->
23 <transition>
24 <h3 v-if="flag">春风吹不倒,我的杨柳腰</h3>
25 </transition>
26
27 <!-- 1.使用transition元素,把需要被动控制的元素,包裹起来 -->
28 <!-- transition 是Vue官方提供的 -->
29 </div>

3.使用第三方类:animate.css

 1  <link rel="stylesheet" href="../lib/animate.css">
2 <!-- 入场用bounceIn 离场bounceOut -->
3 </head>
4 <body>
5 <div id="app">
6 <input type="button"value="toogle" @click="flag=!flag">
7
8 <!-- 使用:duration="毫秒值"来设置入场离场时的动画时长 -->
9 <transition enter-active-class="bounceIn" leave-active-class="bounceOut":duration="400">
10 <h3 v-if="flag">春风吹不倒,我的杨柳腰</h3>
11 </transition>
12
13 <hr>
14 <input type="button"value="toogle1" @click="flag1=!flag1">
15 <!-- 使用:duration="{enter:,leave:}"设置出入场时间 -->
16 <transition
17 enter-active-class="bounceIn"
18 leave-active-class="bounceOut"
19 :duration="{enter:00,leave:400}">
20 <h3 v-if="flag1">春风吹不倒,我的杨柳腰</h3>
21 </transition>

4.修改v-前缀

 1   <style>
2 .my-enter,
3 .my-leave-to{
4 opacity: 0;
5 transform: translatey(80px);
6 }
7 .my-enter-active,
8 .my-leave-active{
9 transition: all 0.4s ease;
10 }
11 </style>
12 </head>
13 <body>
14 <div id="app">
15 <input type="button"value="toogle2" @click="flag2=!flag2">
16 <transition name="my">
17 <h4 v-if="flag2">月儿在手中开呀怀儿笑,云儿在那眼前睡得早</h4>
18 </transition>
19 </div>

5.使用钩子函数模拟小球动画

 1 <style>
2 .ball{
3 width:15px;
4 height:15px;
5 border-radius: 50%;
6 background-color:red;
7 }
8 </style>
9 </head>
10 <body>
11 <div id="app">
12 <input type="button" value="快到碗里来" @click="flag=!flag">
13
14 <transition
15 @before-enter="beforeEnter"
16 @enter="enter"
17 @after-enter="afterEnter">
18 <div class="ball" v-show="flag"></div>
19 </transition>
20
21 </div>
22 <script>
23
24 var vm=new Vue({
25 el:'#app',
26 data:{
27 flag:false,
28 },
29 methods:{
30 // 注意:动画钩子函数的第一个参数:el表示 要执行的动画的那个DOM元素,是个原生JS DOM对象
31 // el是通过docum.getElementByID(''),方法获取到的原生JS对象
32 beforeEnter(el){//表示动画入场之前,此时动画尚未开始,
33 // 可以在这里设置元素开始动画开始之前的起始样式
34 el.style.transform="translate(0,0)"//设置小球开始动画之前的起始位置
35 },
36 enter(el,done){
37 //这句话没有实际作用,不写没动画效果
38 el.offsetWidth//强制动画刷新
39 // 表示动画开始之后的样式,这里可以设置小球完成动画之后的结束状态
40 el.style.transform="translate(150px,450px)"
41 el.style.transition='all 1s ease'
42
43 // 立马消失?这里的done就是afterEnter函数,即,done为afterEnter函数的引用
44 done()
45 },
46 afterEnter(el){//动画完成之后
47 // el.style.transform="translate()"
48 // console.log("执行完毕!")
49 this.flag=!this.flag
50 }
51 },
52 })
53 </script>

6.列表的动画

 1  <script src="../lib/vue.js"></script>
2 <link rel="stylesheet" href="../lib/animate.css">
3 <style>
4 li{
5 border:1px solid #999;
6 margin: 5px;
7 line-height: 35px;
8 padding-left: 5px;
9 font-size: 12px;
10
11 width:100%
12 /* 解决设置absolute后,宽度的变化 */
13 }
14 li:hover{
15 background-color:pink;
16 transition: all 0.4s ease;
17 /* 悬停时,背景过渡 */
18 }
19 /* 固定组合,4个,实现进入时渐变,离开时渐变 */
20 .v-enter,
21 .v-leave-to{
22 opacity: 0;
23 transform: translateY(80px);
24 }
25 .v-enter-active,
26 .v-leave-active{
27 transition: all 1s ease;
28 }
29
30 /* 自编样式 前一个元素离开时,让剩下的渐变移动 ,与.v-leave-active:position为absolute一起使用*/
31 .v-move{
32 transition:all 1s ease;
33 }
34 /* absolute弊端:元素离开时宽度后发生变化,
35 解决:设置其宽为100%即可 */
36 .v-leave-active{
37 position: absolute;
38 }
39 </style>
40 </head>
41 <body>
42 <div id="app">
43 <div>
44 <label for="">
45 Id:
46 <input type="text" v-model="id">
47 </label>
48 <label for="">
49 Name:
50 <input type="text" v-model="name">
51 </label>
52
53 <input type="button" value="添加" @click="add">
54 </div>
55 <!-- <ul> -->
56 <!-- 在使用列表过渡的时候,如果需要过渡的元素,是通过v-for循环渲染出来的,不能使用transition包裹
57 需要使用transitionGroup -->
58 <!-- 给 transition-group添加appear,实现页面刚展示出来的时候的入场动画 -->
59 <!-- tag标签,指明将transition渲染为什么标签,不指定默认渲染为span -->
60 <transition-group appear tag="ul">
61 <!-- 要为v-for循环创建的元素设置动画,必须为每个元素设置 :key属性 -->
62 <!-- <li v-for="item in list" :key="item.id" @click="del(i)"> -->
63 <li v-for="(item,i) in list" :key="item.id" @click="del(i)">
64 <!-- 移除:@click 增加i元素-->
65 {{item.id}} ---{{item.name}}
66 </li>
67 </transition-group>
68 <!-- </ul> -->
69 </div>
70
71 <script>
72 var vm=new Vue({
73 el:'#app',
74 data:{
75 id:'',
76 name:'',
77 list:[
78 {id:1,name:'魏无羡'},
79 {id:2,name:'蓝忘机'},
80 {id:3,name:'江澄'},
81 {id:4,name:'金子轩'},
83 ]
84 },
85 methods:{
86 add(){
87 this.list.push({id:this.id,name:this.name})
88 },
89 del(i){
90 this.list.splice(i,1)
91 }
92 }
94 })
95 </script>

八、组件

1,组件之data和method

 1 <div id="app">
2 <mycom1></mycom1>
3 </div>
4
5 <script>
6 // 1.组件可以有自己的data数据
7 // 2.组件的 data 和实例的 data 有点不一样,实例中的data可以为一个对象,但是组件中的必须是一个方法
8 // 3.组件中的 data 除了必须为一个方法外,这个方法内部,还必须返回一个对象才行
9 // 4.组件中的 data 数据,使用方式和实例中的 data 使用方式完全一样
10 Vue.component('mycom1',{
11 template:'<h3>这是全局组件</h3>',
12 data:function(){
13 return{
14 msg:'这是组件中的data定义的数据'
15 }
16 }
17 })
 1 //组件的data必须是一个function
2 <div id="app">
3 <count></count>
4 <hr>
5 <count></count>
6 <hr>
7 <count></count>
8 </div>
9 <template id="tmpl">
10 <div>
11 <input type="button" @click="increment" value="加">
12 <h3>{{count}}</h3>
13 </div>
14 </template>
15
16 <script>
17 var dataObj={count:0}
18 //计数器组件,身上有个按钮,每当点击按钮,让 data 中的 count 值 + 1
19 Vue.component('count',{
20 template:'#tmpl',
21 // data:function(){ //data是一个function
22 data(){
23 // return dataObj //使用多个组件时,数据一样
24 return {count:0} //使用多个组件时,不关联
25 },
26 methods:{ //methods是一个对象
27 increment(){
28 this.count+=1
29 }
30 }
31 })
      </script>

2.组件之创建组件的方式 - 前4个外部定义

1)使用Vue.extend:

 1 <div id="app">
2 <!-- 如果要使用组件,直接把组件名称,以HTML标签的形式引入页面即可 -->
3 <!-- <myCom1></myCom1> 错误的-->
5 <my-com1></my-com1> //1
6 <mycom1></mycom1> //2
7 </div>
8 // 1.分两步
9 //1.1 使用vue.extend来创建全局vue组件
10 var com1= Vue.extend({
11 template:'<h3>这是使用Vue.extend 创建的组件</h3>'//通过template属性,指定了组件要展示的HTML结构
12 })
13 // 1.2 使用Vue.components('组件的名称',创建出来的组件模板对象)
14 Vue.component('myCom1',com1)
15 // 使用Vue.component定义全局组件时,若使用驼峰,则引用时大写改小写两单词之间用“——”链接
16 // 否则,直接写
17
18 // 2.一步解决
19 Vue.component('mycom1',Vue.extend({
20 template:'<h3>外部定义一:这是Vue.component里Vue.extend创建的组件</h3>'
21 }))
定义组件的时候,全局:Vue.component('组件名称',{})
    组件模板几种方式的创建,通过Vue.component吧组件模板电对象,注册为一个全局的vue组件,同时为这个组件起来一个名称,
    在页面以标签显示 引入组件
2)Vue.component('组件名称',{})
1  // 第二种
2 Vue.component('mycom2',{
3 // 注意:不论是哪种方式创建出来的组件,组件的template属性的模板内容,必须有且只有一个唯一的根元素
4 template:'<div><h3>外部定义二、这是使用Vue.component 创建的组件</h3> <span> 我是第二种方式里的其他标签</span></div>'
5 })

3)Vue.component('组件名称',{tamplate:'#tmpl'})

 1  <!-- 在被控制的#App外面 使用template元素定义组件的模板结构 依旧遵循唯一根元素-->
2 <template id="temp1">
3 <div>
4 <h3>外部定义三:这是通过 template 元素,在外部定义的组件结构,这个方式,有代码的只能提示和高亮</h3>
5 <h4>好用,不错</h4>
6 </div>
7 </template>
8
9 // 第三种
10 Vue.component('mycom3',{
11 template:'#temp1'
12 })

4) Vue.component('组件名称',对象)

1  // 第四种
2 var abc={ //通过对象 字面量的形式,定义了一个组件模板对象
3 template:'<h3>外包定义四、这是用对象承接了template组件,</h3>'
4 }
5 Vue.component('mycom4',abc)

5)内部定义

 1 // 内部定义第二种
2 var register={
3 template:'<h3>内部定义二:这是用对象承接的template</h3>'
4 }
5 var vm2=new Vue({
6 el:'#app2',
7 data:{},
8 methods:{},
9 filters:{},
10 directives:{},
11 components:{//定义内部私有组件
12 //1.内部定义第一种
13 login:{
14 // template:'<h3>这是私有的 login 组件</h3>'
15 template:'#templ2'
16 },
17 // '组件名称':组件模板
18 // 2.1内部定义第二种
19 // register
20 // 2.2内部定义第二种
21 'register':register//同上一个作用
22 },
23 })
24 </script>

3.组件之ref获取DOM元素和组件引用

 1 <div id="app">
2 <input type="button" value="获取元素" @click="getElement" ref="mybtn">
3 <h3 id="myh3" ref="myh3">纵然与世无争 道不同义在心中,怎奈侠肝义胆,却成一场空</h3>
4 <hr>
5 <login ref="mylogin"></login>
6 </div>
7 <script>
8 // 登录组件
9 var login={
10 template:'<input type="button" value="登录组件">',
11 data(){
12 return{
13 msg:'son msg'
14 }
15 },
16 methods: {
17 show(){
18 console.log("调用了子组件的方法")
19 }
20 },
21 }
22 var vm=new Vue({
23 el:'#app',
24 methods:{
25 getElement(){
26 // console.log(document.getElementById('myh3')) //值为h3
27 // console.log(document.getElementById('myh3').innerHTML)//值为h3的内容
            // console.log(document.getElementById('myh3').innerText)//值为h3的内容
28 // ref :reference引用 获取DOM结点
29 console.log(this.$refs.myh3.innerText) //myh3的内容
30 console.log(this.$refs.mybtn.innerHTML+'我是button的') //我是button的
31 console.log(this.$refs.mylogin.msg) //son msg
32 console.log(this.$refs.mylogin.show()) //结果:调用了子组件的方法->执行了show方法
33 // 结果 undefined -> 打印语句里调用的方法没返回值
34 }
35 },
36 components:{
37 login
38 }
39 })
40 </script>

4.组件之组件切换

1     <h3>第一种切换方式</h3>
2 <a href="" @click.prevent="flag=true">登录</a>
3 <a href="" @click.prevent="flag=false">注册</a>
4
5 <login v-if="flag"></login>
6 <register v-else="flag"></register>
7 <hr>
 1    <h3>第二种切换方式</h3>
2 <a href="" @click.prevent="comName='login'">登录</a>
3 <a href="" @click.prevent="comName='register'">注册</a>
4
5 <!-- vue提供了component,来展示对应名称的组件 -->
6 <!-- component是一个占位符,:is属性,指定要展示的组件的名称 -->
7 <!-- <component :is="componentId"></component> -->
8 <component :is="comName"></component>
9
10 <!-- 总结:当前学习的vue提供的标签:
11 component、template、transition、transition-group -->
12 <hr>
   var vm=new Vue({
        el:'#app',
        data:{
            flag:false,
            comName:'register',//当前 component 中的 :is 绑定的组件的名称
        },
        methods:{}
   })
1     <h3>实现切换动画</h3>
2 <a href="" @click.prevent="comName='login'">登录</a>
3 <a href="" @click.prevent="comName='register'">注册</a>
4
5 <!--通过 mode属性:out-in 设置组件切换时候的模式-->
6 <transition mode="out-in">
7 <component :is="comName"></component>
8 </transition>

5.组件之父组件向子组件传值

1 <div id="app">
2 <!-- 值:消息,props与data -->
3 <!--父组件可以在引用子组件的时候,通过属性绑定的形式(v-bind)的形式,把需要传递给子组件的数据,传过去 -->
4 <com1 v-bind:parentmsg="msg"></com1>
5 <div>
 1 var vm=new Vue({
2 el:'#app',
3 data:{
4 msg:'123 - 父组件中的数据',
5 datamsgFromson:null,
6 },
7 methods:{
8 show(data){
9 console.log('调用了父组件身上的show方法 --- '+data)
10 this.datamsgFromson=data
11 },
12 },
13 components:{
14 com1:{ // 子组件中默认无法访问父组件中,data 上的数据、methods 里的方法,如下
15 // template:'<h3>这是子组件 ---{{msg}}</h3>' //获取不到msg
16 template:'<h3 @click="change">这是子组件 ---{{parentmsg}}</h3>',//获取不到parentmsg
17
18 props:['parentmsg'],//把父组件传递过来的parentmsg属性,现在props数组中,定义一下,才能使用
19 // 注意:组件中的所有 props 中的数据,都是通过父组件传递给了子组件
20 // props中的数据都是只读的,
21
22 data(){ //子组件中的data数据并不是通过父组件传递的,而是自己私有的
23 // data里的数据都是可读可写的
24 return {
25 title:'666',
26 content:'qqq',
27 }
28 },
29 filters:{},
30 directives:{},
31 components:{},
32 methods: {
33 change(){ //给template里的标签添加绑定事件
34 this.parentmsg="被修改了"
35 }
36 },
37 },
                  com2:com2  //传递方法
38         }
39 })
40 </script>
1 <div id="app">
2 <!-- 值:methods -->
3 <!-- 父组件向子组件传递方法,使用的是事件绑定机制(v-on)当自定义了一个事件属性之后,子组件就能够通过某些方式来调用 方法 -->
4 <!-- <com2 v-on:fun="show"></com2> -->
5 <!-- 传参1 -->
6 <!-- <com2 @fun="show('哈哈')"></com2> -->
7 <!-- 未传参1 -->
8 <com2 @fun="show"></com2>
9 </div>
 1 <template id="tmpl2">
2 <div>
3 <h3>这是 子组件2</h3>
4 <input type="button"value="子组件中的按钮,点击触发父组件传递过来的方法" @click="myclick">
5 </div>
6 </template>
7
8
9 <script>
10 //另一种
11 var com2={
12 template:'#tmpl2',
13 data(){
14 return{
15 sonmsg:{name:'小头儿子',age:6}
16 }
17 },
18
19 methods: {
20 myclick(){
21 // console.log('1111')
22 // 当点击子组件按钮时,如何拿到父组件传递过来的func方法,并调用
23 //未传参2
24 // this.$emit('fun')
25 // 传参2
26 this.$emit('fun','哈哈')
27 // emit:英文原义- 触发、调用、发射
28 this.$emit('fun',this.sonmsg)
29 }
30 },
31 }

九、路由

1.路由的基本使用

<!-- 1.安装路由模块 -->
    <script src="../lib/vue-router.js"></script>
 1 // 2. 创建一路由对象,当导入vue-router包后,在window全局对象中,就有了一个路由的构造函数,叫做VueRouter
2 //在new 路由对象时,可以为构造函数,传递一个配置对象
3 var routerObj=new VueRouter({
4 // route //这个配置对象中的route表示 【路由配置规则】
5 routes:[ //路由配置规则
6 // 每个路由规则都是一个对象,这个对象身上有两个必须的属性,
7 // 属性1:path - 监听那个路由连接地址
8 // 属性2:component - 表示,如果路由是前面匹配到的path,则展示component属性对应的那个组件,
9 // 值为组件模板对象,不是引用名称
10 {path:'/',redirect:'/login'}, //这里的 redirect 完全是两码事
11 {path:'/login',component:login},
12 {path:'/register',component:register}
14 ], 
  })
      // 此处login为组件的模板对象
        var login={
            template:'<h3>登录组件</h3>'
        }
        //此处login为组件名称,不是对象,不能放到路由里,应选择上面的
         Vue.component('login',{
         template:'<h3>登录组件yaya</h3>'
         });
       var register={
           template:'<h3>注册组件</h3>'
       }
<div id="app">
        <!-- router-link:默认渲染为a标签 -->
        <router-link to="/login">登录</router-link>
        <router-link to="/register">注册</router-link>
        <!-- 这是vue-router 提供的元素,专门用来当做占位符的,将来路由规则、匹配到的组件,就会展示到这个router-view中
        可视router-view为占位符 -->
 
                <router-view></router-view>       
 
    </div>
1  var vm=new Vue({
2 el:'#app',
3 data:{},
4 methods:{},
5 router:routerObj //将路由规则对象注册到vm实例上,用来监听URL变化,然后展示组件
6
7 })

2.路由之修改样式:

1 <transition mode="out-in">
2 <router-view></router-view>
3 </transition>
一般样式如下:
    .v-enter,
    .v-leave-to{
        opacity: 0;
        transform:translateX(150px);
    }
    .v-enter-active,
    .v-leave-active{
        transition: all 0.5s ease;
    }
/* 修改样式第一种:修改自带的类样式  */
    .router-link-active{
        color:red;
        font-weight: 800;
        /* font-style: italic; */
        font-size: 20px;
        text-decoration: underline;
        background-color: green;
    }
/* 修改样式第二种,自定义样式,传给linkActiveClass */
    .myactive{
        color:green;
        font-weight: 400;
        background-color: pink;
    }
//增加linkActiveClass如下:
   var routerObj=new VueRouter({
 
            routes:[ //路由配置规则
 
            {path:'/',redirect:'/login'}, //这里的 redirect 完全是两码事
            {path:'/login',component:login},
            {path:'/register',component:register}
            ],
            // 修改样式第二种:通过linkActiveClass设置样式
            linkActiveClass:'myactive'
        })

3.路由的嵌套

 1     <div id="app">
2 <router-link to="/account">Account</router-link>
3 <router-view></router-view>
4 </div>
5
6 <template id="tmpl">
7 <div>
8 <h3>这是Account组件</h3>
9 <router-link to="/account/login">登录</router-link>
10 <router-link to="/account/register">注册</router-link>
11
12 <!-- 放置子路由组件的位置 -->
13 <router-view></router-view>
14 </div>
15 </template>
16
17 <script>
18 // 组件的模板对象
19 var account={
20 template:'#tmpl'
21 }
22 var register={
23 template:'<h4>注册组件</h4>'
24 }
25 var login={
26 template:'<h4>登录组件</h4>'
27 }
28 var router=new VueRouter({
29 routes:[
30 { path:'/account',
31 component: account,
32 children:[ //children:子路由,子路由的path前面不用带斜线,否则永远以根路径开始请求,不方便用户立即URL地址
33 {path:'login',component:login},
34 {path:'register',component:register}
35 ],
36 },
37 ]
38 })
39
40 var vm=new Vue({
41 el:'#app',
42 data:{},
43 methods:{},
44 router,
45 })
46 </script>

4.路由之使用命名规则实现经典布局

 1 <style>
2 .header{
3 background-color: orange;
4 height:80px;
5 }
6 .left{
7 background-color:lightgreen;
8 flex:2
9 }
10 .main{
11 background-color: lightpink;
12 flex:8;
13 }
14 .container{
15 display: flex;
16 height: 600px;
17 }
18 h2{
19 margin:0;
20 /* padding:0; */
21 font-size: 16px;
22 }
23 html,body{
24 margin:0;
25 padding:0;
26 }
27 </style>
28 </head>
29 <body>
30 <div id="app">
31 <router-view></router-view>
32 <div class="container">
33 <router-view name='left'></router-view>
34 <router-view name="main"></router-view>
35 </div>
36 </div>
37
38 <script>
39 // 模板
40 var header={
41 template:'<h2 class="header">Header头部区</h2>'
42 }
43 var leftBox={
44 template:'<h2 class="left">侧边栏区域</h2>'
45 }
46 var mainBox={
47 template:'<h2 class="main">主题、体区域</h2>'
48 }
49
50 // 创建路由对象
51 var router = new VueRouter({
52 routes:[
53 {
54 // {path:'/left',component:leftBox},
55 // {path:'/main',component:mainBox}
56 path:'/',components:{
57 'default':header,
58 'left':leftBox,
59 'main':mainBox
60 }
61 },
62 ]
63 })
64 var vm=new Vue({
65 el:'#app',
66 data:{},
67 methods:{},
68 router
69 })
70 </script>

十、vuex

 1 //项目入口     ---main.js文件
2
3 // console.log('ok')
4 import Vue from '../node_modules/vue/dist/vue.js'
5 // 1.运行cnpm i vue-x -S
6 // 2。导入vuex
7 import Vuex from "vuex"
8 // 3.注册vuex到vue中
9 Vue.use(Vuex)
10 // 4.new Vuex.Store()实例,得到一个数据仓储对象
11 var store=new Vuex.Store({
12 state:{
13 count:0
14 // 如果在组件中想要访问,store中的数据,只能通过this.$store.state.名称
15 //
16 },
17 // 注意:操作store中的state值,通过调用mutations提供的方法,
18 // 子组件想要调用mutation中的方法,只能使用this.$store.commit('方法名')
19 // mutations的参数列表中,最多支持两个参数,参数1:state状态,参数2:通过commit传递过来的值
20 mutations:{
21 increment(state){
22 state.count++;
23 },
24 subtract(state,obj){
25 // console.log(obj);
26 state.count-=(obj.c+obj.d);
27 },
28
29 },
30 getters:{
31 // 注意:这里的getters,只负责对外提供数据,不负责修改数据,修改state中的数据,找mutations
32 optCount:function(state){
33 return '当前最新的count值是:'+state.count
34 }
35 }
36 })
37
38
39 import app from './app.vue'
40
41 var vm=new Vue({
42 el:'#app',
43 render:c=>c(app),
44 //5.将vuex创建的store挂载到vm实例上
45 store:store
46 // 只要挂载到了vm上,可以全局使用了
47 })

组件一使用:

 1 <template>
2 <div>
3 <input type="button" value="减少" @click="del">
4 <input type="button" value="增加" @click="add">
5 <input type="text" v-model="this.$store.state.count">
6 </div>
7 </template>
8 <script>
9 export default {
10 methods:{
11 add(){
12 // this.$store.state.count++;
13 // 不符合vuex的设计概念
14 this.$store.commit('increment');
15 },
16 del(){
17 // this.$store.state.count--;
18 this.$store.commit('subtract',{c:3,d:4});
19 }
20 }
21 }
22 </script>

组件二使用:

 1 <template>
2 <div>
3 <!-- <h3>当前数量为:{{this.$store.state.count}}</h3> -->
4 <h3>{{this.$store.getters.optCount}}</h3>
5
6 </div>
7 </template>
8 <script>
9 export default {
10
11 }
12 </script>

最新文章

  1. prototype,__proto__,constructor
  2. Python之路【第十八章】:Web框架
  3. log4jWARN Please initialize the log4j system properly解决办法
  4. linux开机启动mongodb
  5. JQuery获取子节点的第一个元素
  6. POJ 3678 Katu Puzzle(强连通 法)
  7. sqlserver表数据导出为insert into语句
  8. keepalived初探
  9. Ubuntu 安装软件的命令
  10. JQuery上传插件uploadify整理(Options)
  11. ANDROID5.0触摸屏校准
  12. C#打印条码BarTender SDK打印之路和离开之路(web平凡之路)
  13. SQL Server 链接数据库 error:40
  14. 系列三VisualSvn Server
  15. 接收一个IT招聘促销信息,试着想参加,有兴趣的可以携手并进,共同。
  16. 【python】字符串变量赋值时字符串可用单或双引号
  17. 为什么腾讯有QQ,还要推出微信?
  18. django——中间件
  19. Android相关 博客收藏
  20. .NET Core微服务之路:文章系列和内容索引汇总 (v0.52)

热门文章

  1. python manage.py loaddata dumpdata 用于导出和导入数据库中的数据
  2. EF Core如何到回滚上一次迁移
  3. Ribbon负载均衡调用
  4. ORACLE 数据库备份脚本(数据泵2-指定用户)
  5. 利用python中的win32com模块操作Word、Excel文件
  6. HUAWEI——— 防火墙+ACL访问控制+AP上线+默认路由+NAT+DHCP(案例拓扑)
  7. iOS开发之时间格式化
  8. Redis集群(主从复制)
  9. ethcat开发记录 一
  10. js小数相加精度不准确