vue
首先vue 是一个构建用户界面的渐进式的框架,它是目前最火的一个框架,采用自底向上增量开发的设计,它的核心只关注视图层、容易学,低耦合,可重复使用一些视图逻辑,独立开发。
库与框架的区别
我们知道vue 是一个构建用户界面的渐进式的框架,基于mvvm模式开发,那我们必须知道库和框架的区别:
1.库(插件) - 提供某一个小功能,对项目的入侵性较小,如果某个库无法完成某些需求,可以很容易切换到其它库实现需求;例如vue.js,jquery.js…等,其实我们之前使用的引入js文件,就是使用的其中的库。
2.框架 - 框架是以整套完整的解决方案,对项目侵入性很大,项目如果需要更换框架,就需要重新构架整个项目,换句话说就要从头到脚彻底换新。
vue的特点与核心
首先我们需要先了解vue的特点,它只关注视图层,容易学,而且轻量,灵活,适用于移动端项目,是渐进式框架等。
其次它的核心包括:1.响应式的数据变化,视图可以改变数据,数据也可以改变视图;2.通过Object.defineProperty()方法来实现响应式数据变化(此时不理解这个方法不要紧,后面解释数据双向绑定时候会详情解释这个方法);3.设计思想是MVVM;4.组件化系统,组件可维护,可复用。
vue的设计思想MVVM
MVVM是Model-View-ViewModel的缩写,Model层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View代表的是ui组件,它负责将数据模型转换成ui展现出来;ViewModel它是一个调度者,分割了M与V,每当V层想要获取保存数据都要由VM做中间处理。
如何使用vue
1.引入vue.js
2.vue-cli脚手架直接生成vue项目
vue基本语法
Vue的基本使用步骤
1、需要提供标签用于填充数据
2、引入vue.js库文件
3、可以使用vue的语法做功能了
4、把vue提供的数据填充到标签里面
<body>
<div id="app">
<!-- 此处显示data中的msg数据,下面两个大括号表示插值表达式-->
{{ msg }}
</div>
<script src="./js/vue.js"></script>
<script type="text/javascript">
let vm = new Vue({ //创建vue实例
el: '#app', //绑定元素
data: { //此处的数据存放方式是对象
msg: 'hello world'
}
</script>
</body>
vue的常用指令
1.v-text与v-html
v-text相当于原生javascript中的innerText,只识别文本不识别标签
v-html相当于原生javascript中的innerHTML,可以识别标签
<body>
<div id="app" v-cloak>
<p v-text="msg"></p>
<p v-html="msg"></p>
</div>
<script src="./js/vue.js"></script>
<script type="text/javascript">
let vm = new Vue({ //创建vue实例
el: '#app', //绑定元素
data(){//存放数据
return{
msg:'<h3>hello world</h3>'
}
}
})
</script>
</body>
如下图所示
2.v-bind,属性绑定,可以简写成:(冒号),只能实现单向数据的绑定
<body>
<div id="app">
<input type="button" :value="msg" />//绑定属性,用data中的数据
</div>
<script src="./js/vue.js"></script>
<script type="text/javascript">
let vm = new Vue({ //创建vue实例
el: '#app', //绑定元素
data(){//存放数据
return{
msg:'修改'
}
}
})
</script>
</body>
3.v-on,绑定事件,可以简写成@
<body>
<div id="app" >
<!-- 绑定属性和事件 -->
<input type="button" :value="msg" @click="handlerClick"/>
</div>
<script src="./js/vue.js"></script>
<script type="text/javascript">
let vm = new Vue({ //创建vue实例
el: '#app', //绑定元素
data(){//存放数据
return{
msg:'点击'
}
},
methods:{//定义的逻辑事件放在methods中定义声明
handlerClick(){
alert('hello world')
}
}
})
</script>
</body>
4…v-for与key属性,列表循环与数据渲染,可以循环数组、对象、以及数字
<body>
<div id="box" >
<!--v-for循环语法 ,key值确定唯一性,以免操作相同元素引起失误,故循环时候都加上key值,确定唯一性 -->
<p v-for="(item,index) in user" :key='item.id'> {{item.name}}-----{{item.gender}} </p>
</div>
<script src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el: '#box',
data() {
return {
user: [{
id: 1,
name: 'tom',
gender: '男'
},
{
id: 2,
name: 'tony',
gender: '女'
},
{
id: 3,
name: 'toke',
gender: '男'
},
{
id: 4,
name: 'toome',
gender: '女'
}
]
}
}
})
</script>
</body>
5.v-model,vue中唯一一个实现数据双向绑定的指令(除自定义指令外),它只能应用于表单控件中(input,textare,select),下面列举介绍几种数据双向绑定的效果以及v-model的原理
<body>
<div id="box">
<h4>{{msg}}</h4>
<!-- 当改变input里面的数据内容,暂时h4里面的内容也会发生改变,这就是数据双向绑定 -->
<input type="text" v-model="msg" style="width: 100%;"/>
</div>
<script src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#box',
data:{
msg:'大家都是好同志,爱敲代码的好同志'
}
})
</script>
</body>
如下图所示:当你修改里面的内容立马与页面中h4标题一致
②.使用绑定属性与绑定方法共同来实现数据双向传递(oninput方法)
<body>
<div id="box">
<h4>{{msg}}</h4>
<!-- 当改变input里面的数据内容,暂时h4里面的内容也会发生改变,这就是数据双向绑定 -->
<input type="text" :value="msg" @input='changeHandler' style="width: 300px;"/>
</div>
<script src="js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#box',
data:{
msg:'大家都是好同志,爱敲代码的好同志'
},
methods:{
changeHandler(e){//定义的点击事件
this.msg = e.target.value
}
}
})
</script>
</body>
6.v-if与v-show两种都是显示与隐藏的效果,v-if每次显示与隐藏都有新元素的创建与销毁过程伴随,而v-show,只是css样式display的显示与隐藏,占据内存空间。
其中指令系统还包括v-else,v-else-if,一般v-if与v-else连用时,当不显示v-if时就显示v-else的内容;v-else-if是v-if与v-else的结合。
vue实例的生命周期
1.对于生命周期我们先了解什么是生命周期?从vue实例创建、运行、到销毁的期间,总是伴随着各种各样的事件,这些事件统称为生命周期。
2.生命周期钩子:生命周期过程中的事件函数名叫做生命周期钩子。
3.vue的生命周期函数:
创建期间的生命周期函数:
beforeCreated:实例刚在内存模板中创建出来,此时还没有初始化好data与methods,换句话说此时data中的数据与methods中的方法不能使用与获取;
created:实例已经在内存中创建ok,此时data中的数据与methods中的方法可以获取查看,但是还没有开始编译模板;
beforeMoubted:此时已经完成模板的编译,只是在内存中渲染了模板,但是还没有将数据渲染到页面中;
mounted:已经完成了模板的编译,已经挂载到了页面的容器中;
运行期间的生命周期函数:
beforeUpdated:当数据发生变化时,此时data中的状态值已经保持最新,但是页面的数据还是旧的数据;
updated:实例已经更新完毕,此时data中的状态值已经与页面的显示数据保持一致,页面已经重新渲染好了;
销毁期间的生命周期函数:
beforeDestory:实例在销毁之前调用此步,解绑之间的束缚,但是里面的方法还有指令,过滤器都还可以用,只是在做准备工作;
destory:此时实例已经销毁,里面的方法还有data不能使用,所有的监听都会被移除。
beforeCreate(创建前) created(创建后) beforeMount(载入前) mounted(载入后) beforeUpdate(更新前), updated(更新后) beforeDestroy(销毁前) destroyed(销毁后)
应用场景
vue生命周期的应用场景:
beforeCreate 可以在此时加一些loading效果,在created时进行移除
created 需要异步请求数据的方法可以在此时执行,完成数据的初始化
mounted 当需要操作dom的时候执行
updated 当数据更新需要做统一业务处理的时候使用
vue的组件化开发
什么是组件?
组件的出现就是为了拆分vue实例的代码量的,能够让我们以不同的组件来划分不同的功能模块,将来我们需要什么样的功能,就去调用对应的组件即可。
组件化与模块化的不同
组件化:是从UI界面的角度惊醒划分的,方便UI组件的重复使用;
模块化:是从代码逻辑的角度进行划分的,方便代码的分层开发,保证每个功能的单一。
组件的使用
全局组件
定义在vue实例(new Vue({}))之前
1.创建组件
模板
Vue.component(‘组件名’,{
template:‘html代码’,
data(){…},
mehtods:{…}
})
2.使用组件
<组件名></组件名>
<div id="app1">
<my-p></my-p>
</div>
<script src="js/vue.js"></script>
<script type="text/javascript">
//注册全局组件
Vue.component("my-p",{
template:"<p>我是p</p>"
});
let v1 = new Vue({
el:"#app1"
});
</script>
局部组件(私有组件)
定义在实例当中,如下代码所示:
<div id="app1">
<my-p></my-p>
</div>
<script src="js/vue.js"></script>
<script type="text/javascript">
let v1 = new Vue({
el:"#app1",
data:{
msg:''
},
components:{
my-p:{//这是创建的局部组件
template:"<p>我是p</p>"
}
}
});
</script>
组件之间的传值
1.父组件向子组件传值
父组件通过props向子组件传值,子组件定义属性名,把父组件的数据绑定在属性上,然子组件中使用props接收,如下代码所示:
<body>
<div id="app">
<coml :message = 'msg'></coml>
</div>
<script src="../../js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data:{
msg:'这是实例的数据',
check:false,
num:23,
list:[{id:1,name:'李四1'},{id:2,name:'李四2'}]
},
methods:{},
components:{
coml:{
template:'<h2>这是子组件上面的html代码----{{ message }}</h2>',
data(){
return{msgs:'这是子组件上面的数据'}
},
props:['message'],//这里可以是数组,也可以是对象
//props: {
//message:{
//type:['String']//数据类型
//default:'父组件不给值时候,这就是默认值',
// required:true//这是设置必传,与default二选一
//}
//}
methods:{}
}
}
})
</script>
</body>
2.子组件向父组件传值
子组件向父组件传值也是通过绑定自定义事件,然后子组件通过$.emit(‘方法名’,参数),这里的参数代表子组件上面的属性,可以是数据也可以是其他的。
<body>
<div id="app">
<coml @func = 'show'></coml>//这是绑定的自定义事件
<h4>{{ msg }}</h4>
</div>
<template id="temp">
<div>
<h3>这是子组件中的html代码</h3>
<input type="button" value="按钮" @click="myclick"/>
</div>
</template>
<script src="../../js/vue.js"></script>
<script type="text/javascript">
var vm = new Vue({
el:'#app',
data:{
msg:null
},
methods:{
show(data){
this.msg = data;
console.log(this.msg)//这是子组件的数据
}
},
components:{
coml:{//这是创建的子组件
template:'#temp',
data(){
return{
msgs:'这是子组件中的数据'
}
},
methods:{
myclick(){
//这是使用的方法与携带的子组件的参数数据
this.$emit('func',this.msgs)
}
}
}
}
})
</script>
</body>
3.平行组件之间的传值
平行组件之间传值思路:
①.先创建一个过渡的bus对象 let bus = new Vue(),通过这个对象将数据传递过去
②.创建两个平行之间的组件test1,test2,确定1向2中传递数据
③.在1中设置数据,并且在1中调用方法使用emit方法,bus.emit方法,bus.emit方法,bus.emit(‘方法的名字’,参数(指数据))
④.在2中接收参数,使用bus.$on(‘方法的名字’,(val)=>{val就是1中传递过来的数据})
<body>
<div id="app">
<mycom></mycom>
<mycon></mycon>
</div>
<template id="test1">
<span @click="handlerClick">传值</span>
</template>
<template id="test2">
<span>{{ testdata }}</span>
</template>
<script src="../../js/vue.js"></script>
<script type="text/javascript">
/*
平行组件之间传值思路:
1.先创建一个过渡的bus对象 let bus = new Vue(),通过这个对象将数据传递过去
2.创建两个平行之间的组件test1,test2,确定1向2中传递数据
3.在1中设置数据,并且在1中调用方法使用$emit方法,bus.$emit('方法的名字',参数(指数据))
4.在2中接收参数,使用bus.$on('方法的名字',(val)=>{val就是1中传递过来的数据})
*/
let bus = new Vue();
new Vue({
el:'#app',
data(){
return{}
},
methods:{},
components:{
mycom:{
template:'#test1',
data(){
return{
testData:'我是test1的数据'
}
},
methods:{
handlerClick(){
bus.$emit('func',this.testData)
}
}
},
mycon:{
template:'#test2',
data(){
return{
testdata:''
}
},
methods:{
add(){
bus.$on('func',(val)=>{
this.testdata = val;//val代表传过来的值
console.log(this.testdata)
})
}
},
created(){
this.add()
}
}
}
})
</script>
</body>
vue 中的路由
基本使用
首先需要下载路由,1.可以使用cdn的链接通道,必须在有网的情况下引入https://unpkg.com/vue-router/dist/vue-router.js,在引入vue-router之前必须先引入vue.js;
2.下载路由使用npm install vue-router;引入下面内容
import Vue from ‘vue’
import VueRouter from ‘vue-router’
Vue.use(VueRouter)
然后就可以使用路由了
如下步骤所示
<body>
<div id="app">
//第一步:问路
<router-link to="/login" tag='button'>登录</router-link>
<router-link to='/register' tag='button'>注册</router-link>
//表示占位符,用来显示组件的信息
<router-view></router-view>
</div>
<script src="../js/vue.js"></script>
<script src="../js/vue-router.js"></script>
<script type="text/javascript">
//创建组件的模板对象
var login = {
template:'<h1>登录组件</h1>',
data(){},
methods:{}
}
var register = {
template:'<h1>注册组件</h1>',
data(){},
methods:{}
}
//第二步:创建路由对象
var vt = new VueRouter({
routes:[//表示路由匹配规则组合
{path:'/login',name:'login',component:login},
{path:'/register',name:'register',component:register}
]
})
//第三步:创建vue实例,并将路由对象挂载在app中
var vm = new Vue({
el:'#app',
data:{},
methods:{},
router:vt//挂载路由对象于app中
})
</script>
</body>
路由的嵌套与切换
路由分为一级路由与多级路由,如果路由需要嵌套,则需要在路由配置里面加上children属性,然后配置路径与展示页面,如下代码所示:
var routerobj = new VueRouter({
//route//这表示路由匹配规则
routes:[
//每个路由规则都是一个对象,这个规则对象身上有两个属性
//属性1:path表示监听路由的链接地址
//属性2:component表示 如果前面匹配到的path,则展示对应组件component
//component的属性值必须是一个组件的模板对象,不能是组件的引用名称
//以及路由path必须加/
//{path:'/',component:login},//设置默认显示登录组件
{path:'/',redirect:'/register'},//重定向,设置默认页面
{path:'/login',component:login,
//二级路由新加的属性
children:[
{path:'login1',component:login1},
{path:'login2',component:login2}
]},
{path:'/register',component:register}
]
路由传参
1.使用query方式传递参数
使用query方式传递参数,是直接在地址栏上面以?+参数形式传递,当你想要获取传递的参数时,使用this.$route.query.参数名,query传递参数时不需要配置路由匹配规则,如下代码所示:
2.使用params传递路由参数(路由匹配规则中匹配的是name中的路径)
路由守卫
路由守卫是在路由跳转前做一些验证,比如登录前进行页面跳转验证
全局前置守卫
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// to.path即将要进入的目标 路由对象
//from.path当前导航正要离开的路由
//next()指向后执行的函数,且此函数必须执行。next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。
})
总结
经过以上的分析总结,vue其实说难不难,说简单不简单,难在于使用时候需要了解其中的数据驱动的方法,以及对于原生js的编程能力要强,这是学习者需要掌握的;简单在于不需要编程者操作dom,能够简化很多多余的代码,而更多的关心数据的变化与视图的渲染,