vue常见问题收集
打工累吗?累呀。但是我不能哭,因为骑电动车的时候擦眼泪不安全。早安,打工人!!!
vue组件之间传值
1、父传子
这种传值比较简单,子组件只需用props将父组件传递过来的数据接收,即可使用
//父组件代码
<p>父组件<p>
<input type="text" v-model="parentData">
<Children :parentData="parentData"></Children>
----------------子组件代码------------------
props:{
parentData:{type:String,required:true}
}
2、子传父
子组件传值给父组件需要提交(this.$emit)一个自定义的方法,父组件监听这个方法来获得子组件传过来的值。
//-----------子组件代码----------
<p><input type="text" v-model="childrenData"></p>
<p><button @click="handelChildren">点击传值给父组件</button></p>
export default{
name:'Children',
data(){
return{
childrenData:''
}
},
methods:{
handelChildren(){
this.$emit('onSetData',this.childrenData)
}
}
}
//----------------父组件代码-----------------
<Children @onSetData="handelSetData"></Children>
export default{
name:'Parent',
data(){
return{
number:''
}
},
methods:{
handelSetData(val){
this.number = val
}
}
}
3、 $refs
父组件通过$refs
获取子组件的数据和方法:在调用子组件的时候写入一个ref="xxx"
,在父组件中通过this.$refs.xxx.属性
可以直接获取子组件的值,this.$refs.xxx.方法
通过方法传参,可以实现父组件给子组件传值
//----------------父组件代码-----------------
<template>
<div>
<children-comp ref="child"></children-comp>
<button @click="getChildProp()">获取子组件的属性值</button>
<button @click="getChildMethod()">获取子组件的方法</button>
</div>
</template>
<script>
import ChildrenComp from './ChildrenComp.vue'
export default{
components:{
ChildrenComp
},
data(){
return{}
},
methods:{
getChildProp(){
alert(this.$refs.child.msg);
},
getChildMethod(){
this.$refs.child.run();
}
}
}
</script>
//----------------子组件代码-----------------
<script>
export default{
data(){
return:{
msg:'我是子组件的值哦'
}
},
methods:{
run(){
alert("我是子组件的方法"+this.msg);
}
}
}
</script>
4、$parent
子组件通过$parent
获取父组件的数据和方法:直接在子组件中使用this.$parent.xxx
,不需要做任何多余操作。
//子组件代码示例
<script>
export default{
methods:{
getFatherProp(){
let fatherMsg = this.$parent.fatherMsg;
},
getFatherMethod(){
this.$parent.fatherRun();
}
}
}
</script>
5、 兄弟组件传值
//操作步骤
1、创建一个新的Vue实例,让各个兄弟公用同一个事件机制。(关键点:使用Bus事件总线,创建一个中转站来进行传值)
2、传递数据方-->通过事件触发$emit('方法名','传递的数据')
3、接收数据方-->在mounted()钩子函数中触发事件$on('方法名',callback(接收的数据)),此时callback函数中的this已经发生了变化,可以使用箭头函数
- 在main.js里首先声明
Vue.prototype.$bus = new Vue();
- 父组件里面有两个子组件,他们是兄弟关系
<template>
<div>
<child1></child1>
<child2></child2>
</div>
</template>
<script>
import child1 from './userChild/child1'
import child2 from './userChild/child2'
export default {
components:{
child1,
child2
},
data(){
return {
value:'',
}
},
}
</script>
- 子组件传值
//----------------子组件1----------------
<template>
<div class="child1">
子组件1
<div>
<el-input v-model="value"></el-input>
<el-button @click="submit">提交</el-button>
</div>
</div>
</template>
<script>
export default {
data(){
return{
value:''
}
},
methods:{
submit(){
this.$bus.$emit('onName',this.value)
}
}
}
</script>
//----------------子组件2----------------
<template>
<div class="child2">
子组件2
<div> {{msg}} 提交了申请</div>
</div>
</template>
<script>
export default {
data(){
return{
msg:''
}
},
mounted(){
this.$bus.$on('onName',(value)=>{
this.msg = value;
})
}
}
</script>
6、 依赖注入provide&inject
provide/inject需要一起使用,以允许一个祖先向其所有子孙后代注入一个依赖,单向的,只能父-->后代,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。
有人这么形容:provide就相当于加强版父组件prop,可以跨越中间组件;inject就相当于加强版子组件的props
//-----------父组件中------------
<template>
<div id="app">
{{count}}
<child-component @update:xxx="changeCount"></child-component>
</div>
</template>
<script>
export default {
data: {
count: 2000,
text: 'hello world!'
},
provide: function () {
return {
infos:this.text, //这里是data中定义的数据
fun:this.fun //这里是methods中定义的方法
}
},
}
</script>
//-----------后代组件中------------
<script>
export default {
inject:['infos','fun'], //使用的时候都是通过this,类似于普通的组件传值
data: {
count: 2000,
text: 'hello world!'
}
}
</script>
7、 Vuex数据共享来相互传值更改状态
vue动态绑定class
第一种:对象的形式
- 最简单的绑定(这里的active加不加单引号都可以,一下也一样能渲染)
//isActive是在data里面的布尔值,active是class样式类
//isActive为true时样式类active才生效
<div :class='{active:isActive}'>123</div>
- 判断是否绑定一个active
<div :class='{active:isActive == index}'>123</div>
- 绑定并判断多个
1、第一种(用逗号隔开)
<div :class='{active:isActive, sort:isSort}'>123</div>
2、第二种(放在data里面)
<div :class='classObject'>123</div>
export default{
data(){
return{
classObject:{active:true, sort:false}
}
}
};
3、第三种(使用computed属性)
<div :class='classObject'>123</div>
export default{
data(){
return{
isActive:true,
isSort:false
}
},
computed:{
classObject:function(){
return{
active:this.isActive,
sort:this.isSort
}
}
}
};
第二种:数组的形式
- 单纯的数组
<div :class='[isActive,isSort]'>123</div>
export default{
data(){
return{
isActive:true,
isSort:false
}
}
};
- 数组与三元运算符结合判断选择需要的class
<div :class="[ isActive ? 'active':'' ]">123</div>
//或者
<div :class="[ isActive==index ? 'active':'otherActive' ]">123</div>
- 数组结合对象动态判断
//前面的这个active在对象里可以不加单引号,后面这个sort要加单引号
<div :class="[{active:isActive}, 'sort']">123</div>
//或者
<div :class="[{active:isActive==index}, 'sort']">123</div>
vue动态添加style
vue在动态添加style的时候需要注意:
1、凡是有-的style属性名都要变成驼峰式,比如font-weight需要写成fontWeight
2、除了绑定值,其他属性名的值要用引号括起来,比如width:'75px',不要忘记引号
3、动态绑定时,属性值和属性名要用大括号括起来
1、对象形式
:style="{ width:activeWidth,fontSize:fontSize + 'px' }"
2、数组形式
:style="[{height:(warnData.length>0 ? '100px':'200px')},{color:'#fff'}]"
3、绑定data对象的形式
:style="activeStyle"
export default{
data(){
return{
activeStyle:{
color:'#fff',
fontSize:'16px'
}
}
}
}
vue动态组件
场景:做tab切换的时候就会涉及到组件动态加载
//通过使用保留的<component>元素,动态的绑定到它的is特性,可以实现动态组建
<component :is="currentTabComponent"></component>
//但是这样每次组件都会重新加载,会消耗大量性能,所以就用到了缓存组件
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>
//这样切换效果没有动画效果,这个也不用着急,可以利用内置的动画效果
<transition>
<keep-alive>
<component v-bind:is="currentTabComponent"></component>
</keep-alive>
</transition>
参考文献:①vue动态组件详解
vue组件的双向绑定
vue中父子组件通信都是单向的,直接在子组件中修改prop传的值vue会给出一个警告,所以需要一下方法解决
方法一:model选项(父组件的v-model指令所绑定的属性num通过model选项传给子组件的data属性,子组件通过自定义事件改变父组件的num属性)
//-----------------父组件----------------
<template>
<div>
<child v-model="num">{{num}}</child>
</div>
</template>
<script>
import child from './child'
export default{
components:{
child
},
data(){
return{
num:123
}
}
}
</script>
//-----------------子组件----------------
<template>
<div>
<input type="text" :value="data" @input="change" ></input>
</div>
</template>
<script>
import child from './child'
export default{
model:{
prop:'data', //指定父组件双向绑定子组件的哪个属性
event:'on-change' //指定触发双向绑定的事件名
},
props:{
data:Number
},
methods:{
change(event){
this.$emit('on-change',Number(event.target.value));
}
}
}
</script>
方法二:通过prop和自定义属性
//-----------------父组件----------------
<template>
<div>
<child :data="num" @on-change="num=$event">{{num}}</child>
</div>
</template>
<script>
import child from './child'
export default{
components:{
child
},
data(){
return{
num:123
}
}
}
</script>
//-----------------子组件----------------
<template>
<div>
<input type="text" :value="data" @input="change" ></input>
</div>
</template>
<script>
import child from './child'
export default{
props:{
data:Number
},
methods:{
change(event){
this.$emit('on-change',Number(event.target.value));
}
}
}
</script>
方法三:sync修饰符
//-----------------父组件----------------
<template>
<div>
<child :data.sync="num">{{num}}</child>
</div>
</template>
<script>
import child from './child'
export default{
components:{
child
},
data(){
return{
num:123
}
}
}
</script>
//-----------------子组件----------------
<template>
<div>
<input type="text" :value="data" @input="change" ></input>
</div>
</template>
<script>
import child from './child'
export default{
props:{
data:Number
},
methods:{
change(event){
this.$emit('update:data',Number(event.target.value));
}
}
}
</script>
Vue.observable
2.6.0 新增 用法:让一个对象可响应。Vue 内部会用它来处理 data 函数返回的对象; 返回的对象可以直接用于渲染函数和计算属性内,并且会在发生改变时触发相应的更新; 也可以作为最小化的跨组件状态存储器,用于简单的场景。 通讯原理实质上是利用Vue.observable实现一个简易的 vuex
// 文件路径 - /store/store.js
import Vue from 'vue'
export const store = Vue.observable({ count: 0 })
export const mutations = {
setCount (count) {
store.count = count
}
}
//使用
<template>
<div>
<label for="bookNum">数 量</label>
<button @click="setCount(count+1)">+</button>
<span>{{count}}</span>
<button @click="setCount(count-1)">-</button>
</div>
</template>
<script>
import { store, mutations } from '../store/store' // Vue2.6新增API Observable
export default {
name: 'Add',
computed: {
count () {
return store.count
}
},
methods: {
setCount: mutations.setCount
}
}
</script>