vue组件知识整理

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

回到顶部