1、v-if和v-show的区别:
v-if:
1)真正的条件渲染,DOM元素切换的过程中,被销毁和重建。
2)懒惰,如果初始条件为假则神魔都不做,直到初始条件为真时渲染元素
3)有更高的切换开销
4)在切换频率少时使用
v-show:
1)不管初始条件是什么,元素都会被渲染,只是简单的基于display属性的block和none进行变换
2)有更高的初始条件开销
2、v-bind和v-model的区别
v-bind:单向数据绑定
v-model: 双向数据绑定
{{mes}}
(mes在data中声明,适用于表单元素)双向数据绑定的原理:defineProperty渲染实现的原理
3、vue中父子组件传值问题
1)父组件传递个子组件,通过props
2)子组件传递给父组件,通过this. e m i t ( ) 3 ) 同 级 组 件 之 间 传 值 , 通 过 同 一 个 v u e 对 象 , 传 值 方 : 方 法 V u e . emit() 3)同级组件之间传值,通过同一个vue对象,传值方:方法Vue. emit()3)同级组件之间传值,通过同一个vue对象,传值方:方法Vue.emit(‘名称’,数据) 接收方:Vue.$on(‘名称’,res => { 回调处理 })
4)使用vuex的状态管理
4、vue中的插槽
1)后备内容和具名插槽
创建一个mybutton的vue组件,并将其注册为全局组件,代码如下
<template>
<div :class="type">
<!-- 后备内容 -->
<!-- 不带name的插槽会带有一个隐含的名字"default" -->
<button >
<slot></slot>
</button>
<!-- 具名插槽 -->
<header>
<slot name="header"></slot>
</header>
<main>
<slot name="main"></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>
<script>
export default {
name: 'mybutton',
props: { type: String
},
}
</script>
<style lang="scss" scoped>
.success1 {
background: green
}
.success2 {
background: yellow
}
</style>
在main.js中将其注册为全局组件
import mybutton from './components/mybutton'
// 全局组件注册
Vue.component('mybutton',mybutton)
在另一个组件中引用
<mybutton type="success1">
陈工1号
<!-- v-slot只能添加在template上 -->
<template v-slot:header>
<h5>我是头部</h5>
</template>
<template v-slot:main> //具名插槽缩写,#main
<h5>我是内容</h5>
</template>//前提是必须之前使用name属性
<template v-slot:footer>
<h5>我是底部</h5>
</template>
</mybutton>
2)作用域插槽(使父组件中的插槽内容能够访问到子组件中数据)
创建组件mybutton.vue,main.js同上
<template>
<div :class="type">
<!-- 绑定在slot元素上的attribute被称为插槽prop -->
<!-- 在父级作用域中,我们可以使用带值的v-slot来定义我们提供的插槽prop的名字 -->
<slot :people='people'> {{ people.lastName }} </slot>
</div>
</template>
<script>
export default {
name: 'mybutton',
props: { type: String },
data() {
return {
people: { lastName: '李', firstName: '明敏' }
}
}
}
</script>
父组件中使用作用域插槽
父组件中使用作用域插槽
<mybutton type="success2">
<!-- 作用,使父组件中插槽内容能够访问到子组件中存在的数据 -->
<template v-slot="slotProps">(缩写语法) 或 <template v-slot:default="slotProps">
{{ slotProps.people.firstName }}
</template>
</mybutton>
注意问题:
1)具名插槽是v-slot:’name’而作用域插槽是v-slot=’name’,且插槽违背命名即未使用name实行定义插槽名称
2)不带参数的 v-slot 被假定对应默认插槽
3)默认插槽的缩写语法不能和具名插槽混用,会导致作用域不明确
4)只要出现多个插槽,使用未每个插槽使用<template></template>
语法
5、vue中的过滤器filter
1)局部过滤器`
<template>
<!--
1)vue允许自定义过滤器
2)过滤器可以用在两个地方:双花括号插值和v-bind表达式
3)过滤器应该被添加在js表达式的尾部
4)由“管道”符号指示 例:{{ message | capitalize }} <div :id=”message | capitalize”></div> -->
<div>
<input type="text" v-model="message">
<p>{{message}}</p>
<!-- capitalize将message作为参数 -->
<!-- capitalize1('hello','world')传入三个参数,第一个是capitalize -->
<p>{{message | capitalize | capitalize1('hello','world')}}</p>
</div>
</template>
<script>
export default {
name:'myFilter',
data() {
return {
message: ''
}
},
filters: { // 在组件内部定义本地的过滤器 // 当局部过滤器与全局过滤器重名时,会采用局部过滤器
capitalize(value) {
if(!value) return '';
value = value.toString();
return value.charAt(0).toUpperCase() + value.slice(1)
},
capitalize1(value,str1,str2) {
if(!value) return '';
value = value.toString();
return value.charAt(1).toUpperCase()+str1+str2
}
}
}
</script>
//过滤器调用 在父组件中调用
引入=====>挂载=====>调用<myFilter />
2)全局过滤器
main,js
// 定义全局过滤器,在创建vue实例前
Vue.filter('capitalize',(value) => {
if(!value) return ''
value = value.toString()
return value.charAt(0).toUpperCase()+value.slice(1)
})
6、vue的计算属性与侦听器
创建一个监听的组件
<template>
<div>
<button @click="stus[0].name='小李'">改变</button>
<p>{{stus[0].name}}</p>
<!-- watch监听属性练习 -->
<input type="text" v-model="mess">
<p>{{mess}}</p>
<button @click="todo.count++">{{todo.count}}</button>
<!-- computed计算属性练习 --> <br />
<input type="text" v-model="computedMes">
<p @click="reversedMes = '小花'">{{reversedMes}}</p>
<!-- 计算属性不在更新,因为Date.now()不是响应式依赖 -->
<p>{{now}}</p>
</div>
</template>
<script>
export default {
name: 'myWatch',
data() {
return {
mess: 'hello,world',
computedMes: 'hello',
stus:[{name: "小明"}],
todo: {id:'01',count:1} }
},
// 计算属性,使用计算属性时,变量事先不能再data中进行声明
// 声明了一个计算属性reversedMes,我们提供的函数将作用于计算属性reversedMes的getter函数
// 计算属性基于响应式依赖进行缓存。只用在相关响应式依赖发生改变时它们才会重新求值。如果使用跟计算属性出现相同结果的方法,则每次出发重新渲染时都会再次执行
// 只要computedMes还没有发生改变,多次访问reversedMes计算属性回立即返回之前的结果,而不必再次执行函数 // 计算属性默认只有getter,但是也可以提供一个setter
computed: {
reversedMes: {
get() {
return this.computedMes.split('').reverse().join('')
},
set(val) {
this.computedMes = val
console.log(val)
}
},
now() {
return Date.now()
}
},
// watch监听单个属性,基本数据类型简单监视,复杂数据类型深度监视 // 使用watch进行监听时,变量需要在data中进行声明
watch: {
// 简单数据类型进行监听
mess(newV,oldV) {
if(newV == '你好')
alert('hello')
console.log(newV,oldV)
},
// 针对复杂数据类型(object、array)要进行深度监视
stus: {
deep: true,
handler(newV) {
console.log(newV[0].name);
}
},
todo:{
deep: true,
handler(val) {
if(val.count > 10) {
alert('我大于10了')
}
}
},
}
}
</script>
7、vue的生命周期
// 生命周期练习
beforeCreate() {
console.log("创建前:beforeCreate")
},
// $$$$$ 常用:发送请求,此时数据data已初始化完成,方法也可以调用,但是DOM为渲染
// 只要是将请求设置为异步,在这个生命周期执行不会影响实例加载,因此渲染速度会更快
created() {
console.log('被创建:created')
},
beforeMount() {
console.log('挂载之前:beforeMount')
},
// $$$$$ 常用:执行初始化需要操作DOM的方法,引为此时数据和DOM都完成挂载
mounted() {
console.log('被挂载:mounted')
},
beforeUpdate() {
console.log('更新之前:beforeUpdate')
},
update() {
console.log('被更新:update')
},
beforeDestory() {
console.log('销毁之前:beforeDestory')
},
destoryed() {
console.log('被销毁:destoryed')
}
8、在组件上使用v-model
//定义一个myComponent组件
<template>
<!-- 组件
1)组件命名:my-component 或 MyComponent
2)在组件上使用v-model
-->
<div>
<button @click="clickF">边界值练习</button>
<!-- name="keywords" -->
<input type="text"
ref="input"
:value="value"
@focus="myfocus"
@input="$emit('input',$event.target.value)">
<ul>
<li ref="myLi" v-for="(item,index) in person" :key="index">{{item}}</li>
</ul>
</div>
</template>
<script>
export default {
name: 'my-component',
props: {
value: String
},
data() {
return {
person:['三姑','四姨','五姨','六姨','八姑']
}
},
created() {
this.$nextTick(() => {
console.log(this.$refs.myLi)
})
},
mounted() {
// console.log(this.$refs.myinput)
// this.$refs.myinput.focus()
},
methods: {
clickF() {
console.log(this.$refs.input)
console.log(this.$parent.keywords )
},
myfocus() {
this.$emit('myfocus')
}
}
}
</script>
在父组件中调用
<!-- 使用v-model相当于完成了两件事1)给组件绑定以一个value属性 2)为当前组件绑定了一个input事件 -->
<myComponent
ref="myinput"
v-model="keywords"/>
<p>{{keywords}}</p>
<button @click="submit">提交</button>
methods:{
submit() {
console.log('keywords:',this.keywords)
console.log(this.$refs.myinput.value)
},
}
9、动态组件
//通过<component/>的is属性实现动态组件,currentView可以是组件的名称也可以是一个组件的选项对象
<template>
<div class="about">
<div class="dong-tai">
<!-- 点击按钮实现页面切换 -->
<button @click="changeF">切换</button>
<component :is="currentView"/>
</div>
</div>
</template>
<script>
//自己定义几个组件即可
import demo from '../components/demo'
import demo1 from '../components/demo1'
import live from '../components/live'
export default {
data() {
return {
index: 0,
arr: ['demo','demo1','live']
}
},
methods: {
changeF() {
this.index = (++this.index)%3
}
},
// 通过计算属性改变currentView
computed: {
currentView() {
return this.arr[this.index];
}
},
components:{
demo,
demo1,
live
}
}
</script>
<style lang="scss" scoped>
.dong-tai {
width: 200px;
height: 200px;
color: #333;
background: yellow;
}
</style>