推荐:Vue汇总
Vue - attribute is & ref
attribute is
用于动态组件且基于 DOM 内模板的限制来工作。
动态组件
有的时候,在不同组件之间进行动态切换是非常有用的。
可以通过 Vue的 <component>
元素加一个特殊的 is attribute
来实现:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>count</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="div">
<component v-bind:is="currentComponent">kaven</component>
<button @click="click">切换</button>
</div>
</body>
</html>
<script>
Vue.component("slot-welcome" , {
template: `
<div>
<p>welcome </p>
<slot></slot>
</div>
`
});
Vue.component("slot-hello" , {
template: `
<div>
<p>hello </p>
<slot></slot>
</div>
`
});
var vue = new Vue({
el: '#div',
data: {
currentComponent: 'slot-hello'
},
methods: {
click(){
if(this.currentComponent === 'slot-hello'){
this.currentComponent = 'slot-welcome'
}
else{
this.currentComponent = 'slot-hello'
}
}
}
})
</script>
效果:
点击按钮。
解析 DOM 模板时的注意事项
有些 HTML 元素,诸如 <ul>
、<ol>
、<table>
和 <select>
,对于哪些元素可以出现在其内部是有严格限制的。而有些元素,诸如 <li>
、<tr>
和 <option>
,只能出现在其它某些特定的元素内部。
这会导致我们使用这些有约束条件的元素时遇到一些问题。例如:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>if & ref</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="div">
<table>
<row></row>
<row></row>
<row></row>
</table>
</div>
</body>
</html>
<script>
Vue.component('row' , {
template: '<tr>Hello Kaven</tr>'
})
var vue = new Vue({
el: '#div'
})
</script>
效果:
<tr>
出现在<table>
的外面,很显然有问题。
这个自定义组件 <row>
会被作为无效的内容提升到外部,并导致最终渲染结果出错。幸好这个特殊的 is attribute
给了我们一个变通的办法:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>if & ref</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="div">
<table>
<tr is="row"></tr>
<tr is="row"></tr>
<tr is="row"></tr>
</table>
</div>
</body>
</html>
<script>
Vue.component('row' , {
template: '<tr>Hello Kaven</tr>'
})
var vue = new Vue({
el: '#div'
})
</script>
效果:
还自动创建了<tbody>
,这样就没问题了。
attribute ref
ref
被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs
对象上。如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例。
DOM 元素:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>if & ref</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="div" ref="div" @click="click">
<p>Hello Kaven</p>
</div>
</body>
</html>
<script>
var vue = new Vue({
el: '#div',
methods: {
click(){
console.log(this.$refs.div.innerHTML);
}
}
})
</script>
效果:
对this.$refs.div
的操作,其实就是对DOM的操作。
子组件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>if & ref</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="div" @click="click">
<child ref="child"></child>
</div>
</body>
</html>
<script>
Vue.component('child' , {
data: function(){
return {
message: 'Hello Kaven'
}
},
template: '<p>{{message}}</p>'
});
var vue = new Vue({
el: '#div',
methods: {
click(){
console.log(this.$refs.child.message);
}
}
})
</script>
效果:
对this.$refs.child
的操作,其实就是对子组件的操作。
当 v-for
用于元素或组件的时候,引用信息将是包含 DOM 节点或组件实例的数组。
关于 ref
注册时间的重要说明:因为 ref
本身是作为渲染结果被创建的,在初始渲染的时候你不能访问它们 - 它们还不存在!$refs
也不是响应式的,因此你不应该试图用它在模板中做数据绑定。
$refs
只会在组件渲染完成之后生效,并且它们不是响应式的。这仅作为一个用于直接操作子组件的“逃生舱”——你应该避免在模板或计算属性中访问 $refs
。
写博客是博主记录自己的学习过程,如果有错误,请指正,谢谢!
参考: