理理Vue细节

1. 动态属性名:可使用表达式来设置动态属性名或方法名:

<!-- 属性name -->
<a :[name]="url"> ... </a>
<!-- 计算属性sss和s -->
<img :[sss]="/img/test.png"/>
<!-- 方法change1和change2 -->
<img :[change1()]="change2()"/> data: {
name: 'href',
sss: 'src'
}

注意:要避免空格和引号等,且需要小写,可使用计算属性来应对复杂表达式,都需要使用[]

2. computed/methods/watch

  • computed可使用get/set
   computed: {
top() {
return 'top'
},
name: {
get () {
return this.name
},
set (val) {
this.name = val
}
}
}
 
  • computed可缓存,但不可传参,会根据data中的属性变化而变化,即是根据响应式依赖来变化,而Date不是响应式依赖,即不会变化;method则每次都会进行计算,但可传参。

  • watch用于处理异步或开销较大的操作,如输入搜索时。

3. style绑定

  • 直接对象或变量对象
  • 计算属性
  • 直接style或style对象
<!-- 属性名可加引号也可不加,属性小驼峰 -->
<div :style="{ 'color': 'red', fontSize: fontSize + 'px' }">样式3</div>
  • 数组结合三目/数组结合对象
data: {
isActive: true,
activeClass: 'active'
}
<!-- 使用数组时变量和字符串需要通过引号来区分 -->
<div :class="[isActive ? activeClass : '', 'errorClass']"></div>
<!-- 使用对象时类名不加引号可表示变量也可表示字符串 -->
<div :class="[{ active: isActive }, 'errorClass']"></div>

4. v-if条件渲染

  • 可使用template包裹元素,template会被当成不可见的包裹元素
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
  • 多条件判断
<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Not A/B/C
</div>

5. key

  • 添加key防止vue重复利用不想被重复利用的元素,如下的input如果不添加key,则vue会重复使用key,进而inputvalue值在切换后还会被保留,因为vue仅仅替换了placeholder
<template v-if="loginType === 'username'">
<label>Username</label>
<input placeholder="Enter your username" key="username-input">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Enter your email address" key="email-input">
</template>

6. v-if和v-show

  • v-if是组件的销毁和重建,如果初始条件为false,则什么都不做,直到变为真,所以切换开销高,运行条件很少改变时适用
  • v-showdisplay:noneblock之间的CSS切换,基于渲染,不管初始条件如何都会渲染,所以初始渲染开销高,切换频率高时适用

7. v-for

  • 可使用in或者of
  • 也可遍历对象:v-for="(value, key, index) in obj"
  • 可根据template渲染多个组合元素:
<ul>
<template v-for="item in items">
<li>{{ item.msg }}</li>
<li class="divider"></li>
</template>
</ul>
 

8. v-for和v-if

  • v-for优先级更高,所以v-if会重复运行于每个v-for循环中,所以尽量不要一起使用,可先使用计算属性对数据进行过滤再遍历。

9. 更改响应式数据

  • Vue.set(object, key, value)
  • this.$set(object, key, value)
  • this.items.splice(index, 1, newValue)
  • 批量添加属性:
// 不要直接Object.assign(this.items, {age: 18}
this.items = Object.assign({}, this.items, {
age: 18,
favoriteColor: 'Vue Green'
})

10. 事件修饰符

  • .passive:滚动的默认事件会立即出发,即告诉浏览器不想阻止默认事件的触发,可提升移动端性能
<div :scroll.passive="onScroll">...</div>
 
  • .capture:添加事件监听器时使用事件捕获模式,即元素自身触发的事件先在此处理,然后才交由内部元素进行处理
  • .self:只当在 event.target 是当前元素自身时触发处理函数,即事件不是从内部元素触发的
  • .once:点击事件只会触发一次
  • 键盘修饰符: <input v-on:keyup.enter="submit">

11. v-model

  • 选择框
<!-- 单选框时,picked为字符串 "a",不是布尔值 -->
<input type="radio" value="a" v-model="picked"> <!-- 多选框时,toggle默认值设为字符串或布尔值时得到布尔值,设为数组时得到的是value值-->
<input type="checkbox" value="b" v-model="toggle"> <!-- 当选中第一个选项时,selected为字符串value的值 "abc" -->
<select v-model="selected">
<option value="abc">ABC</option>
</select>
  • 修饰符.lazy:在change时而非input时更新 <input v-model.lazy="msg" >

注:change事件是在input失去焦点时触发,即用于单选、多选框和选择框,而input事件是在value值变化时触发,但脚本改变value值时不会触发,即用于text和textarea

  • 修饰符.number:输入值转为数值
  • 修饰符.trim:过滤收尾空白字符

12. Prop

  • 使用v-bind="obj"会将对象的每个属性都作为一个独立的prop传入进去,所以接受时也需要逐个属性接收。
<test v-bind="obj"></test>
  • props虽然是单向数据流,但对于引用类型,子组件还是可以改变父组件的状态。
  • props会在组件实例创建之前进行验证,所以实例的属性再defaultvalidator中是不可用的。

13. 自定义事件

  • 自定义事件需要注意事件名为小写或-分隔,因为$emit('BaseEvent')虽然事件名不会变,但在html中该事件名会被转化为小写,不会监听到。

14. slot

  • 具名插槽
<base-layout>
<template v-slot:header>
<h1>Here might be a page title</h1>
</template>
<!-- 默认插槽也可不用加上template和v-slot -->
<template v-slot:default>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</template>
<template v-slot:footer>
<p>Here's some contact info</p>
</template>
</base-layout>
 
  • 作用域插槽
<!-- current-user组件 -->
<span>
<slot :user="user">
{{ user.lastName }}
</slot>
</span> <!-- 父级组件通过自定义名称访问子级作用域 -->
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
</current-user> <!-- 支持缩写和解构 -->
<current-user>
<template #default="{ user = { firstName: Gust } }">
{{ user.firstName }}
</template>
</current-user>
 

15. 组件通信

  • vuex/eventBus
  • prop/$emit
  • $children/$parent
  • provide/inject
  • $refs
// 父或祖先级
provide: function () {
return {
getMap: this.getMap
}
} // 后代级
inject: ['getMap']
 

16. scope

  • scoped 属性会自动添加一个唯一的属性 (比如 data-v-21e5b78) 为组件内 CSS 指定作用域,编译的时候 .list-container:hover 会被编译成类似 .list-container[data-v-21e5b78]:hover

17. 路由

  • 区分:this.$router指路由器,this.$route指当前路由

  • 通配符:捕获所有路由或 404 Not found路由

  // 含通配符的路由都要放在最后,因为优先级由定义顺序决定
{
// 会匹配所有路径
path: '*'
}
{
// 会匹配以 `/user-` 开头的任意路径
path: '/user-*'
}
 
  • 当使用一个通配符时,$route.params内会自动添加一个名为 pathMatch 参数。它包含了 URL 通过通配符被匹配的部分:
// 给出一个路由 { path: '/user-*' }
this.$router.push('/user-admin')
this.$route.params.pathMatch // 'admin'
// 给出一个路由 { path: '*' }
this.$router.push('/non-existing')
this.$route.params.pathMatch // '/non-existing'
  • 点击 <router-link :to="..."> 等同于调用 router.push(...)方法,因为<router-link>会在内部调用该方法,进而在history栈添加一个新的记录

  • 使用了push时,如果提供的path不完整,则params会被忽略,需要提供路由的 name 或手写完整的带有参数的 path

const userId = '123'
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user
 
  • router.push/router.replace/router.go 效仿于 window.history.pushState/window.history.replaceState/window.history.go

  • 命名视图:router-view可设置名字,如果router-view没有设置名字,那么默认为 default

<router-view></router-view>
<router-view name="a"></router-view>
<router-view name="b"></router-view> const router = new VueRouter({
routes: [
{
path: '/',
components: {
default: Foo,
a: Bar,
b: Baz
}
}
]
})
 
  • 路由使用props:可将路由参数设置为组件属性
const User = {
props: ['id'],
template: '<div>User {{ id }}</div>'
}
// 通过布尔值设置
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User, props: true }, // 对于包含命名视图的路由,你必须分别为每个命名视图添加 `props` 选项:
{
path: '/user/:id',
components: { default: User, sidebar: Sidebar },
props: { default: true, sidebar: false }
}
]
}) // 通过函数设置query
// URL /search?q=vue 会将 {name: 'vue'} 作为属性传递给 SearchUser 组件
const router = new VueRouter({
routes: [
{ path: '/search', component: SearchUser, props: (route) => ({ name: route.query.q }) }
]
})
 
  • beforeRouteEnter:可使用beforeRouteEnter来提前获取接口数据,同时需要在next后才能访问到实例:
beforeRouteEnter(to, from, next) {
axios('/text.json').then(res => {
next(vm => {
vm.datas = res
})
})
}
 
  • 路由设置有参数时,如果跳转页面后再通过返回键返回时,路由会保留有参数,如果通过push跳转返回,则不会保留该参数,这在第三方调用模块传参时需要注意。

18. loader

  • Vue Loader编译单文件的template块时,会将所有遇到的URL资源转为webpack模块请求:
// <img src="../image.png">将会被编译成为:
createElement('img', {
attrs: {
src: require('../image.png') // 现在这是一个模块的请求了
}
})
  • 资源URL转换规则
  1. 如果是绝对路径,例如 /images/foo.png),则会原样保留。
  2. 如果路径以.开头,将会被看作相对的模块依赖,并按照你的本地文件系统上的目录结构进行解析。
  3. 如果路径以~开头,其后的部分将会被看作模块依赖。
  4. 如果路径以 @ 开头,也会被看作模块依赖。

后续会持续更新,欢迎关注!

转载链接:https://juejin.im/post/5cb444605188251ada7e320d

理理Vue细节的更多相关文章

  1. vue 细节注意

    *只有vm.$data这些被代理的属性是响应的,能够重新渲染视图 *注意,不要在实例属性或者回调函数中(如 vm.$watch('a', newVal => this.myMethod()))使 ...

  2. vue学习之用 Vue.js + Vue Router 创建单页应用的几个步骤

    通过vue学习一:新建或打开vue项目,创建好项目后,接下来的操作为: src目录重新规划——>新建几个页面——>配置这几个页面的路由——>给根实例注入路由配置 src目录重整 在项 ...

  3. 写给后端同学的vue

    安装环境 安装vue-cli 脚手架 1. 安装nodejs环境 下载地址: (nodejs)[https://nodejs.org/zh-cn/download/] 安装(略) 2. 安装vue-c ...

  4. Vue.js 和 MVVM 小细节

    MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式,其核心是提供对View 和 ViewModel 的双向数据绑定,这使得ViewModel 的状态改变可以自 ...

  5. 使用keepAlive对上下拉刷新列表数据 和 滚动位置细节处理 - vue

    [前言] 使用vue处理项目中遇到列表页面时,之前项目中总会有一些细节问题处理得不太好,这里总结一下,以便优化以后的代码.如下: 1. 使用mint-ui中的LoadMore组件上下拉刷新时,有时无法 ...

  6. vue安装element-ui和px2rem的细节

    1.按需引入element-ui vue脚手架搭建完成之后,可以到element-ui官网进行npm 安装: npm i element-ui -S 如果是完整引入可以按照官网一步一步做即可完成:这里 ...

  7. vue 自学笔记(七) 组件细节问题

    前情提要: 这里盘点一下,组件细节的问题 现在我们观察一些用框架开发的网页BiliBili.掘金,会发现很多部分都十分相似或者一模一样,我们甚至可以将其拆分归类.而事实上,页面的确是被一个个组件构成的 ...

  8. Vue.js 和 MVVM 的小细节

    Vue.js 和 MVVM 的小细节 转载 作者:流云诸葛 链接:www.cnblogs.com/lyzg/p/6067766.html MVVM 是Model-View-ViewModel 的缩写, ...

  9. Vue : props 使用细节(父组件传递数据给子组件)

    props使用细节 在Vue.js中我们可以使用 props 实现父组件传递数据给子组件,下面我们总结一下props的使用细节 1.基础类型检查 2.必填数据 3.默认值 4.自定义验证函数 其中每一 ...

随机推荐

  1. Vs2015 当前不会命中断点,没有与此关联的可执行代码

    在学习Civil 3D本地化包程序的过程中, 使用.Net Reflector调试本地化包的主程序CountryKits.dll, .Net Reflector创建了相应的pdb文件等, 在我反编译并 ...

  2. js打开新窗口,打开新窗口屏蔽工具栏和地址栏,窗口按规定大小显示

    opener=null; window.open ("http://baidu.com", "newwindow", "height=500, wid ...

  3. 深入理解JVM(6)——Java内存模型和线程

    Java虚拟机规范中定义了Java内存模型(Java Memory Model,JMM)用来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果(“即Ja ...

  4. MFC:位图和图标的设置

    一. 图标的设置 加载图标   API函数:AfxGetApp()->LoadIconW(); 2. 显示图标 API函数:SetClassLong(); 函数原型:DWORD WINAPI S ...

  5. windows环境下安装composer,然后使用composer安装Laravel

    Composer 不是一个包管理器,它仅仅是一个依赖管理工具,它允许你申明项目所依赖的代码库,并在你的项目中安装这些代码库.它涉及 “packages” 和 “libraries”,但它在每个项目的基 ...

  6. 关于vue的增删改查操作

    利用vue也可以实现数据的增删改查,只是未涉及到数据库,只是在浏览器页面中进行操作. 将datas数组中的数据循环输出: 再增加一行,用于保存新数据,编辑数据后保存: 此时,数据已经呈现出来,开始进行 ...

  7. 从线性模型(linear model)衍生出的机器学习分类器(classifier)

    1. 线性模型简介 0x1:线性模型的现实意义 在一个理想的连续世界中,任何非线性的东西都可以被线性的东西来拟合(参考Taylor Expansion公式),所以理论上线性模型可以模拟物理世界中的绝大 ...

  8. Tomcat系列(2)——Tomcat文件目录7个

    核心部分 bin (运行脚本) conf (配置文件) lib (核心库文件) logs (日志目录) temp (临时目录) webapps (自动装载的应用程序的目录) work (JVM临时文件 ...

  9. 计算机网络(HTTP)之客户识别:cookie机制

    什么是cookie? 承载用户相关信息的HTTP首部 cookie的工作原理 cookie的缺陷 一.什么是cookie? cookie是由服务器生成,发送给USER-Agent(一般是浏览器),(服 ...

  10. hive 时间函数

    使用时发现:1.datediff可以传入timestamp类型参数     官网文档: Date Functions The following built-in date functions are ...