this.$set()
官方文档说明 如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。这个时候就需要使用this.$set(this.data,”key”,value)
如果我们在创建实例以后,再在实例上绑定新属性,vue是无法进行双向绑定的
sex属于data的一个新属性,而vue的原理是,在创建实例的时候,遍历data里的值,监听’getter’和’setter’方法,一旦这些值更新了,就去触发对应的视图更新。
而sex并不是vue实例化的时候拥有的属性,所以我们新增这个属性,vue并没有对他的setter和getter方法进行监听,因此无法实现双向绑定
var data = {
name: "zeller",
age: '20',
}
var key = 'content';
var vm = new Vue({
el:'#app',
data: data
});
data.sex = 'male';
methods:{ //更新数据
setSex: function(){
this.$set('sex','male')
}
}
示例链接:https://www.jianshu.com/p/e58f099c9133
父组件向子组件进行传值
# 第一种方式
<template>
<Tab :uuid="uuid"/> //子组件引入
</template>
<script>
import Tab from "./detailTab"; //引入子组件
export default {
data() {
return {
uuid:" " //父组件传给子组件的值
}
}
},
methods: {
onTransfer(item) {//item是父组件的表格信息的uuid
this.uuid = item;
},
},
</script>
components: {
Tab, //子组件引入
}
<template>
//子组件内容
</template>
<script>
export default {
data() {
return {
}
},
props: ["uuid"], //父组件传来的值放到props里,而非data里定义
watch: {
uuid: function(newUuid, oldUuid) {
this.getVirtualDisk(newUuid);//方法获取uuid
}
},
},
</script>
# 第二种方式
<template>
<div>
<child :inputName="name"></child> //引入子组件
</div>
</template>
<script>
import child from './child'//引入子组件
export default {
components: {
child //引入子组件
},
data () {
return {
name: ''
}
}
}
</script>
<template>
<div>
<span>{{inputName}}</span> //子组件内容
</div>
</template>
<script>
export default {
props: { // 接受父组件的值
inputName: String,
required: true
}
}
</script>
ref 和refs
1、ref 加在普通的元素上,用this.refs. 获取到的是dom元素
2、ref 加在子组件上,用this.refs.获取到的是组件实例,可以使用组件的所有方法。
3、如何利用 v-for 和 ref 获取一组数组或者dom 节点
ref 需要在dom渲染完成后才会有,在使用的时候确保dom已经渲染完成。比如在生命周期 mounted(){} 钩子中调用,或者在 this.$nextTick(()=>{}) 中调用。
如果ref 是循环出来的,有多个重名,那么ref的值会是一个数组 ,此时要拿到单个的ref 只需要循环就可以了
# 1普通元素
<template>
<div id="app">
<div ref="testDom">11111</div>
<button @click="getTest">获取test节点</button>
</div>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
getTest() {
this.$refs.testDom="HELLO"
}
}
},
</script>
# 2使用子组件的所有方法
<template>
<button id="virtual" :class="{actived: toggleTab}" >a</button>
<button id="template" :class="{actived: !toggleTab}" >b</button>
<Tab ref="template"/> //子组件引入ab
</template>
<script>
import Tab from "./detailTab"; //引入子组件
export default {
data() {
return {
toggleTab: true, // 切换按钮
}
}
},
watch: {
toggleTab:function(val,oval){
if(this.id="template"){ //如果id是template
this.$refs.template.tabPage = 0 //子组件的tab按钮默认0
}
}
},
</script>
components: {
Tab, //子组件引入
}
3.v-for 和 ref
li里的ref的无法读取item里面的值,即item.name或被直接读取为字符串“item.name”,此时的$refs
this.$nextTick()
主要是用在随数据改变而改变的dom应用场景中,vue中数据和dom渲染由于是异步的,所以,要让dom结构随数据改变这样的操作都应该放进this.nextTick()的回调函数中。created()中使用的方法时,dom还没有渲染,如果此时在该钩子函数中进行dom赋值数据(或者其它dom操作)时无异于徒劳,所以,此时this.$nextTick()就会被大量使用,而与created()对应的是mounted()的钩子函数则是在dom完全渲染后才开始渲染数据,所以在mounted()中操作dom基本不会存在渲染问题。
<template>
<div class="app">
<div ref="msgDiv">{{msg}}</div>
<div v-if="msg1">Message got outside $nextTick: {{msg1}}</div>
<div v-if="msg2">Message got inside $nextTick: {{msg2}}</div>
<div v-if="msg3">Message got outside $nextTick: {{msg3}}</div>
<button @click="changeMsg">
Change the Message
</button>
</div>
</template>
<script>
export default {
data() {
return {
msg: 'Hello Vue.',
msg1: '',
msg2: '',
msg3: ''
}
},
methods: {
changeMsg() {
this.msg = "Hello world."
this.msg1 = this.$refs.msgDiv.innerHTML
this.$nextTick(() => {
this.msg2 = this.$refs.msgDiv.innerHTML
})
this.msg3 = this.$refs.msgDiv.innerHTML
}
}
}
</script>
点击前
点击后
原文链接:https://blog.csdn.net/gaoxin666/article/details/96143571
子组件调用父组件的方法
第一种方法是直接在子组件中通过this.$parent.event来调用父组件的方法
父组件
<template>
<div>
<child></child>
</div>
</template>
<script>
import child from '~/components/dam/child';
export default {
components: {
child
},
methods: {
fatherMethod() {
console.log('测试');
}
}
};
</script>
子组件
<template>
<div>
<button @click="childMethod()">点击</button>
</div>
</template>
<script>
export default {
methods: {
childMethod() {
this.$parent.fatherMethod();
}
}
};
</script>
第二种方法是在子组件里用$emit向父组件触发一个事件,父组件监听这个事件就行了。
父组件
<template>
<div>
<child @fatherMethod="fatherMethod"></child>
</div>
</template>
<script>
import child from '~/components/dam/child';
export default {
components: {
child
},
methods: {
fatherMethod() {
console.log('测试');
}
}
};
</script>
子组件
<template>
<div>
<button @click="childMethod()">点击</button>
</div>
</template>
<script>
export default {
methods: {
childMethod() {
this.$emit('fatherMethod');
}
}
};
</script>
第三种是父组件把方法传入子组件中,在子组件里直接调用这个方法
父组件
<template>
<div>
<child :fatherMethod="fatherMethod"></child>
</div>
</template>
<script>
import child from '~/components/dam/child';
export default {
components: {
child
},
methods: {
fatherMethod() {
console.log('测试');
}
}
};
</script>
子组件
<template>
<div>
<button @click="childMethod()">点击</button>
</div>
</template>
<script>
export default {
props: {
fatherMethod: {
type: Function,
default: null
}
},
methods: {
childMethod() {
if (this.fatherMethod) {
this.fatherMethod();
}
}
}
};
</script>
第四种是通过$root 属性访问父组件实例的属性和方法
root 和parent 都能够实现访问父组件的属性和方法,两者的区别在于,如果存在多级子组件,通过parent 访问得到的是它最近一级的父组件,通过root 访问得到的是根父组件
原文链接:https://blog.csdn.net/zgrkaka/article/details/100528714
父组件调用子组件的方法
第一种 ref为子组件指定一个索引名称,通过索引来操作子组件
父组件
<template>
<child ref="template" />
<div @click="toggle"></div>
</template>
<script>
import child from "./detailTab";
export default {
data() {
return { }
},
methods:{
toggle(){
this.$refs.template.getTemplateDisk(this.uuidTem) //调用子组件的方法
}
},
components: {child}
}
</script>
子组件
<template>
<div ></div>
</template>
<script>
export default {
data() {
return { }
},
methods:{
getTemplateDisk() {...} //子组件的方法
}
}
</script>
第二种 通过this.children 访问它所有的子组件,this.children返回的是一个组件集合,如果你能清楚的知道子组件的顺序,你也可以使用下标来操作
父组件
<template>
<div class="parent" @click='fatherMethod'>
<child></child>// ref 作用在组件上 指向的是组件的实例 实例上的方法都可以调用
</div>
</template>
<script>
import child from '../base/child'
export default {
methods:{
fatherMethod() {
this.$children[0].childClick() // $children获取的是子组件的数组 通过索引找到对应的子组件的实例
console.log(this.$children[0].msg)
}
},
components:{
child
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.parent{
width: 100px;
height: 100px;
background-color: blue;
}
</style>
子组件
<template>
<div class="child" @click='childClick'>
</div>
</template>
<script>
export default {
data() {
return {
msg: '我是子组件传递过来的数据'
}
},
methods:{
childClick(){
console.log(this.$children.msg)
}
}
}
</script>
原文链接:https://blog.csdn.net/alokka/article/details/87104189
兄弟组件之间调用方法
兄弟组件1
<template>
<div @click="toggle"></div>
</template>
<script>
export default {
data() {
return { }
},
methods:{
toggle(){
this.$eventBus.$on('getVirtualDriveList',()=>{
this.getVirtualDriveList()
})
},
getVirtualDriveList(){.....}
},
}
</script>
兄弟组件2
<template>
<div ></div>
</template>
<script>
export default {
data() {
return { }
},
methods:{
getFun() { this.$eventBus.$emit('getVirtualDriveList') //调用兄弟组件的方法
}
}
</script>