vue2.5快速入门(一)

第一章 Vue核心知识讲解

初识VUE,走进VUE的世界

历史介绍

  • angular 09年,年份较早,一开始大家是拒绝 star:59.3k
  • react 2013年, 用户体验好,直接拉到一堆粉丝 star:119k
  • vue 2014年, 用户体验好 star:124k

Vue等框架与jQuery的区别

  • jQuery是基于操作dom的库
  • Vue框架是以数据驱动和组件化开发为核心

引包、留坑、实例化 、插值表达式{{}}

开展vue,用vue做出自己的第一个网页的步骤

下载vue包

npm init --yes
npm install vue@2.5.21

引包

在node_modules\vue文件夹中取出来vue.js
创建一个页面引入刚下载的包

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 引包 -->
	<script type="text/javascript" src="vue.js"></script>
</head>
<body>
</body>
</html>

留坑

即留一个vue模板插入的地方或者是vue代码对其生效的地方

实例化—即启动Vue

启动: new Vue({el:目的地,template:模板内容});实例化传入的是一个对象options

options

  • 目的地 el 对应上面留坑的坑位,可通过id名,类名,标签名来查找。方式和jq一样
  • 内容 template
  • 数据 data 值为函数形式也可是对象,但是都是用函数,因为用的函数最后也是return一个对象
<script type="text/javascript">
	// 实例化启动vue
	new Vue({
		el:'#app',//目的的,可以识别类名、id名和标签名,如果做到极致优化可以直接用document.getElementById获取
		template:`     
		<div>
			<div>我这里是模板内容</div>
			<div>111</div>
		</div>
	})
</script>

现在打开网页的内容,为

插值表达式{{ }}

插值表达式内填入data里面的变量即可在页面取到变量值{{data}},用到的变量都要在data里面声明,

    data:function(){
        return {
            msg:'Hello Vue!'
        }
    }

整个测试代码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <!-- 留坑 -->
    <div id="app"></div>
    <!-- 引包 -->
</body>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
    // 实例化启动vue
    new Vue({
        el:'#app',//目的的,可以识别类名、id名和标签名,如果做到极致优化可以直接用document.getElementById获取
        template:`     
        <div> // 根节点只能有一个
            <div>我这里是模板内容</div>
            <div>111</div>
        </div>`,
        data:function(){
            return {
                msg:'Hello Vue!'
            }
        }
    })
</script>
</html>

熟悉及使用常用指令

什么是指令

在vue中提供一些对于页面+数据的更为方便的操作,这些操作就叫做指令。譬如在HTML页面中这样使用

<div v-xxx=''></div>

在vue中v-xxx就是vue的指令

指令就是以数据去驱动DOM行为的,简化DOM操作

常用的指令

  • v-text 不可解析html标签
  • v-html 可解析html标签
  • v-if 做元素的插入(append)和移除(remove)操作
  • v-else-if
  • v-else
  • v-show display:none 和display:block的切换
  • v-for
    • 数组 item,index
    • 对象 value,key ,index

示例代码

<!DOCTYPE html>
<html>
<head>
	<title></title>
</head>
<body>
	<div id="app"></div>
	<script type="text/javascript" src="vue.js"></script>
	<script type="text/javascript">
		
		new Vue({
			el:'#app',
			template:`
			<div>
					<!--测试v-text-->
					<div v-text='mytext'></div>
					</hr>
					<!--测试v-html-->
					<div v-html='myhtml'></div>
					<!--测试v-if  v-else-if  v-else-->
					<button v-if='num==1'>测试v-if</button>
					<button v-else-if='num==2'>测试v-else-if</button>
					<button v-else>测试v-else</button>

					<!--测试v-show-->
					<div v-show='checkshow'>我是V-SHOW</div>
					<!--循环数组-->
					<ul>
					<li v-for='(item,index) in arrayfor'>
					{{ item }}-{{index}}
					</li>
					</ul>
					<ul>
					<!--循环对象-->
					<li v-for='(oj,key) in ojfor'>
					{{key}}:{{oj}}
					</li>
					</ul>
			</div>
			`,
			data:function(){
				return {
					mytext:'<h1>我这里是v-text</h1>',
					myhtml:'<h1>我这里是v-html</h1>',
					checkvif:true,
					num:6,
					checkshow:true,
					arrayfor:['篮球','足球','乒乓球'],
					ojfor:{play:'篮球',people:'ming',age:'19'}
				}
			}
		})
	</script>
</body>
</html>

阐述vue单双向数据流及事件绑定

单向数据绑定

vue单向数据流绑定属性值 v-bind: (属性) 简写 :(属性),例子

<input v-bind:value="name" v-bind:class="name">
  • 单向数据绑定 内存改变影响页面改变(在html页面中定义后,改变值不改变页面中的定义)
  • v-bind就是对属性的简单赋值,当内存中值改变,还是会触发重新渲染

双向数据绑定

vue双向数据流 v-model 只作用于有value属性的元素,例子

<input v-model="name" v-bind:class="name">
  • 双向数据绑定 页面对于input的value改变,能影响内存中name变量
  • 内存js改变name的值,会影响页面重新渲染最新值

事件绑定

事件绑定v-on:事件名=“表达式||函数名” 简写 @事件名=“表达式||函数名”

  • 事件名可以是原生也可以是自定义的

事件绑定如果是卸载methods中的函数,则需要带上this参数,如果直接在函数中写上则不需要带this

<button v-on:click="name='点击我改变name变量'">点击我改变name变量</button>
<button v-on:click="change">点击我改变name变量2</button>

示例代码如下

<!DOCTYPE html>
<html>
<head>
	<title></title>
</head>
<body>
	<div id="app"></div>

	<script type="text/javascript" src="vue.js"></script>
	<script type="text/javascript">
		console.log(this)
		new Vue({
			el:"#app",
			template:`
				<div>
				单向数据绑定
				<input type='text' v-bind:value="name" :class="name"><br>
				双向数据绑定
				<input type='text' v-model="name"></br>
				{{ name }}
				<button v-on:click="name='点击我改变name变量'">点击我改变name变量</button>
                </br>
                {{ name }}
                <button v-on:click="change">点击我改变name变量2</button>
				</div>
			`,
			data:function(){
				return {
					name:'hello'
				}
			},
			methods:{
				change:function(){
					console.log(this)
					this.name='我改变了,是在方法属性里面定义的方法'
				},
			}
		})
	</script>
</body>
</html>

总结:
v-model双向数据绑定

  • vue页面改变影响内存(js)
  • 内存(js)改变影响vue页面

v-bind 单向数据绑定只是内存(js)改变影响vue页面

过滤器

过滤器就是可以对我们的数据进行添油加醋然后再显示(需要先声明再使用)

过滤器有全局过滤器和组件内的过滤器

  • 全局过滤器Vue.filter(‘过滤器名’,过滤方式fn );
  • 组件内的过滤器 filters:{ ‘过滤器名’,过滤方式fn }
  • {{ msg | 过滤器名}}

组件内过滤器的方式的示例代码

<!DOCTYPE html>
<html>
<head>
	<title>过滤器</title>
</head>
<body>
	<div id="app">
		我输入的:<input type="text" name="" v-model='instring'></br>
		我输出的:{{ instring }}</br>
		{{ instring | reversal('翻转输出:')}}
	</div>
	<script type="text/javascript" src="vue.js"></script>
	<script type="text/javascript">
		new Vue({
			el:'#app',
			data(){
				return {
					instring:''
				}
			},
			// 第一个参数固定为传入的左边变量
			filters:{
				reversal(val,arg2){
					//          字符串转数组  翻转    数组转字符串
					return  arg2+val.split('').reverse().join('')
				}
			}
		})
	</script>
</body>
</html>

全局过滤器的示例代码

<!DOCTYPE html>
<html>
<head>
	<title>过滤器</title>
</head>
<body>
	<div id="app">
		我输入的:<input type="text" name="" v-model='instring'></br>
		我输出的:{{ instring }}</br>
		{{ instring | reversal('翻转输出:')}}
	</div>
	<script type="text/javascript" src="vue.js"></script>
	<script type="text/javascript">
		Vue.filter('reversal', function(val, arg2){
			return  arg2+val.split('').reverse().join('')
		})
		new Vue({
			el:'#app',
			data(){
				return {
					instring:''
				}
			},
		})
	</script>
</body>
</html>

最终都是在过滤方式fn里面return产出最终你需要的数据

vue中的this是vue封装好给我们使用的,跟平常方法里面的this是不同的

数据监听watch计算属性computed

watch监听单个,computed监听多个,思考业务场景:

  • 类似淘宝,当我输入某个人名字时,我想触发某个效果
  • 利用vue做一个简单的计算器

示例代码

<div id="app">
	<div>watch监听数据</div>
	<input type="text" name="" v-model='msg'>
</div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
	new Vue({
		el:'#app',
		data(){
			return {
				msg:'',
			}
		},
		watch:{
			msg(newval, oldval) {
                if(newval=='love'){
					alert(newval)
				}
            }
		}
	})
</script>

当watch监听的是复杂数据类型的时候需要做深度监听(写法如下)

<div id="app">
	<div>watch监听数据</div>
	<input type="text" name="" v-model='msg.text'>
</div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
	new Vue({
		el:'#app',
		data(){
			return {
				msg:{text:''},
			}
		},
		watch:{
			msg:{
				handler(newval,oldval){
					if(newval.text=='love'){
						alert(newval.text)
					}
				},
				deep:true // 开启深度监听
			}
		}
	})
</script>

computed 监视对象,写在了函数内部,凡是函数内部有this.相关属性,改变都会触发当前函数,示例代码如下

<!DOCTYPE html>
<html>
<head>
	<title></title>
</head>
<body>
	<div id="app">
		<div>computed计算属性</div>
		(<input type="text" name="" v-model='n1'>+
		<input type="text" name="" v-model='n2'>)*
		<input type="text" name="" v-model='n3'>={{result}}
	</div>
	<script type="text/javascript" src="vue.js"></script>
	<script type="text/javascript">
		new Vue({
			el:'#app',
			data(){
				return {
					msg:{text:''},
					n1:'',
					n2:'',
					n3:'1'
				}
			},
			computed:{
				result(){
					return (Number(this.n1)+Number(this.n2))*Number(this.n3)
				}
			},
		})
	</script>
</body>
</html>

组件化开发知识介绍

组件化开发

组件化开发能让我们的项目更加灵活

创建组件的两种方式

var Header = { template:'模板' , data是一个函数,methods:功能,components:子组件们 }//局
部声明

Vue.component('组件名',组件对象);//全局注册 等于注册加声明了

组件类型

  • 通用组件(例如表单、弹窗、布局类等)
  • 业务组件(抽奖、机器分类)
  • 页面组件(单页面开发程序的每个页面的都是一个组件、只完成功能、不复用)

组件开发三步曲:声明、注册、使用

示例代码如下

<!DOCTYPE html>
<html>
<head>
	<title></title>
</head>
<body>
	<div id="app">
	</div>
	<script type="text/javascript" src="vue.js"></script>
    <script type="text/javascript">
        // 这个是语法糖
        var MyHeader = {
            template:`
                <div>我是头部</div>
            `,
        }
        // 一般形式是这样的
        var MyBody = Vue.extend({
            template:`
                <div>我是身体</div>
            `,
        })
        Vue.component('MyFooter', {
			template:`
				<div>我是尾部</div>
			`
		})
		new Vue({
            el:'#app',
            // 注册组件
            components: {
                MyHeader,
                MyBody
            },
            template:`
                <div>
                    <My-Header></My-Header> 也可以用My-Header的名字调用
                    <MyBody></MyBody>
                    <my-footer></my-footer>
                </div>
            `,
            data(){
				return{}
			},
		})
	</script>
</body>
</html>

slot插槽和ref、$parent

slot插槽

  • slot就是子组件里给DOM留下的坑位
  • <子组件>DOM</子组件>
  • slot是动态的DOM

示例代码

<!DOCTYPE html>
<html>
<head>
	<title>组件化开发</title>
</head>
<body>
	<div id="app">
	</div>
	<script type="text/javascript" src="vue.js"></script>
	<script type="text/javascript">
			var MyParent={
			template:`
				<div>
					我是父组件
					<h2>
						<slot name='hello'></slot>
					</h2>
				</div>
			`,
		}
		new Vue({
			el:'#app',
			components:{
				MyParent
			},
			template:`
				<div>
					<MyParent>
						<div>你是看不到这个输出的,因为没有对应的slot name</div>
						<div slot='hello'>如果指定了name,就只显示对应的组件</div>
					</MyParent>
				</div>
			`,
			data(){
				return{}
			},
		})
	</script>
</body>
</html>

ref获取子组件实例

  • 识别:在子组件或元素上使用属性ref=“xxxx”
  • 获取:this.$refs.xxxx 获取元素
  • $el 是拿其DOM

p a r e n t 获 取 父 组 件 实 例 ( 可 在 子 组 件 直 接 使 用 t h i s . parent获取父组件实例(可在子组件直接使用this. parent使this.parent即可)

可以用作后面的父子组件的通信

示例代码

<!DOCTYPE html>
<html>
<head>
	<title>组件化开发</title>
</head>
<body>
	<div id="app">
	</div>
	<script type="text/javascript" src="vue.js"></script>
	<script type="text/javascript">
		var Child={
			template:`
				<div>我是子组件</div>
			`,
			data(){
				return {
					msg:'hello'
				}
			},
			created(){
				console.log("通过this.$parent可以找到父组件,也能调用父组件的方法", this.$parent)
			}
		}
		var Parent={
			template:`
				<div>
					我是父组件
					<slot name='hello'></slot>
					<child ref='childs'></child>
				</div>
			`,
			components:{
				Child
			},
			data(){
				return {
					parents:'我是父组件'
				}
			},
			mounted(){
				console.log("通过this.$refs.childs可以找到子组件,也能调用子组件的方法", this.$refs.childs)
			}
		}
		new Vue({
			el:'#app',
			components:{
				Parent
			},
			template:`
				<div>
					<parent>
						<div>我是插槽内容</div>
						<div slot='hello'>我是插槽内容2</div>
					</parent>
				</div>
			`,
			data(){
				return{}
			},
		})
	</script>
</body>
</html>

父子组件的通信

父传子

  • 父用子的时候通过属性传递
  • 子要声明props:[‘属性名’] 来接收
  • 收到就是自己的了,随便你用
    • 在template中直接用
    • 在js中 this.属性名用

示例代码如下

<!DOCTYPE html>
<html>
<head>
	<title>组件化开发</title>
</head>
<body>
	<div id="app">
	</div>
	<script type="text/javascript" src="vue.js"></script>
	<script type="text/javascript">
		var Child={
			template:`
				<div>
					我是子组件
					<h2>{{sendchild}}</h2>
				</div>
			`,
			props:['sendchild'], // 通過props来传递值
		}
		var Parent={
			template:`
				<div>
					我是父组件
					<child sendchild="zengraoli"></child>
				</div>
			`,
			components:{
				Child
			},
		}
		
		new Vue({
			el:'#app',
			components:{
				Parent
			},
			template:`
				<div>
					<parent>
						<div>我是插槽内容</div>
						<div slot='hello'>我是插槽内容2</div>
					</parent>
				</div>
			`,
			data(){
				return{}
			},
		})
	</script>
</body>
</html>

子传父

  • 子组件里通过$emit(‘自定义事件名’,变量1,变量2)触发
  • 父组件@自定义事件名=‘事件名’监听

示例代码如下

<!DOCTYPE html>
<html>
<head>
	<title>组件化开发</title>
</head>
<body>
	<div id="app">
	</div>
	<script type="text/javascript" src="vue.js"></script>
	<script type="text/javascript">
		var Child={
			template:`
				<div>
					我是子组件
					<h2>{{sendchild}}</h2>
					<button @click='sendparent'>我要反馈东西给父组件,点击后$emit触发父组件的baba函数</button>
				</div>
			`,
			props:['sendchild'], // 通過props来传递值
			methods:{
				sendparent(){
					this.$emit('baba','这是儿子组件给你的')
				}
			}
		}
		var Parent={
			template:`
				<div>
					我是父组件
					<child sendchild='父亲给你的' @baba='reserve'></child>
					子组件传过来的数据:{{childMsg}}
				</div>
			`,
			components:{
				Child
			},
			data(){
				return {
					childMsg:''
				}
			},
			methods:{
				reserve(val) {
					this.childMsg = val
				}
			}
		}
		
		new Vue({
			el:'#app',
			components:{
				Parent
			},
			template:`
				<div>
					<parent>
					</parent>
				</div>
			`,
			data(){
				return{}
			},
		})
	</script>
</body>
</html>

非父子组件之间的通信

创建一个空实例(bus中央事件总线也可以叫中间组件)

利用$emit $on的触发和监听事件实现非父子组件的通信

Vue.prototype.$bus=new Vue()//在vue上面挂载一个$bus作为中央处理组件
this.$bus.$emit('自定义事件名','传递的数据')//触发自定义事件传递数据
this.$bus.$on('自定义事件名',fn)//监听自定义事件获取数据

解决的方案还有vuex、provide/inject是解决同根往下派发、本地存储也可以进行非父子组件之间的通信

简单的使用就使用中间过渡的形式,示例代码如下

<!DOCTYPE html>
<html>
<head>
	<title>非父子组件的通信</title>
</head>
<body>
	<div id="app">
	</div>
	<script type="text/javascript" src="vue.js"></script>
	<script type="text/javascript">
		Vue.prototype.$bus=new Vue()
		var MyHeader={
			template:`
				<div>
				我是头部
				{{ headermsg }}
				</div>
			`,
			data(){
				return {
					headermsg:'我是头部的信息'
				}
			},
			created() {
				// 在created中新建一个监听数据的事件
				var self = this
				self.$bus.$on('sending', function(val){
					self.headermsg=val
				})
				// 另外一个使用---箭头函数的定义域需要区分一下
				// this.$bus.$on('sending',val=>{
				// 	this.headermsg=val
				// })
			}
		}
		var MyBody={
			template:`
				<div>我是身体</div>
			`,
		}
		var MyFooter={
			template:`
				<div>我是底部<button @click="sendHeader">我要跟头部通信</button></div>
			`,
			methods:{
				sendHeader(){
					this.$bus.$emit('sending', '我是底部传过来的数据')
				}
			}
		}
		new Vue({
			el:'#app',
			components:{
				MyHeader,
				MyBody,
				MyFooter
			},
			template:`
				<div>
					<my-header></my-header><hr>
					<my-body></my-body><hr>
					<my-footer></my-footer>
				</div>
			`,
			data(){
				return {}
			},
		})
	</script>
</body>
</html>

vue的生命周期

需要频繁的创建和销毁组件

  • 比如页面中部分内容显示与隐藏,但是用的是v-if

组件缓存

  • 内置组件中
  • 被其包裹的组件,在v-if=false的时候,不会销毁,而是停用
  • v-if=“true” 不会创建,而是激活
  • 避免频繁创建组件对象的性能损耗
  • 组件的激活和停用
    • activated 和 deactivated

成对比较

  • created 和 beforeCreate
    • A 可以操作数据 B 数据没有初始化
  • mounted 和 beforeMount
    • A 可以操作DOM B 还未生成DOM
  • updated 和 beforeUpdate
    • A 可以获取最终数据 B 可以二次修改

destroyed 和 beforeDestroy
性能调优:频繁销毁创建的组件使用内置组件包裹

参考官网:https://cn.vuejs.org/v2/guide/instance.html#生命周期图示

演示的小例子代码如下,app.js内容(仅仅是引入实现代码main.js)

<!DOCTYPE html>
<html>
<head>
	<title>vue的生命周期</title>
</head>
<body>
	<div id="app">
	</div>
	<script type="text/javascript" src="vue.js"></script>
	<script type="text/javascript" src="main.js">
	</script>
</body>
</html>

main.js代码

var Test={
    template:`
        <div>我是Test组件{{ msg }}
        <button @click="msg+='1'">msg+1</button>
        </div>
    `,
    data(){
        return{
            msg:'HELLO VUE'
        }
    },
    //组件创建前
    beforeCreate(){
        console.log('组件创建前')
        console.log(this.msg)
    },
    //组件创建后
    created(){
        console.log('组件创建后')
        console.log(this.msg)
    },
    //Dom挂载前
    // beforeMount(){
    // 	console.log('Dom挂载前')
    // 	console.log(document.body.innerHTML)
    // },
    // //Dom挂载后
    // mounted(){
    // 	console.log('Dom挂载后')
    // 	console.log(document.body.innerHTML)
    // }
    //基于数据更新前
    beforeUpdate(){
            console.log('数据更新前')
            console.log(document.body.innerHTML)
    },

    //基于数据更新后
    updated(){
            console.log('数据更新后')
            console.log(document.body.innerHTML)
    },
    //销毁前
    beforeDestroy(){
        console.log('销毁前')
    },
    //销毁后
    destroyed(){
        console.log('销毁后')
    },
    //组件停用
    deactivated(){
        console.log('组件停用')
    },
    //组件激活
    activated (){
        console.log('组件激活')
    }
}

new Vue({
    el:'#app',
    components:{
        Test	
    },
    template:`
        <div>
            <keep-alive><test v-if='testshow'></test></keep-alive></br>
            <button @click='clickbut'>销毁组件</button>
        </div>
    `,
    data(){
        return {
            testshow:true
        }
    },
    methods:{
        clickbut(){
            this.testshow=!this.testshow
        }
    }
})

参考链接

全文所涉及的代码下载地址

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值