1. 自定义指令
1.1 基础语法
- 全局注册:在main.js文件中,进行注册
Vue.directive('指令名', {
inserted (el) {
// 处理逻辑代码
}
})
- 局部注册:在当前组件内进行注册
directives: {
loading: {
//inserted函数是指令所绑定的元素在被插入到页面时触发的
inserted(el,binding) {
// el为绑定的元素,binding.value为指令的值
binding.value ? el.classList.add('loading') : el.classList.remove('loading')
},
//update函数是指令的值在被修改之后触发的
update(el,binding) {
binding.value ? el.classList.add('loading') : el.classList.remove('loading')
}
}
}
1.2 封装loading指令
- 准备一个loading类,通过伪类元素添加蒙层
```css
.loading::before {
content: '';
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: #fff url('./loading.gif') no-repeat center;
}
```
- 注册loading指令,通过添加和删除类来控制loading效果
```javascript
directives: {
loading: {
inserted(el,binding) {
binding.value ? el.classList.add('loading') : el.classList.remove('loading')
},
update(el,binding) {
binding.value ? el.classList.add('loading') : el.classList.remove('loading')
}
}
}
```
2. 插槽
2.1 默认插槽(当组件内的某个结构需要定制时,使用默认插槽进行自定义)
- 先在组件内使用slot标签在需要定制的位置进行占位
- 然后在使用组件时,在组件标签间自定义需要的内容
- 后备内容:可以在slot标签中设置默认内容
2.2 具名插槽(拥有name属性的插槽,可以定制组件内的多个结构)
- 给slot标签添加name属性,从而区分多个slot标签
- 在使用时,用template标签包裹定制的内容,并通过添加v-slot:插槽名的方式分别定制对应的结构
- 可以简写为#插槽名
<template>
<div>
<MyDialog>
<template v-slot:header>
<p>友情提示</p>
</template>
<template v-slot:content>
<p>确定要删除么</p>
</template>
<template #footer>
<button>确定</button>
<button>取消</button>
</template>
</MyDialog>
<MyDialog>
<template v-slot:header>
<p>警告</p>
</template>
<template v-slot:content>
<p>不可以删除</p>
</template>
<template #footer>
<button>取消</button>
</template>
</MyDialog>
</div>
</template>
2.3 作用域插槽(插槽传值的一种语法)
- 在slot标签上,通过添加属性的方式给上层组件传值
- 在使用时,属性和值会被集合到一个对象中,组件可以通过#插槽名=变量名的方式获取slot传递的对象值
- 默认插槽的插槽名为default
// 1. 在slot标签上,通过添加属性的方式给上层组件传值
<tr v-for="(item,index) in data" :key="item.id">
<td>{{ index + 1 }}</td>
<td>{{ item.name }}</td>
<td>{{ item.age }}</td>
<td>
<slot :id="item.id" msg="测试文本"></slot>
</td>
</tr>
// 2. 组件通过#插槽名=变量名获取slot传递的对象值
<MyTable :data="list">
<template #default="obj">
<button @click="del(obj.id)">删除</button>
</template>
</MyTable>
2.4 标签组件的封装
- 双击标签,显示输入框,自动获取焦点(绑定双击事件,布尔值控制显示隐藏,自定义focus指令获取焦点)
- 失去焦点,输入框隐藏(绑定失去焦点事件)
- 标签信息回写(父给子组件传值,给输入框赋值)
- 修改内容,回车确认(子传父,修改标签内容)
3. 路由
3.1 路由的基本内容
-
单页应用程序:只有一个html文件,应用通过路由进行组件的切换。而多页应用程序则有多个html文件,是页面之间进行切换。
-
在Vue中,路由就是组件与路径的映射关系。通过vue内置的插件vue-router来实现。
- 下载vue-router,导入main.js文件中。通过vue.use注册使用,声明路由变量,将变量放入vue实例中。
- 定义组件与路径的映射关系
const router = new VueRouter({ routes: [ {path: '/findmusic', component: FindMusic}, {path: '/myfriend', component: MyFriend}, {path: '/mymusic', component: MyMusic} ] })
- 配置路径,设置路由出口(router-view)
<template> <div> <div class="footer_wrap"> <a href="#/findmusic">发现音乐</a> <a href="#/mymusic">我的音乐</a> <a href="#/myfriend">朋友</a> </div> <div class="top"> <router-view></router-view> </div> </div> </template>
-
组件分类
- 页面组件:需要使用路由进行跳转的组件,放在views文件夹下
- 复用组件:需要大量复用的组件,放在components文件夹下
3.2 路由进阶
3.2.1 声明式导航&导航链接router-link
-
VueRouter中内置全局组件router-link,可以代替a标签进行跳转,并且可以实现标签高亮。
-
router-link通过添加类名的方式来实现高亮,有两种方式:
- 模糊匹配:添加了router-link-active类,匹配路径如/my、/my/one、/my/two等路由标签
- 精确匹配:添加了router-link-exact-active类,只匹配如/my路径的路由标签
-
跳转传参:
- 查询参数传参(适合传递多个参数)
<!-- 配置路径 --> <div class="hot-link"> 热门搜索: <router-link to="/search?key=黑马程序员">黑马程序员</router-link> <router-link to="/search?key=前端培训">前端培训</router-link> <router-link to="/search?key=如何成为前端大牛">如何成为前端大牛</router-link> </div> <!-- 获取参数 --> <p>搜索关键字: {{ $route.query.key}} </p>
- 动态路由传参(比较简洁,适合传递单个参数)
<!-- 配置动态路由 --> const router = new VueRouter({ routes: [ { path: '/home/:words', component: Home }, <!-- 动态路由参数可选符?,表示参数可填可不填,避免没有参数时页面显示空白 --> { path: '/search/:words?', component: Search } ] }) <!-- 配置路径 --> <div class="hot-link"> 热门搜索: <router-link to="/search/黑马程序员">黑马程序员</router-link> <router-link to="/search/前端培训">前端培训</router-link> <router-link to="/search/如何成为前端大牛">如何成为前端大牛</router-link> </div> <!-- 获取参数 --> <p>搜索关键字: {{ $route.params.words}} </p>
-
路由重定向&404&路由模式设置
const router = new VueRouter({
// 路由模式选择分为hash和history。history模式下,路径没有#
mode: 'history',
routes: [
// 路由重定向
{ path: '/', redirect: '/home'},
{ path: '/home', component: Home },
{ path: '/search/:words?', component: Search },
// 404路由设置,必须放在最后
{ path: '*', component: NotFound}
]
})
3.2.2 编程式导航-路由跳转和传参(通过js控制页面跳转)
- path路径跳转传参
methods: {
handleSearch() {
// 简便写法
// 查询参数方式
this.$router.push(`/search?input=${ this.input }`)
// 动态路由方式
this.$router.push(`/search/${this.input}`)
// 完整写法
// 查询参数方式
this.$router.push({
path: '/search',
query: {
input: this.input
}
})
// 动态路由方式
this.$router.push({
path: `/search/${this.input}`,
})
}
}
- name命名路由跳转传参(需要给路由配置name)
this.$router.push({
name: 'search',
// 查询参数方式
query: {
input: this.input
},
// 动态路由方式
params: {
words: this.input
}
})
3.3 面经基础版案例
- 路由配置
const router = new VueRouter({
routes: [
{
path: '/',
component: Layout,
redirect: '/article',
// 二级路由
children: [
{
path: '/article',
component: Article
},
{
path: '/collect',
component: Collect
},
{
path: '/like',
component: Like
},
{
path: '/user',
component: User
},
]
},
{
path: '/detail/:id',
component: ArticleDetail
}
]
})
- article首页请求渲染
- artucleDetail详情页渲染
- 缓存组件(keep-alive)
- keep-alive:vue的内置组件,包裹动态组件(如router-view)时,可以缓存
- 优点:组件切换过程中,把切换的组件缓存在内存,提升性能
- 三个属性:include:组件名数组,只有匹配的组件才会缓存;exclude:组件名数组,被匹配的组件不会缓存;max: 最多可缓存多少组件实例
- keep-alive会使created,mounted,destroyed等钩子函数失效,但会多增加两个钩子函数activated和deactivated
- activated函数会在组件被使用到时触发——进入页面触发;deactivated函数会在离开页面时触发