单选/复选
<div id="app"> <!--checkbox需要给每个复选双向绑定同一个数据,并添加value值, 点击某个复选时就会把该复选的value值添加到数据里,复选显示选中状态,再点击移除该数据显示未选中状态--> 喜欢谁?<input type="checkbox" v-model="a" value="北京">北京 <input type="checkbox" v-model="a" value="天津">天津 <input type="checkbox" v-model="a" value="上海">上海 {{a}} </div> <script> var vm=new Vue({el:"#app", data:{a:[]}}) </script> 单选框也这么写
- vuetools工具
下载工具地址https://github.com/arcliang/Vue-Devtools- 通过git下载到本地 打开谷歌浏览器-更多工具-扩展程序。直接将Chrome文件夹拖拽到扩展程序区域,浏览器会自动识别安装 右上角会出现灰色vue图标,以后运行vue程序时他就会亮了 使用 控制台会出现vue项,点击其中的root会看到所有挂在根实例上的内容
vue中的动态绑定
<img :src="item.img" alt="">
这样动态绑定的右边是变量,变量一般是定义在data数据里的。如果不用:动态绑定数据右侧是字符串,无其他意义
- @keyup键盘抬起事件,需要搭配input表单控件使用
<div id="app"> <input @keyup.13="fn">点我呀</input> //当键盘抬起时且是enter键时执行fn函数,13代表的也是enter键只不过13是键盘码。也可以@keyup.13。ctrl="fn"同时按住两个键抬起才会执行fn函数 </div>
钩子函数this也指向实例
- methods里定义方法,created里调用
- 取变量对应的值用:src="a.img"。在外面取用大括号,在属性里用:
- HTML结构中取数据不用实例.xxx。可以直接xxx取数据
- <input type="number" v-model.number.lazy="b">如果想要输入框只能输入是数字,类型得是number。data中获取到的想要是数字类型需要加修饰符.number,想要input失去焦点才更新数据用修饰符.lazy
- 计算属性,动画
- 计算属性虽然里面是函数但是还是属性,有两个方法,get,set。默认调用get方法必须有return
- .stop阻止事件冒泡
- .capture捕获
- .prevent阻止默认事件触发
- .once事件只执行一次
- .self只有点自己时触发事件
- v-model第一步会将值取出来放到这里
- @blur失去焦点事件
created:function(){ //从浏览器的localstorage里获取数据.如果有数据就获取,没有用自己的定义的数据 this.list=JSON.parse(localStorage.getItem("data"))||this.list; this.hash="#/all"; window.addEventListener("hashchange",()=> { //监控哈希值的变化,页面有哈希或哈希值变化都重新获取数据 this.hash=window.location.hash//#/finish //console.log(window.location)//存着浏览器的所有信息 },false) //页面加载时直接created,拿哈希值。以后页面变化也会走hashchange这个事件重新拿哈希值。 } 用watch监控哈希的变化不可以吗 watch:{ route: } watch:{//监控list数据,有变化就存储到本地浏览器 list:{ handler() { console.log(1) localStorage.setItem("data",JSON.stringify(this.list))//默认存的是字符串,取得也是字符串 //每一次数据改变都往本地存 },deep:true //深度监控 //默认只监控数组一层的变化。即数组里面每一项对象的增减可以监控,但对象里的内容变化无法监控 } //写法是固定的,handler名字也是固定的 },
组件特点就是独立性,根组件外的组件data使用函数返回对象的形式是为了保证组件数据的独立性。且在哪个组建中this指的就是当前组件
不同函数返回的data对象空间不是一个,不会公用数据。所以子组件不能直接拿父组件的数据
组件上绑定的事件都是自定义事件
父组件通过动态绑定数据的方法将数据传递给子组件,子组件通过props数组接收,然后将数据绑定到当前组件上。子组件向父组件传递数据父组件定义好方法,后通过自定义事件绑定在子组件模板上。子组件中通过this.$emit(自定义事件名,参数)方法触发模板上自定义事件绑定的方法
三种情况下会缓存组件
第一种
<keep-alive>
<!--缓存组件,如果缓存了就不会再走钩子函数-->
<component :is="val"></component> </keep-alive>
第二种
v-if
第三种
router-view
- mounted钩子函数里DOM渲染是异步操作,即你数据变化了但是根据数据渲染页面是需要时间的,此时你在父级mounted里拿元素,DOM还没渲染好你拿到的还是之前的元素,所以才需要在this.$nextTick(function(){})的回调函数里拿元素
- 项目并没有less的安装包,但是他把less配好了。如果你安装了less的安装包他就支持了。less,less-loader
proxyTable: { '/api': { target: 'http://api.douban.com/v2', // 目标url changeOrigin: true, // 是否跨域 pathRewrite: { '^/api': '' // 可以使用 /api 等价于 http://api.douban.com/v2 } } },
- 配路由,加router-link,router-view
- app.vue默认样式是全局的,使用了则所有的组件都会使用,也不用加scope
- 父组件需要使用子组件,引入-注册-使用
- <style scoped lang="less"> </style>使用less
- fixed将底部导航固定在下面
- 希望点的时候加激活样式a.router-link-active{color:red}该链接激活时会拥有这个类名,即会有这些样式
- 头也用fixed定位来固定
- localstorage.setItem("自定义",字符串数据)。存的时候是字符串,取得时候也是字符串
- 返回按钮有没有,通过home组件给封装的头部组件传值。头部组件里通过props接收home组件传递的值验证是否是布尔类型的值,且设置默认值。父组件不给传值用默认的值。slot是父组件使用模板组件时模板HTML中间的内容插入到slot里,即父组件中模板HTML中间是什么slot就是什么就可以实现首页显示首页两字,列表页显示列表两字
- 体轮播图距离头尾分别一段距离站中间所有区域,用一个div.content盒子包起来,头尾是定位,这个content盒子也定位。设置overflow:auto让中间高出的部分就可以滚动了,样式是全局的写在app.vue里
- webpack会启动一个服务,后台也会启动一个服务。webpack里去访问另一个服务就跨域了。8080掉后台3000端口。后台用cors处理前端跨域
- 直接/slider请求发送到自己身上了,所以需要将url写全即http://localhost:3000/slider,但前面的路径是死的每次发送请求都需要写,很麻烦,axios为我们提供了一个默认的方法axios.defaults.baseURL="http://localhost:3000";设置默认的基本路径,也就是说以后在发送请求时他会把这个设置的默认基本路径加上。
- 将请求方法一个个实名导出,以后调用时直接发送axios请求。返回的是promise实例能够调用then方法
- 导入方法时用解构赋值的方法
- async和await。await后面只能跟promise实例(结果是得到异步的结果,可以直接将结果结构出来),async写在await前面最近的函数前面,即使是钩子函数
-
//传统写法 created(){ getslider().then((response)=>{ var {data}=response; console.log(data);//拿到数据 }) } //语法糖 async created(){ var {data}=await getslider(); console.log(data);//拿到数据 }
- 轮播图将拿到的数据通过动态绑定数据的方式(:slide="swiperData",slide是自定义的,swiperData是数据)将数据传递给轮播图轮播图组件,子组件通过props:["slide"]接收父组件的数据,并将数据绑定到当前组件的实例上
- 图片过大,是图片尺寸的问题。我们设置一下图片尺寸即可
- 获取数据为什么不在swiper组件里面写死呢,非要在使用swiper组件的父级组件里获取数据再传递给swiper???因为如果在swiper里获取数据那不管有多少轮播图长得都一个样,因为这个组件是复用的,所以数据应该是他爸爸决定的,如果是他自己决定的那都长得一样
- 布局结构:APP.vue页有tab组件(实际上是底部的四个router-link路由)和router-view。通过点击router-link显示对应的home页还是list页在router-view这里,home也有什么呢?home页有头,体
- 在哪个组建中调取API读取数据?如果是一个基础组件即可多次复用的组件那我们在他的父级调取API获取数据然后再传递给他。不需要复用的组件直接在组件内部获取数据即可
- created里面调用,功能写在methods里
- axios同时处理两个请求???
.container ul{ display: flex; <!--li宽度50%即一行放两个,达到最大宽度自动折行。默认不折行--> flex-wrap: wrap; li{ width: 50%; } }
- 脚手架启动的服务默认访问路径是/,我们需要处理一下。访问/的时候重定向到首页,随便访问"*"也重定向到首页
- options请求是试探性请求
- 删除请求是删除后台请求前台数据还没变,可以重新发送请求获取数据或者自己删除前台数据里的该项页面都会重新变化
- 当点击列表页的书图片时,会进入detail/xxx,路由参数变化。给每个li设置点击功能(变为a标签,但我们需要li标签所以要加个属性tag="li",通过路由参数变化跳转需要加动态加to属性,to一个对象,里面两组键值对,name,和params。所以要求路由配置表里面配置路由时增加name属性
- 点击删除时阻止他的冒泡事件,否则点击删除也会跳到详情页。即触发他父级的事件
- 让detail盒子把整个页面都遮住,定位四个方向为零(让盒子自动适应)设置z-index
- 某个盒子的具体信息刷新出来了,但是你改变路由参数想改变为其他盒子的信息发现不刷新,因为组件已经渲染出来了不会再走钩子函数了,用watch监听路由参数变化,变化重新发送请求获取数据
- 路由参数变化和多级路由的区别???路由参数变化是一个页面展示的不同信息,多级路由是在根路由上局部刷新组件例如后台系统。路由参数变化一般用在详情页,多级路由一般用在后台管路系统,一级路由就可以搞定简单的app开发
- 怎么判断一个对象是不是空对象,用Objext.keys(对象)。返回的值是数组,数组的每一项是对象的属性名key,判断数组的长度,数组长度大于零对象不为空
- 当轮播图和图书数据都加载完成loading效果才消失,如何写?
//获取轮播图数据 export function getslider() { return axios.get("/slider") } //获取热门图书数据 export function getbookdata() { return axios.get("/book") } //封装一下,同时发送两个请求(轮播图,热门图书) export function twoget() { return axios.all([getslider(),getbookdata()]) } two(){ getall().then(axios.spread((slider, hotbook)=> {//slider是第一个请求的数据, hotbook是第二个请求的数据 this.imgdata=slider.data; this.bookdata=hotbook.data; this.flag=false })) } <!--以下不行不知道为什么,所以这个就不用语法糖了--> async two(){ let [a,b]=await getall();//合并请求返回的是数组,里面的每一项是每个请求返回来的数据 <!--同时获取两组数据--> this.imgdata=a; this.bookdata=b; this.flag=false;//加载数据完成,不显示 }
- 把加载组件和轮播图与热门图书组件看作一个整体。怎么把两部分弄成一个整体但是还不想增加标签?用template包裹两个部分。然后加载与这个整体你死我活只显示一个。v-if="" v-else
- 默认加载组件是显示的,数据拿回来加载组件消失。加载组件就是一个css效果
- 路由元信息,在配置路由的时候可以增加路由元信息,他会把这信息放在路由属性上的,如下
{path:"/home",component:()=> {return import("../components/home")},meta:{keepalive:true,title:"首页"}} 获取的时候this.$route.meta.keepalive即可获取到存储在路由上的路由元信息
- 分页拿书,判断是不是还有跟多书,如果有更多发送请求拿书,每一次将拿回来的书添加到数据里不是替换,这样数据才会越来越多,另外是不是有更多也看后台返回的数据。
- 数组拼接[...a,...b]
- 根据书的长度拿数据,即第一次拿,后台会默认返回给你5本书,数据数组的长度为5。第二次后台会返回给你5+5本书,数据数组的长度为10.第三次他会返回给你10+5本书。。。其实不是这样的。他会拿到你越来越大的偏移量,你的偏移量为什么会越来越大因为你的数据越来越多数据的长度就会越来越大,后台拿到的也就会越来越大。后台拿到后会在该基础上加固定值截取中间这段数据给你返回也就是5条数据。前端传递是根据数组的长度传递偏移量
- 点击:默认没有正在加载,点击时正在加载,获取到数据就加载完毕。这样设置是因为如果网不好的话你点击多次,他会同一次请求请求多次,显示多条相同的数据。你设置了之后只有当你加载完成时,loading变为false才能通过条件在发送请求,否则发送不了请求。这就防止你点击多次了
- content能滚动,给他添加滚动事件@scroll="loadmore"。滚动的时候只要一滚动就会触发滚动事件,这样滚动事件触发的太频繁了。滚动事件里面是需要获取元素的你滚动就获取元素太浪费性能了,我们应该减少滚动事件的触发 当符合条件时出发加载更多
<div class="content" @scroll="loadmore" ref="scroll"> loadmore:function(){ clearTimeout(this.timer); this.timer=setTimeout(()=> { let {scrollTop,clientHeight,scrollHeight}=this.$refs.scroll;//卷曲的高度,当前可见区域,总高 if(scrollTop+clientHeight+20>=scrollHeight){ this.getallbookdata(); } },60)//13毫秒触发一次滚动事件 } 这样每次触发滚动事件时都会触发该函数,但是函数里面的定时器可以帮我们减少滚动事件触发带来的获取DOM 滚动事件被触发就会开启一个定时器,所以我们需要接收定时器的值好在开启定时器之前就清除上个定时器。讲定时期的值挂载在vue组件上即可
图片懒加载插件
安装 npm i vue-lazyload -S 引用 import VueLazyload from 'vue-lazyload' Vue.use(VueLazyload, { preLoad: 1.3, error: 'dist/error.png',;//错误图地址 loading: 'dist/loading.gif',;//缓冲图地址 attempt: 1 }) 然后再需要懒加载的图片上加上v-lazy属性即可,如下 <img :src="item.bookimg">变为<img v-lazy="item.bookimg"> 他会先显示假的,拿到真正图片时地址就真正图片的地址了
- 代码分割:点一个页面-加载当前页
- 以前的写法,会找到所有组件将它们打包到一起。现在换成动态加载当前页即点击某个路由匹配到路径会执行路径对应的函数,函数会动态载入组件
- vue也有类似于中间件的东西,将共用的放在一起。每个页面一加载取一下元信息放在页面上。利用路由的全局钩子router.beforeEach(function(){})在进入路由之前每一个次都会执行这个方法
router.beforeEach(function (to,from, next) {//在进入路由之前每一个都会执行这个方法 //from 从哪个路由来 //to 到哪个路由下 //next 继续往下走 document.title=to.meta.title; //当然了功能还以更强的,比如有权限的页面。 // 本来是去某个需要权限的页面但是验证后没有权限next({path:"registe"})去其它页面 if(to.path==="/collect"){ return next({path:"/list"}) } next();//必须调用,不调用不会执行下面的路由 });