1. 加载更多
插件:vue-infinite-scroll
2. ★★控制Footer的显示隐藏
router/index -----> meta: {} (路由元信息$route.meta.xxx)
| export default new VueRouter({ |
App.vue
| <FooterGuide v-show="$route.meta.showFooter"></FooterGuide> |
3. 图片懒加载: vue-lazyload
- Github:
https://github.com/hilongjw/vue-lazyload
- 下载包 不用下载: mint-ul库已经下载了这个库,可以直接用(间接依赖)
| npm install --save vue-loader |
- 使用
| import VueLazyload from 'vue-lazyload' import loading from './common/img/loading.gif' Vue.use(VueLazyload, {
<img v-lazy="food.image"> |
4. 使用: mode=hash #
- 打包前端应用: npm run build
- 将build文件夹中生成的所有打包文件拷贝到后台项目的public下
- 运行后台应用: npm start
- 访问: http://localhost:5000
使用mode=history
- 问题: 刷新某个路由路径时, 会出现404的错误
- 原因: 项目根路径后的path路径会被当作后台路由路径,
去请求对应的后台路由, 但没有
- 解决: 使用自定义中间件去读取返回index页面展现
| const fs = require('fs') |
5.你有对 Vue 项目进行哪些优化?
(1)代码层面的优化
-
v-if 和 v-show 区分使用场景
-
computed 和 watch 区分使用场景
-
v-for 遍历必须为 item 添加 key,且避免同时使用 v-if
-
长列表性能优化
-
事件的销毁
-
图片资源懒加载
-
路由懒加载
-
第三方插件的按需引入
-
优化无限列表性能
-
服务端渲染 SSR or 预渲染
(2)Webpack 层面的优化
-
Webpack 对图片进行压缩
-
减少 ES6 转为 ES5 的冗余代码
-
提取公共代码
-
模板预编译
-
提取组件的 CSS
-
优化 SourceMap
-
构建结果输出分析
-
Vue 项目的编译优化
(3)基础的 Web 技术的优化
-
开启 gzip 压缩
-
浏览器缓存
-
CDN 的使用
-
使用 Chrome Performance 查找性能瓶颈
6. 如何在v-for 循环中实现v-model 数据的双向绑定?
有时候需要循环创建input,并用v- model实现数据的双向绑定。此时可以为v- model绑定数组的一个成员 selected [$ index],这样就可以给不同的 input绑定不同的v- model,从而分别操作它们。
<div v-for= " ( item, index ) in arr"><input type= "text " v-model="arr [index ] "><h1> { { arr [index ] } } </h1></div>
7. vue首屏白屏如何解决?
1)路由懒加载
2)vue-cli开启打包压缩 和后台配合 gzip访问
3)进行cdn加速
4)开启vue服务渲染模式
5)用webpack的externals属性把不需要打包的库文件分离出去,减少打包后文件的大小
6)在生产环境中删除掉不必要的console.log
plugins: [new webpack.optimize.UglifyJsPlugin({ //添加-删除console.logcompress: {warnings: false,drop_debugger: true,drop_console: true},sourceMap: true}),
7)开启nginx的gzip ,在nginx.conf配置文件中配置
http { //在 http中配置如下代码,gzip on;gzip_disable "msie6";gzip_vary on;gzip_proxied any;gzip_comp_level 8; #压缩级别gzip_buffers 16 8k;#gzip_http_version 1.1;gzip_min_length 100; #不压缩临界值gzip_types text/plain application/javascript application/x-javascript text/cssapplication/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;}
8)添加loading效果,给用户一种进度感受
8. $nextTick的使用?
答:在vue中理解修改数据后,对应的dom需要一定的时间进行更新,因此为了能够准确的后去更新后的dom,可以采用延迟回调的方法进行更新dom的获取,所以出现了$nextTick来进行延迟回调。即:在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。
9.route和router的区别?
$router
router是VueRouter的一个对象,通过Vue.use(VueRouter)和VueRouter构造函数得到一个router的实例对象,这个对象中是一个全局的对象,他包含了所有的路由包含了许多关键的对象和属性,常见的有:
1)push:向 history 栈添加一个新的记录,当我们点击浏览器的返回按钮时可以看到之前的页面
// 字符串this.$router.push('home')// 对象this.$router.push({ path: 'home' })// 命名的路由this.$router.push({ name: 'user', params: { userId: 123 }})// 带查询参数,变成 /register?plan=123this.$router.push({ path: 'register', query: { plan: '123' }})
2)go:页面路由跳转 前进或者后退
// 页面路由跳转 前进或者后退this.$router.go(-1) // 后退
3)replace:push方法会向 history 栈添加一个新的记录,而replace方法是替换当前的页面,不会向 history 栈添加一个新的记录
$route
$route对象表示当前的路由信息,包含了当前URL解析得到的信息。包含当前的路径、参数、query对象等。
1)$route.path:字符串,对应当前路由的路径,总是解析为绝对路径,如 "/foo/bar"。
2)$route.params:一个 key/value 对象,包含了 动态片段 和 全匹配片段,如果没有路由参数,就是一个空对象。
3)$route.query:一个 key/value 对象,表示 URL 查询参数。例如,对于路径 /foo?user=1,则有 $route.query.user == 1,如果没有查询参数,则是个空对象。
4)$route.hash:当前路由的 hash 值 (不带#) ,如果没有 hash 值,则为空字符串。
5. $route.fullPath:完成解析后的 URL,包含查询参数和 hash 的完整路径。
6 $route.matched:数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。
7. $route.name:当前路径名字
8. $route.meta:路由元信息
10. vue-router实现懒加载的方式?
vue异步组件
vue异步组件技术 ==== 异步加载
vue-router配置路由 , 使用vue的异步组件技术 , 可以实现按需加载 。但是,这种情况下一个组件生成一个js文件
/* vue异步组件技术 */{path: '/home',name: 'home',component: resolve => require(['@/components/home'],resolve)},{path: '/index',name: 'Index',component: resolve => require(['@/components/index'],resolve)},{path: '/about',name: 'about',component: resolve => require(['@/components/about'],resolve)}
es提案的import()
路由懒加载(使用import)
// 下面2行代码,没有指定webpackChunkName,每个组件打包成一个js文件。/* const Home = () => import('@/components/home')const Index = () => import('@/components/index')const About = () => import('@/components/about') */// 下面2行代码,指定了相同的webpackChunkName,会合并打包成一个js文件。把组件按组分块const Home = () => import(/* webpackChunkName: 'ImportFuncDemo' */ '@/components/home')const Index = () => import(/* webpackChunkName: 'ImportFuncDemo' */ '@/components/index')const About = () => import(/* webpackChunkName: 'ImportFuncDemo' */ '@/components/about')
{path: '/about',component: About}, {path: '/index',component: Index}, {path: '/home',component: Home}
webpack的require,ensure()
vue-router配置路由,使用webpack的require.ensure技术,也可以实现按需加载。这种情况下,多个路由指定相同的chunkName,会合并打包成一个js文件。
/* 组件懒加载方案三: webpack提供的require.ensure() */{path: '/home',name: 'home',component: r => require.ensure([], () => r(require('@/components/home')), 'demo')}, {path: '/index',name: 'Index',component: r => require.ensure([], () => r(require('@/components/index')), 'demo')}, {path: '/about',name: 'about',component: r => require.ensure([], () => r(require('@/components/about')), 'demo-01')}
11. 路由跳转和location.href的区别?
使用location.href='/url'来跳转,简单方便,但是刷新了页面;
使用路由方式跳转,无刷新页面,静态跳转;
12. vue的solt的用法?
在子组件内使用特殊的<slot>元素就可以为这个子组件开启一个slot(插槽),在父组件模板里,插入在子组件标签内的所有内容将替代子组件的<slot> 标签及它的内容。
简单说来就是:在子组件内部用 <slot></slot>标签占位,当在父组件中使用子组件的时候,我们可以在子组件中插入内容,而这些插入的内容则会替换 <slot></slot>标签的位置。
当然:单个solt的时候可以不对solt进行命名,如果存在多个 则一个可以不命名,其他必须命名,在调用的时候指定名称的对应替换slot,没有指定的则直接默认无名称的solt
13. vue开发遇到的问题?
1)样式污染
答:在编写样式中,如果需要防止样式的污染,可以使用两种方式:
一种是在组件的根元素上增加一个唯一的class或者id,然后在编写组件的样式时候在根元素对应的class或者id下进行编写;
另一种方式是在对应的style上添加scoped关键字,不过该关键字对引用的框架UI无效
2)router-link在安卓上不起作用
答:不起作用的原因是因为转码编译的问题,可以使用babel来进行处理,安装babel polypill插件解决
3)初始化页面出现闪屏乱码的问题
答:这是因为vue还没有解析的情况下会容易出现花屏现象,看到类似于{{data}}的字样,可以使用两种方式来进行处理,一种为:在设置index.html的根元素的元素的样式为display:none,然后在mounted中的$nextTick函数中display:block展示;另一种方式是使用vue的内置指令:v-cloak,并且在css中设置样式
[v-cloak] {display: none;}
4)router-link上事件无效解决方法
答:使用@click.native来进行调用原生的js事件。原因:router-link会阻止click事件,.native指直接监听一个原生事件。
14. 合并数组
合并数组可以通过多种方式完成。一种是内置concat()功能。另一个是点差运算符(…)。在这里,我解释了两者。
let arrOne = [1,3,5]let arrTwo = [2,4,6]// first waylet combine = arrOne.concat(arrTwo)console.log(combine)// second waycombine = [...arrOne,...arrTwo]console.log(combine)
ps: 你可以使用传播运算符(...)将一个数组的元素扩展为另一个数组,例如:
const numbers = [10, 20, 30, 40];
const allNumbers = [...numbers, 50, 60, 70, 80];
console.log(allNumbers);
// 输出
[10, 20, 30, 40, 50, 60, 70, 80]
ps:点差运算符速记
//longhand// joining arrays using concatconst data = [1, 2, 3];const test = [4 ,5 , 6].concat(data);//shorthand// joining arraysconst data = [1, 2, 3];const test = [4 ,5 , 6, ...data];console.log(test); // [ 4, 5, 6, 1, 2, 3]
对于克隆,我们也可以使用传播运算符。
//longhand// cloning arraysconst test1 = [1, 2, 3];const test2 = test1.slice()//shorthand// cloning arraysconst test1 = [1, 2, 3];const test2 = [...test1];
15.从阵列中删除重复项(数组去重)
const numbers = [1, 1, 20, 3, 3, 3, 9, 9];const uniqueNumbers = [...new Set(numbers)];console.log(uniqueNumbers);
输出:
[1, 20, 3, 9]
16. 交换两个变量而没有第三个
let x = 1;let y = 2;[x, y] = [y, x];console.log(x, y);
输出:
2 1
17. 将数字转换为字符串
const num = 1 +“”;console.log(typeof num);console.log(num);
输出:
string1
18.将字符串转换为数字
const numStr = "124";const num = +numStr;console.log(typeof num);console.log(num);
输出:
number84
19. 将变量嵌入到字符串
通过使用反引号(`)将字符串括起来并将变量插入之间,将变量整齐地嵌入到字符串之间${}:
const age = 41;const sentence = `I'm ${age} years old`; console.log(sentence); //I'm 41 years old另外://longhandconst welcome = 'Hi ' + test1 + ' ' + test2 + '.'//shorthandconst welcome = `Hi ${test1} ${test2}`;
20.将字符串拆分为数组
要将字符串拆分为数组,可以使用扩展运算符(...):
const str = "Test"const strAsArr = [...str]console.log(strAsArr)
输出:
["T", "e", "s", "t"]
21.查找对象数组
进入阵列是日常开发或编程中最需要完成的任务。在这里,我们使用find函数来执行此操作。该功能也适用于其他阵列。数字数组,对象数组,字符串数组,所有内容都支持此方法。
简单代码如下:
const students = [{name: 'Shoaib', roll: 2},{name: 'Mehedi', roll: 10},{name: 'Alex', roll: 5}]; // 先找到"Mehedi" function search(student) { return student.name === "Mehedi"; }// 再找到包含"Mehedi"的.. console.log(students.find(search)); // { name: 'Mehedi', roll: 10 }
Array.find的简写★
当我们确实有一个对象数组并且我们想要根据对象属性查找特定对象时,find方法确实很有用。
const data = [{type: 'test1',name: 'abc'},{type: 'test2',name: 'cde'},{type: 'test1',name: 'fgh'},]function findtest1(name) {for (let i = 0; i < data.length; ++i) {if (data[i].type === 'test1' && data[i].name === name) {return data[i];}}}//ShorthandfilteredData = data.find(data => data.type === 'test1' && data.name === 'fgh');console.log(filteredData); // { type: 'test1', name: 'fgh' }
22. 滚动到页面顶部
该window.scrollTo()方法可以帮助你完成任务。它需要滚动到页面上该位置的x和y坐标。如果将它们设置为(0,0),它将滚动到页面顶部。
const goToTop =()=> window.scrollTo(0,0);goToTop();
23.声明变量
当我们要声明两个具有共同值或共同类型的变量时,可以使用此简写形式。
//Longhandlet test1;let test2 = 1;//Shorthandlet test1, test2 = 1;
24.给多个变量赋值
当我们处理多个变量并希望将不同的值分配给不同的变量时,此速记技术非常有用。
//Longhandlet test1, test2, test3;test1 = 1;test2 = 2;test3 = 3;//Shorthandlet [test1, test2, test3] = [1, 2, 3];
25. 箭头函数
//Longhandfunction add(a, b) {return a + b;}//Shorthandconst add = (a, b) => a + b;
更多示例
function callMe(name) {console.log('Hello', name);}callMe = name => console.log('Hello', name);
26.短函数调用
我们可以使用三元运算符来实现这些功能。
// Longhandfunction test1() {console.log('test1');};function test2() {console.log('test2');};var test3 = 1;if (test3 == 1) {test1();} else {test2();}// Shorthand(test3 === 1? test1:test2)(); // 括号:函数调用
27. 默认参数值
//Longhandfunction add(test1, test2) {if (test1 === undefined)test1 = 1;if (test2 === undefined)test2 = 2;return test1 + test2;}//shorthandadd = (test1 = 1, test2 = 2) => (test1 + test2);add() //output: 3
28. 对象属性分配
let test1 = 'a';let test2 = 'b';//Longhandlet obj = {test1: test1, test2: test2};//Shorthandlet obj = {test1, test2};
29.分配速记(项目懂)
//longhandconst test1 = this.data.test1;const test2 = this.data.test2;const test2 = this.data.test3;//shorthandconst { test1, test2, test3 } = this.data;
30.在数组中查找最大值和最小值
const arr = [1, 2, 3];Math.max(…arr); // 3Math.min(…arr); // 1
477

被折叠的 条评论
为什么被折叠?



