1、介绍vue
MVP和MVVM模式!!!
mvp模式,其中m是模型是ajax请求数据, v是视图层(html),p是控制器,就是使用jq来实现业务逻辑相关操作(DOM操作很多)
MVVM模式,其中M是new实例里面相关操作,v是视图层,vm即vue自己进行操作转化!
首先使用vue(mvvm模式)可以通过两种方式,
第一种:是直接通过引入vue.js的形式,那么这时候的vue直接写在<script></script>里面,这时候的vue是全局注册作为全局变量!我们进行全局注册组件的时候,可以直接引用,如果是进行
<div id="app">
{{ message }} =======》》》》V层
<todo-item></todo-item>
</div>
<script>
//vue中全局注册组件
Vue.component("TodoItem",{
props:['content'],
template:"<li>{{content}}</li>",
})
//vue全局实例化
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!', =======》》》》M层
content:"测试全局组件"
},
method:{
}
})
</script>
2、vue的实例化
3、vue中的基本语法
计算属性(computed)、方法(methods)、事件监听(watch)
computed属性,会有一个缓存机制,计算页面重新加载,只要计算的属性没有发生改变,就不会重复执行computed,而方法methods中,只要页面有重新加载就会被重复执行,
对于监听事件(watch),需要监听的属性有发生变化时才会执行!!也既有缓存机制,但是相比代码量会比computed多!!
computed中的get和set函数!!!
类名跟样式表达式
:class=“{active:isActive}” 这时候,是通过isActive来控制active类名是否要显示
:class=“[actived]” 这个时候activde的值是通过data里面的值来控制的
样式表达式
:style=“styleObejt” styleObject的值是通过data来赋值==》styleObject:{color:#fff;}
key值标识唯一性
vue虚拟dom中,会有自带缓存复用机制,如果它检测到页面上相同的东西没有发生变化,它就会进行有效的复用!
例如:用户名的时候input的输入值是小明,当你把用户名切换为密码是,input上的值还是小明,这是因为input被复用了
当给下面的两个input加key值,那么这时候input中的元素就不会被有效地复用!
v-for指令
使用该指令的时候,设置key值是不要使用index来赋值,而是使用后端提供的id,这样可以保证唯一性跟提高性能
数组操作
在vue中,对数值进行时不能直接通过下标来增加(删除)数组,通过这种方式增加数组(删除),数据上是变了,但是页面上不会变。
例如list[4]={“id”:4,name:”55″}这时候页面上的list元素还是只有三个!
在vue中如果想操作数组的同时,页面跟着变化。有两种方法。
第一种是使用数组中的7种编译方法来操作数组
第二种是直接改变list数据的指定空间来改变
在列表渲染中使用包裹占位符template,来包裹需要循环的列表,这时候template不会被页面渲染出来!!
对象操作
第一点:遍历对象的时候,直接往对象里面加值,这时候页面也是没有跟着变的,同样可以改变对象的引用==》数据指向新的引用对象
第二点:用vue中的set方法方法来改变对象(第一个参数是key,第二个参数是name)和数组(第一个参数是下标,第二个参数是对应的值)
对象:
使用vue实例化方法的$set方法!!!!第一个是key,第二个参数是name
3、组件的使用
第一点:全局组件跟局部组件,和子组件与父组件之间的传值
第二点:使用组件时的一些小细节用法
知识点1:使用table的时候,使用组件会有一个小bug,在渲染的时候table标签下面只能是<tbody></tbody>下面只能是<tr></tr>,所以要是直接用<row>组件,在页面渲染出来的<tr>标签会出现在table外面!这时候在<tr>标签上是使用is=“row”进行组件渲染符合H5规范,同样的ul li标签也适应
知识点2:在组件中使用data,当在跟组件中使用data的时候,data可以是一个对象的形式,因为在根组件中,数据只被调取一次,而在子组件中,数据有可能被调用多次,
这时候,不能data只能用函数,为每个数据都存储不同的空间。
Vue.component("row",{ data:function(){ return { content:'this is content' } }, //在子组件中data必须以函数的形式并且以return的方式返回数据 template:'<tr><td>{{content}}</td></tr>' }) var vm = new Vue({ el:"#app", data:{} //在根组件中是允许以对象的形式这样写的 })
知识点3:
在vue中,如果遇到复杂的操作需要使用dom操作时,可以使用$refs引用属性来获取dom元素
<div ref=”hello”>测试下ref</div> ===>>>>alert(this.$refs.hello.innerHTML) //测试下ref
在组件中使用ref来引用不同的子组件,这是ref指向的是这个组件
知识点4:父子组件传值
父组件向子组件传值都是通过属性的形式传值的(但是页面渲染的时候,属性没有渲染出来)
<counter count=”0″></counter> //传值的时候,如果count前面没有加“ : ” 号,那么这时候传的0是字符串类型
<counter :count=”0″></counter> //传值的时候,如果count前面有加“ : ” 号,那么这时候双引号里面的值是一个js表达式,这时候count传0的是一个数字类型
单项数据流,子组件只能使用父组件传过来的值,而不能直接对该属性值进行直接改变,如果真的要改变,可以在子组件的data里另取一个变量进行赋值修改
子组件接收到后count值后,还需要对count的值进行,修改,这时候把count值赋予新变量number,然后在子组件的data里面对number进行修改
知识点5:组件参数验证,在子组件接收父组件传过来的时,props可以对这些值进行一些校验,除了使用自带的基本校验方式,我们还可以自定义validator进行自定义校验!!!
注意:当用props属性接收的时候,改属性不会被渲染出来,如果是没有用props属性接收,那么就是非props属性,
这时候页面会报错,子组件没办法用到content的值,而且这时候子组件渲染成<div content=”hell”></div> content变成了子组件的自定义属性。
知识点6:给组件绑定原生事件
给组件绑定的事件都是自定义事件,这种事件只能从过子组件来触发,如果想直接触发原生事件可以在事件中加native!!
知识点7:非父子组件间传值(Bus/总线/发布订阅模式/观察者模式)
Vue.prototype.bus = new Vue() ====>>>>表示把bus属性挂载在vue是,这样每个有用到VUE实例的地方都有bus属性,而bus属性又是一个new vue实例,所以也拥有vue的相关属性!!!
触发方:this.bus.$emit=(‘change’,this.content)
接收方:this.bus.$on=(‘change’,function(msg){
})
知识点8:插槽(slot)
父组件向子组件优雅传dom值,使用插槽slot,当子组件中使用插槽slot时,父组件要是有传值,那么solt上的默认值,就不会被显示出来,插槽直接渲染父组件传过来的值,如果没有,默认值就会被显示!
没有给slot取名字的话,slot默认就是父组件插入的所有内容。取名字的话就会对应名字插件进去
知识点9:动态组件切换(v-once)
应用场景,例如我们想要通过点击一个按钮,实现不同组件的切换,这时候,我们可以使用两种方法来实现,一种是使用componet的is属性,一种是通过v-if,当我们使用v-if进行组件切换时,会对另一个组件进行销毁,然后切换到的时候再进行创建,但是对于频繁需要切换的静态组件很好耗性能,我们可以加v-once,当这个v-once组件被第一次切换的时候,就会被存在内存里面,第二次使用的时候,就会被拿出来,在使用静态页组件切换时使用可以提高性能!!!
总结父组件跟子组件之间的相互通讯
<v-select :selectType=”selectType”></v-select>
父组件传值给子组件
export default {
data (){
return {
selectType:true;
}
}
}
子组件通过props的方式从父级接收数据:
props:{
selectType:{
type:Boolean,
default(){
return false;
}
}
}
在父级中:title是在子级中要用的名字,如果fff前面有:那么后面的tit就是个变量,在data中要去定义。如果没有那么就是普通字符串。
<header :title=”tit”>
子组件传值给父组件
子组件:<div class=”sureBtn” @click=”suremit”></div>
method:{
suremit:function(){
this.$emit(‘addShop’,this.select,this.num);
}
}
父组件:
<v-select @addShop=”sureAddShop”></v-select>
method:{
sureAddShop:function(key,num){}
}
4、vue中css的动画
知识点1:动画原理
首先,为需要动画的标签外层加一个<transition name=“fade”></transition>,然后可以给其设置一个名字,如果没有设置名字,默认是V
显示的状态流程,默认第一帧是fade-enter,然后下一帧的时候fade-enter就会被销毁,然后fade-enter-active是从第一帧开始就存在,知道结束才销毁,所以可以用该属性监听某个属性的变化,从而使用transition进行动画过度效果
隐藏状态流程,默认第一帧是fade-leave(动画第一瞬间就存在,所以从显示到隐藏状态这个转态就已经有了),下一帧fade-leave销毁,fade-leave-to创建,而fade-leave-active从开始到结束一直存在
知识点2:使用@keyframes(css3动画)和为动画自定义命名
自定义命名 enter-active-class=“active” !!!
知识点3:animate动画库
我们现在的应用场景是点击按钮的时候,动画才会执行,如果想页面一加载就有动画效果,我们可以给transition增加appear属性并且设置appear-active-class=“animated swing”
知识点4:使用animated动画库跟自定义动画并且设置动画时长
type=”transition”来指定动画时长是以哪个动画为准,这边指的是以transition动画时长为准!也可以通过设置:duration来设置自定义时间
4、vue中js的动画与velocity.js结合
通过js来写动画效果
velocity.js实现动画
知识点5:多元素和多组件的切换(状态过度Tween.js)
多元素的切换,使用mode设置多个元素过度(组件)效果,设置key解除缓存效果,出现动画效果
当多个元素是用v-for循环出来的时候,可以使用<transition-group></transition-group>来包裹v-for循环元素!!!
动画封装
<fade :show=”show”></fade>
6、去哪儿项目实战
知识点1:单页应用跟多页应用
多页应用:页面的切换是通过请求不同的html页面,首页加载比较快,利于seo,缺点是切换页面比较慢!
单页应用:页面之前的切换是通过js来控制渲染,始终都是在同一个页面,优点是不同页面之间切换速度快,缺点是首页加载比较慢,不利于seo优化!!!
知识点2:路径引用问题(webpack.base.config.js)
在vue中@符号表示的是src目录下的文件
我们可以在webpack.base.config.js下面进行路径配置 ,在’styles’: resolve(‘src/assets/styles’),设置完,需要重启服务器
知识点3:static文件夹的用法
static文件下的东西是用来放静态的东西,是vue中唯一一个不需要打包编译就可以被外部访问的文件夹(通过相应的路径访问http://localhost:8088/static/mock/index.json),这里我们可以放模拟的数据!!!!
知识点4:步骤记录
gitignore文件===》用来增加提交不提交到git仓库里
知识点5:<keep-alive>(提高网站性能)
使用 <keep-alive>包裹在<router-view>来缓存路由,减少每次切换路由的时候,都请求ajax,但是使用这个缓存路由的时候,数据发送改变时也不会被重新请求路由,这时候需要用到keep-alive提供的方法
activated因为只有该生命周期函数会被执行,在里面判断前后数据有没有变,有再重新执行!!
我们可以通过2中方法来使用<keep-alive></keep-alive>来选择缓存不同的路由页面
方法一:使用<keep-alive>内封装的include和exclude两种方法
<keep-alive include="test-keep-alive"> <!-- 将缓存name为test-keep-alive的组件 --> <component></component> </keep-alive> <keep-alive include="a,b"> <!-- 将缓存name为a或者b的组件,结合动态组件使用 --> <component :is="view"></component> </keep-alive> <!-- 使用正则表达式,需使用v-bind --> <keep-alive :include="/a|b/"> <component :is="view"></component> </keep-alive> <!-- 动态判断 --> <keep-alive :include="includedComponents"> <router-view></router-view> </keep-alive> <keep-alive exclude="test-keep-alive"> <!-- 将不缓存name为test-keep-alive的组件 --> <component></component> </keep-alive>
方法二:动态配置路由,在router里面的index.js设置
然后在然后在app.vue文件下修改一下keep-alive组件的用法
知识点6:activated方法和deactivated生命周期钩子(activated
和 deactivated
将会在 <keep-alive>
树内的所有嵌套组件中触发)
keep-alive会缓存组件,是的每次切换路由的时候,页面都不会重新请求ajax,而是直接用缓存里面的数据,如果这时候我们的数据发送变化需要重新请求ajax的时候,就需要用到keep-alive提供的activated函数(页面重新显示的时候会被执行,可利用前后两次的数据是否变化来判断是否重新执行ajax)
activated:keep-alive 组件激活时调用(页面进入或显示时失效被执行)
deactivated:keep-alive 组件停用时调用(页面离开或隐藏时失效被执行)
注意一点:activated,deactivated这两个生命周期函数一定是要在使用了keep-alive组件后才会有的,否则则不存在 !!!
知识点7:打包编译
知识点1:打包编译上线,cnpm run build 命令编译,然后提交dist 文件里面的index跟static文件。到服务端。然后就可以直接用localhost/的后端方式来打开!!!
知识点改变提交给服务端的路径,这时候需要修改config里面的配置,例如project文件里面
build: { // Template for index.html index: path.resolve(__dirname, '../dist/index.html'), // Paths assetsRoot: path.resolve(__dirname, '../dist'), assetsSubDirectory: 'static', assetsPublicPath: '/project', //把路径修改为需要更改的路径
然后重新执行命令cnpm run build然后在生成的dist文件修改问project!
这时候就可以通过localhost/project来访问网站!!!
知识点8、异步组件调用提高网站加载速度从而提高性能
当路由中是调用组件名时,页面在加载的时候会默认一次性把所有的组件页面都加载出来,导致在打开首页的时候,其它所有页面一起被加载出来,从而打开速度缓慢!
方法一:在router文件下index。js修改
import Vue from 'vue' import Router from 'vue-router' import Home from '@/pages/home/Home' //@表示src目录下的文件 import City from '@/pages/city/City' import Detail from '@/pages/detail/Detail' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'Home', component: Home },{
修改为//改为箭头函数异步加载组件
export default new Router({
routes: [
{
path: ‘/’,
name: ‘Home’,
component: () => import(‘@/pages/home/Home’) //改为箭头函数异步加载组件
}
方法二:在引用组件的时候用箭头函数
components:{
header:()=>import(‘./components/Header’)
}
文件打包编译后会生成下面三个文件,用后端网址打开时会有以下三个文件
异步组件调用拆分后,app.js被拆分成一个个js文件
注意:当app.js文件特别大的时候,使用异步组件,对app.js进行拆分,拆分后每次切换到前面没有加载过的页面都相当于是一次http请求(有加载过的话,有缓存不需要重新加载),所以当app.js不是很大的时候,不推荐进行异步组件拆分,直接在进首页的时候都加载!!!
知识点9、字体图标的使用
如何使用字体图标
首先打开iconfont官网,选择相应的图标添加购物车,然后加入我的项目,然后下载到本地。解压,然后选择如下文件放在自己的目录下,然后修改iconfont.css下面相应的路径。
然后在需要用到字体图标的地方使用
iconfont.css路径修改
调用文件
<span class="iconfont"></span> //编码在iconfont我的项目对应图标那边复制
如何新增字体图标
把新增的字体图标添加到项目后,然后下载到本地,替换四个字体文件,样式文件不需要替换,但是必须修改下旧的iconfont.css里面的base64位路径修改为最新下载下来的iconfont.css里面的base64位图片位置!!
2.在vue中,如果某个函数需要用到ajax返回的data值,那这时候,不能通过在created或者mounted来获取数据然后调用函数,需要在请求成功时,直接调用传数据!
3.箭头函数的使用
在vue中使用cs6语法,直接使用箭头函数,那么函数所指的作用域直接指向最外层,不用通过_this=this来指向最外层!!!res是函数里面的参数即是返回的结果!!!
4.过滤器的使用
过滤器的使用中,如果没有带参数,只需要写函数名即可,默认第一个参数是val值。{{title | ratefilter}},要是用使用参数则需要用函数的形式来调用过滤器{{title | ratefilter(“元”) }}
5.需要item中的item.check字段, vue中如何来判断一个ajax字段是否存在,如何给vue中设置需要的字段!!
使用typeof判断一个字段是否存在,使用vue.$set来为item.check增加字段,同时如果点击事件的时候要改变列表item中的某个值也需要使用this.$emit !!!但是如果是在forEach()里面可以直接赋值!!
如果列表是用v-for循环出来的,那么在进行选中判断的时候,可以使用索引来控制元素有没有被选中!!其中列表中的每一项使用forEach来循环相应的值,如果不是循环出来的列表,可以通过控制变量来实现选中操作!!!!!
循环出来的列表,控制选中方式!!!
forEach()循环
循环出来的列表样式控制
不是循环出来的列表选中方式控制
6.@click事件里面可以直接使用简单表达式操作,但是在使用vue的过程中,如是在视图html命令上进行操作元素,不用使用this来指定作用域进行操作,因为在指令里面默认作用域就是当前元素,使用指令会导致出错!只有在vue实例函数里面,才能使用this进行作用域指定!!!
7.vue中事件处理之事件修饰符@click.prevent.self和@click.self.prevent区别(事件执行的过程中,根据冒泡事件从最里层开始触发到最外层依次执行)!!!
@click.prevent事件表示,阻止默认事件例如a标签中<a href=”www.baidu.com” @click.prevent =”abc”> 这个时候a链接就不会跳转,而是会执行abc函数!!!!@click.prevent.self事件表示,会阻止所有的点击。
所以这两个的区别是@click.self.prevent只会阻止自身的点击事件,而不会阻止默认事件(跳转事件)。而@click.prevent.self都会阻止
@click.self.prevent事件表示只会阻止对元素自身的点击。就是只当在 event.target 即点击当前元素时触发处理函数,即如果事件不是自身元素触发时,而是内部元素点击冒泡触发时,改元素的点击事件不会被执行!!
实例1:@click.self.prevent
<div class="div1" @click="alertf(1)" style="background:#f00">我是第一个div <a class="div2" style="display: block;background:#ccc;80%;height:100px;" href="www.baidu.com" @click.self.prevent="alertf(2)">我是第一个div2 <div class="div3" style="background:#F1C142;70%;height:50px;" @click="alertf(3)">我是第一个div3</div> </a> </div>
上面的代码中,只有点击div2的时候alertf(2)才会被触发同时阻止默认跳转事件,触发完冒泡触发div1的点击事件alertf(1),然后div3的点击事件alertf(3)不会被触发!!!
点击div3,会alert3,alert1,跳转到/#。只阻止了alert(2)。因为会先判断self,点击到div3,不是self(即div2自身的点击),所以不会执行click事件,就不会执行 阻止默认事件和alert(2) ,所以可以跳转!!!!
实例2:@click.prevent.self
<div class="div1" @click="alertf(1)" style="background:#f00">我是第一个div <a class="div2" style="display: block;background:#ccc;80%;height:100px;" href="www.baidu.com" @click.self.prevent="alertf(2)">我是第一个div2 <div class="div3" style="background:#F1C142;70%;height:50px;" @click="alertf(3)">我是第一个div3</div> </a> </div>
点击div3,会alert3,alert1。不但阻止了alert(2),还阻止了a的默认跳转。
因为点击的时候会先prevent,阻止默认事件,阻止了跳转;然后判断是否是self,因为点击到的是div3,所以不是self,阻止了alert(2)。