路由器参数解耦
我相信这是大多数人处理组件中路由器参数的方式
export default {
methods: {
getRouteParamsId() {
return this.$route.params.id
}
}
}
在组件内部使用 $route
会对某个URL产生强耦合,这限制了组件的灵活性
router.js
const router = new VueRouter({
routes: [{
path: '/:id',
component: Component,
props: true
}]
})
//或者
const router = new VueRouter({
routes: [{
path: '/:id',
component: Component,
props: router => ({ id: route.query.id })
}]
})
export default {
props: ['id'],
methods: {
getParamsId() {
return this.id
}
}
}
v-for和v-if的联合用法
前端时间面试的时候, 有个面试官问我, v-for和v-if哪个优先级高, 是v-for的优先较高
业务中尽量不要出现v-if和v-for的联合用法
优化方案:
// 计算属性
computed: {
filterList: function () {
return this.showData.filter(function (data) {
return data.isShow
})
}
// DOM
<ul>
<li v-for="item in filterList" :key="item.id">
{{ item.name }}
</li>
</ul>
避免空class
<!-- 不建议 --><div :class="isBold ? 'bold' : ''"></div><!-- <div class> -->
<!-- 推荐写法 --><div:class ="isBold?'bold': null"></div> <!-- <div > -->
内容loading加载
设想一个场景 如果我们需要在数据渲染到页面的之前让页面 loading
。mounted
之后停止 loading
。beforeUpdata
时开始 loading
。updatad
之后停止 loading
。
最简单的方法就是改写组件的生命周期函数,使其在 mounted/beforeUpdata /updatad
时通知父组件显示或者隐藏 loading。
缺点
因为侵入了自组件的逻辑,增加的逻辑也和组件本身的功能好不关联。最好的办法就是使用 v-on="hook:xxx"
的方式:
<v-chart
@hook:mounted="loading = false"
@hook:beforeUpdated="loading = true"
@hook:updated="loading = false"
:data="data"
/>
sync语法糖
我们知道父传子,单向传递的,props,在一切特殊场景下,我们需要子组件修改父组件的值
object.freeze优化性能
export default {
data: () => ({
users: {}
}),
async created() {
const users = await axios.get("/api/users");
this.users = Object.freeze(users);
}
};
computed和watch使用场景的区分
计算属性computed:
- 支持缓存,只有依赖数据发生改变,才会重新进行计算
- 不支持异步,当computed内有异步操作时无效,无法监听数据的变化
- computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值
- 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed
如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。
侦听属性watch:
不支持缓存,数据变,直接会触发相应的操作;
- watch支持异步;
- 监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
- 当一个属性发生变化时,需要执行对应的操作;一对多;
- 监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数:
immediate:组件加载立即触发回调函数执行
deep: deep的意思就是深入观察,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器,但是这样性能开销就会非常大了,任何修改obj里面任何一个属性都会触发这个监听器里的 handler
vue如何监听对象或者数组某个属性的变化
this.$set(this.arr, 0, "OBKoro1"); // 改变数组
this.$set(this.obj, "c", "OBKoro1"); // 改变对象
vue如何获取dom
先给标签设置一个ref值,再通过this.$refs.domName获取
<div ref="test"></div>
const dom = this.$refs.test
on监听多个方法
<input type="text" v-on="{ input:onInput,focus:onFocus,blur:onBlur, }">
assets和static的静态文件处理
这两个都是用来存放项目中所使用的静态资源文件。
两者的区别:
assets中的文件在运行npm run build的时候会打包,简单来说就是会被压缩体积,代码格式化之类的。打包之后也会放到static中。
static中的文件则不会被打包。
将图片等未处理的文件放在assets中,打包减少体积。而对于第三方引入的一些资源文件如iconfont.css等可以放在static中,因为这些文件已经经过处理了。
关于静态资源的优化,尤其是图片,这里有几个建议
- 小图标使用
SVG
或者字体图标 - 通过
base64
和webp
的方式加载小型图片 - 能通过cdn加速的大图尽量用cdn
- 大部分框架都带有懒加载的图片,不要嫌麻烦,多花点时间使用它
ajax请求代码应该写在组件的methods中还是vuex的actions中
如果请求来的数据是不是要被其他组件公用,仅仅在请求的组件内使用,就不需要放入vuex 的state里。
如果被其他地方复用,这个很大几率上是需要的,如果需要,请将请求放入action里,方便复用。在v-model上怎么用Vuex中state的值
<input v-model="message">
// ...
computed: {
message: {
get () {
return this.$store.state.message
},
set (value) {
this.$store.commit('updateMessage', value)
}
}
}
mutation和action有什么区别
- action 提交的是 mutation,而不是直接变更状态。mutation可以直接变更状态
- action 可以包含任意异步操作。mutation只能是同步操作
提交方式:
action 是用this.store.dispatch('ACTION_NAME',data)来提交。
mutation是用this.$store.commit('SET_NUMBER',10)来提交
接收参数不同,mutation第一个参数是state,而action第一个参数是context,其包含了
组件中重复使用mutation
import { mapMutations } from 'vuex'
methods:{
...mapMutations({
setNumber:'SET_NUMBER',
})
}
调用方式
然后调用this.setNumber(10)相当调用this.$store.commit(‘SET_NUMBER’,10)
vue-router路由配置
主意其他错误错误路径进入的跳转
{path: '*', reditct: '/home'}
路由按需加载
{
path:'/',
name:'home',
components:resolve=>require(['@/components/home'],resolve)
}
webpack> 2.4 时
{
path:'/',
name:'home',
components:()=>import('@/components/home')
}
import()方法是由es6提出的,动态加载返回一个Promise对象,then方法的参数是加载到的模块。类似于Node.js的require方法,主要import()方法是异步加载的。
vue路由传参
使用query方法传入的参数使用this.$route.query接受, 内部传参this.$router.push(‘product?id =’ + id)
使用params方式传入的参数使用this.$route.params接受, /product/:id
router和route的区别
route为当前router跳转对象, 里面可以获取name、path、query、params等
router为VueRouter实例,想要导航到不同URL,则使用router.push方法
Vue里面router-link在电脑上有用,在安卓上没反应怎么解决
Vue路由在Android机上有问题,babel问题,安装babel polypill插件解决
Vue2中注册在router-link上事件无效解决方法
使用@click.native。原因:router-link会阻止click事件,.native指直接监听一个原生事件
RouterLink在IE和Firefox中不起作用(路由不跳转)的问题
- 只用a标签,不使用button标签
- 使用button标签和Router.navigate方法