本章主要包含vue的知识点,包括:组件3种传值方式;computed和watch;keep-alive的使用。个人博客文章地址:个人博客
1 vue组件传值
vue组件传值包含三种:
- 父传子
- 子传父
- 非父子传值
1.1 父传子
子组件props属性
// 父组件
<child :name="name"></child>
// 子组件
<h1>父组件传来的值:{{name}}</h1>
// 父组件
data(){
return{
name : 'yjl'
}
}
// 子组件
props:{
name : String
}
// 第二种写法,可设置默认值,当父组件没有传值时生效
name : {
type : String,
default : "default"
}
注意不要直接修改props里的值。字符串/数字类型会报错,但是仍然可以修改子组件里的值不会修改父组件的值。数组/对象类型会修改父组件里的值。两种都是不希望出现的,如果需要修改传入的值,可以另设变量复制传入的值。
1.2 子传父
子组件emit方法
// 父组件,@自定义方法名='methods'
<child :name="name" @setAge='setAge'></child>
// 子组件
<button @click="setAge">子传父</button>
// 父组件
methods:{
setAge(e){//e为传入的参数
console.log('子组件传来的值: ' + e)
}
}
// 子组件
methods:{
setAge(){
// 第一个参数对应父组件自定义方法名,第二个参数是需要传递的值
this.$emit('setAge',10)
}
}
通常情况下父组件里自定义方法名设置相同。
1.3 非父子传值
非父子传值有多种方法,我主要用到3种:
- 定义公共实例作为传递桥梁
- vuex
- global全局变量
1.3.1 定义公共实例
需要创建一个bus.js的文件。
特点:实时更新
// 组件1
<div>
组件一:
<input type="text" v-model="text1" @input="inputText">
</div>
// 组件2
<div>
组件二:{{text}}
</div>
// bus.js
import Vue from 'vue'
export default new Vue()
// 组件1
import Bus from '../bus.js'
……
data(){
return{
text1 : ''
}
},
methods:{
inputText(e){
Bus.$emit('text',this.text1)
}
}
// 组件2
import Bus from '../bus.js'
……
data(){
return{
text : ""
}
},
mounted() {
Bus.$on('text',text => {
this.text = text
})
}
1.3.2 vuex
需要安装vuex,并创建store.js文件。html内容同1.3.1
npm install vuex
特点:实时更新
// store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export const store = new Vuex.Store({
state:{
name : ""
}
})
// main.js
import {store} from './store.js'
new Vue({
store
})
// 组件1
data(){
return{
text1 : ''
}
},
methods:{
inputText(e){
this.$store.state.name = this.text1
}
}
// 组件2
computed:{
text(){
return this.$store.state.name
}
}
1.3.3 global全局变量
需要在App.vue中创建global变量
特点:简单清晰,还可以传方法。
// 组件1
<div>
组件一:
<input type="text" v-model="text1" @input="inputText">
</div>
// 组件2
<div>
组件二:{{text}}
<button @click="getText">组件2获取组件1值</button>
</div>
// APP.vue
global.text = ""
// 组件1
data(){
return{
text1 : global.text
}
},
methods:{
inputText(e){
global.text = e.target.value
}
}
// 组件2
data(){
return{
text : ""
}
},
methods:{
getText(){
this.text = global.text
}
}
总结:本质上来讲3种方法都是借助了中间桥梁进行传值,个人觉得1和2比较类似,建议直接使用vuex,vuex还有很丰富的内容,当项目所需的数据很大时通常都会使用vuex进行处理。global比较适合小项目,用法比较简单。
2 watch与computed
watch与computed是vue的重要属性,两者都可以用来监听数据变化,监听范围包括:
- data
- vuex
此外watch还可以用来监听路由变化。下面用一段代码来展示两者的异同:
<div>
<span>姓:</span>
<input type="text" v-model="lastname">
</div>
<div>
<span>名:</span>
<input type="text" v-model="firstname">
</div>
<div>
<span>姓名: {{fullname}}</span>
</div>
</div>
computed方式
data(){
return{
lastname : '',
firstname : '',
}
},
computed:{
fullname(){
return this.lastname + this.firstname
}
}
computed里的变量不能与data中的重复,在computed里的其他变量发生改变时会触发一次计算,即lastname或firstname发生变化都会触发fullname的改变。注意:computed中不能包含异步计算
watch方式:
data(){
return{
lastname : '',
firstname : '',
fullname : ''
}
},
watch:{
lastname : function(newData,oldData){
this.fullname = newData + this.firstname
console.log(newData,this.firstname)
},
firstname : function(newData,oldData){
this.fullname = this.lastname + this.firstname
}
}
可以获取到两个参数,一个是改变前一个是改变后。这里不能用箭头函数,否则this指向错误。
watch监听路由变化
watch:{
$route(to,from){
console.log('跳转路径:' + to.path)
console.log('原路径:' + from.path)
}
}
一些路由的方法和属性
- this.$route - 获取当前录音
- beforeRouteEnter - 路由进来前
- beforeRouteUpdate - 路由更新前
- beforeRouteLeave - 路由离开
3个路由钩子函数包含(to,from,next)3个属性,都需要在末尾调用next才能继续渲染。
beforeRouteUpdate 主要是针对同级路由切换参数时使用。
3 keep-alive用法
顾名思义就是让路由保持“活跃”状态,不会因为切换其他路由而重置数据。 需要用router-link或者
$router.push跳转
- 最简单的用法:让所有路由都保留缓存
<keep-alive>
<router-view></router-view>
</keep-alive>
- 部分路由保持缓存
<keep-alive>
<router-view v-if="$route.meta.alive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.alive"></router-view>
// route配置
{
path:"/route1",
component:route1,
meta:{
alive : true
}
},
{
path:"/route2",
component:route2,
meta:{
alive : true
}
},
{
path:"/route3",
component:route3,
meta:{
alive : false
}
},
当然也可以让组件保持alive状态,用法都是一样的,另外组件的话还提供2个筛选alive的方法:
include - 字符串或正则表达式。只有名称匹配的组件会被缓存。
exclude - 字符串或正则表达式。任何名称匹配的组件都不会被缓存
4 本周demo知识点
<!-- 选择器 -->
<select id="">
<option value=""></option>
</select>
/* dom隐藏与显示 */
visibility: hidden;
visibility: visible;
/* 同类选择器:nth-child,nth-last-child*/
:nth-child(2) /*第二个*/
:nth-last-child(2) /*倒数第二个*/
/* 反向选择 */
:not(.occupied) /* 不包含occipied的类 */
/* 3D效果 */
perspective: 1000px; /* 3D视距越大效果越明显*/
transform: rotateX(-45deg); /* X轴旋转*/
// 邮箱验证正则表达式
const reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/
// 本地永久存储
localStorage.getItem(key)
localStorage.setItem(key,string)
// 点击父级事件
dom.onclick = (e) => {
e.target // 可直接获取到被点击的子元素
}
// dom类切换
dom.classList.toggle(name) // 包含name则去掉,不包含则添加
// 通过展开运算符将类数组转化成数组
const selectedSeats = document.querySelectorAll('.row .seat.selected')//类数组
const seats = [...selectedSeats] //数组
// 下拉框改变事件
select.onchange = (e) => {
e.target.selectedIndex //选中的下标
+e.target.value //选中的value值,+号是字符串转数字的隐式转化
}
select.selectedIndex = number //手动切换下拉框选中值,不会触发onchange
video API
事件
play - 监听播放
pause - 监听暂停
timeupdate - 监听时间更新
方法
play() - 播放
pause() - 暂停
属性
currentTime - 当前播放的时间
duration - 视频总时长