vue组件知识整理
此文章,是我在看vue教程时整理的组件部分知识,其中包括网上找的一些案例,有转载意思,只是我进行了编译,如有维权,请联系。
1.组件分为全局注册和局部注册
全局组件注册:必须在new之前注册。
局部组件注册:可以在作用域内使用componentsd
data 必须是函数
报错:
<body><div id="app">
<my-component></my-component>
</div>
<script>
Vue.component('my-component', {
template: '<span>{{ message }}</span>',
data:function() {
message: 'hello'
}
})
var vm = new Vue({
el:'#app'
})
</script>
</body>
[Vue warn]: Property or method "message" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.
found in
---> <MyComponent>
<Root>
VU.M.JS:435(VUE警告):属性或方法“消息”不是在实例上定义的,而是在渲染期间引用的。请确保在数据选项中声明无功数据属性。
修改成
<div id="app"><my-component></my-component>
</div>
<script>
Vue.component('my-component', {
template: '<span>{{ message }}</span>',
data:function() {
return{
message: 'hello'
}
}
})
var vm = new Vue({
el:'#app'
})
</script>
或者:
<div id="app"><my-component></my-component>
</div>
<script>
var x = { message: 'hello' }
Vue.component('my-component', {
template: '<span>{{ message }}</span>',
data:function() {
return x
}
})
var vm = new Vue({
el:'#app'
})
</script>
什么是prop(支柱)
实际就是,你自定义的标签属性,想传递给替换标签时,使用。
<body><div id="app">
<blog-post title="my name is dinghongli"></blog-post>
<blog-post title="my name is dingxiang"></blog-post>
<blog-post title="my name is dingleiying"></blog-post>
</div>
<script>
Vue.component('blog-post',{
template:'<h3>{{ title }}</h3>',
props:['title']
})
new Vue({
el:'#app'
})
</script>
</body>
<body><div id="app">
<blog-post
v-for="post in posts"
v-bind:key = 'post.id'
v-bind:title = "post.title"
></blog-post>
</div>
<script>
Vue.component('blog-post',{
template:'<h3>{{ title }}</h3>',
props:['title']
})
new Vue({
el:'#app',
data:{
posts:[
{ id:1, title:'my name is dinghongli'},
{ id:2, title:'my name is dingxiang'},
{ id:3, title:'my name is dingleiying'}
]
}
})
</script>
</body>
在组件上使用 v-model
<body><div id="blog-posts-events-demo">
<custom-input
v-bind:value="searchText"
v-on:input="searchText = $event"
></custom-input>
</div>
<script>
Vue.component('custom-input', {
props: ['value'],
template: `
<input
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"
>
`
})
new Vue({
el: '#blog-posts-events-demo',
data:{
searchText:'dfksjfksfj'
}
})
</script>
</body>
通过插槽分发内容
<body><div id="app">
<alert-box> fdkjfsjfskfjskfjkfjkf </alert-box>
</div>
<script>
Vue.component('alert-box',{
template:`<div class="demo-alert-box">
<span>Error!</span>
<slot></slot>
</div>`
})
new Vue({
el:'#app'
})
</script>
</body>
动态组件
让多个组件使用同一个挂载点,并动态切换,这就是动态组件。
通过使用保留的 <component>
元素,动态地绑定到它的 is
特性,可以实现动态组件
<body><div id="example">
<button @click="change">切换页面</button>
<component v-bind:is="currentView"></component>
</div>
<script>
var home = { template:'<div>我是主页</div>'};
var post = { template:'<div>我是提交页</div>'};
var archive = { template:'<div>我是存档页</div>'};
new Vue({
el:'#example',
components:{
home,
post,
archive
},
data:{
index:0,
arr:['home','post','archive']
},
computed:{
currentView:function(){
return this.arr[this.index];
}
},
methods:{
change:function(){
this.index = (++this.index)%3;
}
}
})
</script>
</body>
直接绑定到组件对象上
<body><div id="example">
<button @click="change">切换页面</button>
<component :is="currentView"></component>
</div>
<script>
new Vue({
el: '#example',
data:{
index:0,
arr:[
{template:`<div>我是主页</div>`},
{template:`<div>我是提交页</div>`},
{template:`<div>我是存档页</div>`}
],
},
computed:{
currentView(){
return this.arr[this.index];
}
},
methods:{
change(){
this.index = (++this.index)%3;
}
}
})
</script>
解析DOM模板时的注意事项
固定的标签结构,需用is特性来标识
<body>
<div id="app">
<table>
<tr is="my-row"></tr>
</table>
</div>
<script>
Vue.component('myRow', {
template: '<tr>行元素</tr>'
});
new Vue({
el: '#app'
});
</script>
</body>
组件注册
1.1组件名大小写
驼峰命名,要在标签里替换成短横杠命名
<body>
<div id="app">
<my-component-name></my-component-name>
</div>
<script>
Vue.component('myComponentName',{
template:'<div>哈哈哈哈哈哈哈</div>'
})
new Vue({
el: '#app'
});
</script>
</body>
全局组件注册:必须在new之前注册。
局部组件注册:可以在作用域内使用components 对于 components 对象中的每个属性来说,其属性名就是自定义元素的名
<body><div id="app">
<component-a></component-a>
<component-b></component-b>
<component-c></component-c>
</div>
<script>
var componentA = { template:'<div>你好</div>'};
var componentB = { template:'<div>哈哈</div>'};
var componentC = { template:'<div>嘿嘿</div>'};
new Vue({
el: '#app',
components:{
'component-a':componentA,
'component-b':componentB,
'component-c':componentC
}
});
</script>
</body>
注意局部注册的组件在其子组件中不可用。例如,如果你希望 ComponentA
在 ComponentB
中可用,则你需要这样写:
var ComponentA = { /* ... */ }var ComponentB = {
components: {
'component-a': ComponentA
},
// ...
}
传入一个对象的所有属性
<body><div id="app">
<blog-post v-bind ="info"></blog-post>
</div>
<script>
Vue.component('blog-post',{
props:['vBind'],
template:'<div>{{ vBind }}</div>'
})
new Vue({
el: '#app',
data:{
post: {
id: 1,
likes: 'My Journey with Vue',
currentUserFavorited:false,
favorited:'',
commentIds:'dinghongli'
},
info:{
id: 1,
title: 'My Journey with Vue'
}
}
});
</script>
</body>
vue.js将一个对象的所有属性作为prop进行传递
1.方法一:使用不带参数的v-bind写 :v-bind中没有参数,而组件中的props需要声明对象的每个属性
<body><div id="app">
<child v-bind="todo"></child>
</div>
<script>
Vue.component('child', {
props: ['text','isComplete'],
template: '<span >{{ text }} {{isComplete}}</span>'
})
new Vue({
el: '#app',
data: {
todo: {
text: 'Learn Vue',
isComplete: false
}
}
})
</script>
</body>
2.方法二:使用带参数的v-bind写法
v-bind后跟随参数todo,组件中的props需要声明该参数,组件变可以通过todo来访问对象的属性
<body><div id="app">
<child v-bind:todo = "todo" ></child>
</div>
<script>
Vue.component('child', {
props: ['todo'],
template: '<span >{{ todo.text }}{{ todo.isComplete }}</span>'
})
new Vue({
el: '#app',
data: {
todo: {
text: 'Learn Vue',
isComplete: false
}
}
)
</script>
</body>
prop验证
<body><div id="app">
<my-child
:num = "100"
:msg = "'sdf'"
:object = "{a:'a'}"
:cust = "100"
></my-child>
</div>
<script>
Vue.component('my-child',{
props:{
num: Number,
propB: [String,Number],
msg:{
type:String,
required:true
},
num1:{
type:Number,
default: 1000
},
object:{
type:Object,
default:function(){
return { message:'hello' }
}
},
cust:{
validator:function (value){
return value > 10
}
}
},
template:`<div>
<p>{{ num }}</p>
<p>{{ msg }}</p>
<p>{{ num1 }}</p>
<p>{{ object }}</p>
<p>{{ cust }}</p>
`
})
new Vue({
el:'#app'
})
</script>
</body>
替换合并己有的特性
class 和 style 会合并,class
和 style
特性会稍微智能一些,即两边的值会被合并起来,
<body><div id="app">
<bootstrap-date-input
data-date-picker="activated"
class="date-picker-theme-dark"
></bootstrap-date-input>
</div>
<script>
Vue.component('bootstrap-date-input',{
template:'<input type="date" class="form-control">',
props:['']
})
new Vue({
el:'#app'
})
</script>
</body>
结果:
禁用特性继承 (无案例)
自定义事件
自定义事件的主要作用是,父组件可以在使用子组件的地方直接用 v-on 来监听子组件触发的事件。 也就是相互通知
这里推荐 :https://blog.csdn.net/hayre/article/details/60572435 讲的很明白。
<body><div id="counter-event-example">
<p>{{ total }}</p>
<button-counter v-on:increment="incrementTotal"></button-counter>
<button-counter v-on:increment="incrementTotal"></button-counter>
</div>
<script>
Vue.component('button-counter', {
template: '<button v-on:click="increment">{{ counter }}</button>',
data: function () {
return {
counter: 0
}
},
methods: {
increment: function () {
this.counter += 1
this.$emit('increment')
}
}
})
new Vue({
el: '#counter-event-example',
data: {
total: 0
},
methods: {
incrementTotal: function () {
this.total += 1
}
}
})
</script>
</body>
自定义组件的v-model
转载自:https://www.cnblogs.com/bldf/p/6645225.html
<input v-model="something">
v-model指令其实是下面的语法糖包装而成:
<input:value="something"
@:input="something = $event.target.value">
在一个组件上使用 v-model 时,会简化为:
<custom-input:value="something"
@input="value => { something = value }">
</custom-input>
因此,对于一个带有 v-model
的组件,它应该如下:
- 接收一个
value
prop - 触发
input
事件,并传入新值
利用 $emit 触发 input 事件:
this.$emit('input', value);
组件1:
Vue.component('my-component', {template: `<div>
<input type="text" :value="currentValue" @input="handleInput"/>
</div>`,
data: function () {
return {
currentValue: this.value
}
},
props: ['value'], //接收一个 value prop
methods: {
handleInput(event) {
var value = event.target.value;
this.$emit('input', value); //触发 input 事件,并传入新值
}
}
});
currentValue: this.value
上面是将prop属性绑定到data里,以便修改 prop 数据(Vue不允许直接修改prop属性的值)#查看原理#
组件2:
Vue.component("my-counter", {template: `<div>
<h1>{{value}}</h1>
<button @click="plus">+</button>
<button @click="minu">-</button>
</div>`,
props: {
value: Number //接收一个 value prop
},
data: function() {
return {
val: this.value
}
},
methods: {
plus() {
this.val = this.val + 1
this.$emit('input', this.val) //触发 input 事件,并传入新值
},
minu() {
if(this.val>0){
this.val = this.val-1
this.$emit('input', this.val) //触发 input 事件,并传入新值
}
}
}
});
案例:
<body><div id="app">
<!-- <price-input v-model="price"></price-input> -->
<!-- 手动实现了v-model双向绑定 -->
<!-- 3、父组件的input事件被触发,将传来的值赋给父组件的变量price -->
<!-- 4、父组件value的值绑定到price -->
<price-input :value="price" @input="onInput"></price-input>
<p>{{price}}</p>
</div>
<script>
Vue.component('price-input', {
// 5、将父组件的value值通过props传递给子组件
// 1、当有数据输入时触发了该组件的input事件
template: '<input :value="value" @input="updateVal($event.target.value)" type="text">',
props: ["value"],
methods: {
updateVal: function(val) {
// 2、手动触发父组件的input事件并将值传给父组件
this.$emit('input', val);
}
}
});
var app = new Vue({
el: '#app',
data: {
rice: ''
},
methods: {
onInput: function(val) {
this.price = val;
}
}
}); </script>
</body>
将原生事件绑定到组件上,使用native修饰符
我们引入一个原生标签
(div、li、p......)的概念,那么原生事件(存在于标准当中的如'click', 'mouseover')应该绑定到原生标签
上。自定义组件上应该绑定自定义事件。
如果我们想给自定义组件标签(注意是标签,不是内部元素)绑定原生事件(使原生事件生效于组件template的root element上)怎么办,加.native
修饰符。
<body><div id="app">
<my-ding @click.native = "doThis"></my-ding>
<div @click = 'doThis'>你好吗???</div>
</div>
<script>
Vue.component('my-ding',{
template:'<div>开心每一天</div>'
});
new Vue({
el:'#app',
methods:{
doThis:function(){
console.log('我是丁红丽')
}
}
})
</script>
</body>
.sync修饰符
<body><div id="app">
<div>{{bar}}</div>
<my-comp :foo.sync="bar"></my-comp>
<!-- <my-comp :foo="bar" @update:foo="val => bar = val"></my-comp> -->
</div>
<script>
Vue.component('my-comp', {
template: '<div @click="increment">点我+1</div>',
data: function() {
return {copyFoo: this.foo}
},
props: ['foo'],
methods: {
increment: function() {
this.$emit('update:foo', ++this.copyFoo);
}
}
});
new Vue({
el: '#app',
data: {bar: 0}
});
</script>
</body>
以上是 vue组件知识整理 的全部内容, 来源链接: utcz.com/z/377474.html