vue组件
1.component注册组件:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script> </head> <body> <div id="app-7"> <ol> <todo-item v-for="item in groceryList" v-bind:todo="item" v-bind:key="item.id"> </todo-item> </ol> </div> </body> <script type="text/javascript"> Vue.component('todo-item', { props: ['todo'], template: '<li>{{ todo.text }}</li>' }); var app7 = new Vue({ el: '#app-7', data: { groceryList: [ { id: 0, text: '蔬菜' }, { id: 1, text: '奶酪' }, { id: 2, text: '随便其它什么人吃的东西' } ] } }); </script> </html>
2.可以把component中的组件抽出来,用extend方法定义组件,component负责注册组件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script> </head> <body> <div id="app"> <ol> <todo v-for="item in groceryList" v-bind:text="item"> </todo> </ol> </div> </body> <script type="text/javascript"> // 构建一个子组件 var todoItem = Vue.extend({ template: "<li> {{ text }} </li>", props: { text: { type: String, default: '' } } }); Vue.component('todo', todoItem); new Vue({ el: '#app', data: { groceryList: [ '蔬菜', '奶酪', '随便其它什么人吃的东西' ] } }); </script> </html>
type
可以是下面原生构造器:String ,Number,Boolean,Function,Object,Array,Symbol。
Vue.component('example', {
props: {
// 基础类型检测 (`null` 指允许任何类型)
propA: Number,
// 可能是多种类型
propB: [String, Number],
// 必传且是字符串
propC: {
type: String,
required: true
},
// 数值且有默认值
propD: {
type: Number,
default: 100
},
// 数组/对象的默认值应当由一个工厂函数返回
propE: {
type: Object,
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
return value > 10
}
}
}
})
3.组件可以嵌套使用:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script> </head> <body> <div id="app"> <todo :todo-data="groceryList"></todo> </div> </body> <script type="text/javascript"> // 构建一个子组件 var todoItem = Vue.extend({ template: "<li> {{ text2 }} </li>", props: { text2: { type: String, default: '' } } }); // 构建一个父组件 var todoWarp = Vue.extend({ template: ` <ul> <todo-item v-for="(item, index) in todoData" v-bind:text2="item.text" ></todo-item> </ul> `, props: { todoData: { type: Array, default: [] } }, // 局部注册子组件 components: { todoItem: todoItem } }); // 注册到全局 Vue.component('todo', todoWarp); new Vue({ el: '#app', data: { groceryList: [ { id: 2, text: '蔬菜' }, { id: 3, text: '奶酪' }, { id: 4, text: '随便其它什么人吃的东西' } ] } }); </script> </html>
注意命名,html语法不区分大小写,会统一转成小写,所以todoData(驼峰式命名)要转成等价的todo-data(短划线命名),上面例子中的,如果是这样写:
Vue.component('toDo', todoItem);
使用时同样要用to-do
注册局部组件使用:
components: {
todoItem: todoItem
}
在Vue对象里也可以这样注册局部组件
注册全局组件使用:
Vue.component('todo', todoWarp);
其实都是key-value,只不过全局注册调用方法,局部注册传递对象
也可以使用v-text指令替代v-bind,v-text指令设置元素的文本,这样的话,就不需要定义text属性了
以下效果跟上面一样:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script> </head> <body> <div id="app"> <todo :todo-data="groceryList"></todo> </div> </body> <script type="text/javascript"> // 构建一个子组件 var todoItem = Vue.extend({ template: "<li></li>", }); // 构建一个父组件 var todoWarp = Vue.extend({ template: ` <ul> <todo-item v-for="(item, index) in todoData" v-text="item.text" ></todo-item> </ul> `, props: { todoData: { type: Array, default: [] } }, // 局部注册子组件 components: { todoItem: todoItem } }); // 注册到全局 Vue.component('todo', todoWarp); new Vue({ el: '#app', data: { groceryList: [ { id: 2, text: '蔬菜' }, { id: 3, text: '奶酪' }, { id: 4, text: '随便其它什么人吃的东西' } ] } }); </script> </html>
:todo-data跟v-bind:todo-data效果一样
3.数据可以不依赖Vue对象,直接写到extend里:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script> </head> <body> <div id="todoItem"></div> </body> <script type="text/javascript"> // 局部注册组件 var todoItem = Vue.extend({ data: function () { return { todoData: [ { id: 0, text: '蔬菜' }, { id: 1, text: '奶酪' }, { id: 2, text: '随便其它什么人吃的东西' } ] }; }, template: ` <ul> <li v-for='(d, i) in todoData' :key="i"> {{ d.text }} </li> </ul> ` }); new todoItem().$mount('#todoItem'); </script> </html>
- data定义都必须是函数返回对象
- mount用于把组件挂载到指定id的元素里
- mount可以直接挂载元素,不需要通过id
new todoItem().$mount('todoItem');
在html里直接这样写:
<body>
<todoItem></todoItem>
</body>
或
<body>
<todoitem></todoitem>
</body>
new todoItem().$mount('todoItem');也可以写成
new todoItem().$mount('todoitem');
挂载和使用的时候大小写不区分,不能变成短划线命名
可以动态改变data的值:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script> </head> <body> <div id="todoItem"></div> </body> <script type="text/javascript"> // 局部注册组件 var todoItem = Vue.extend({ data: function() { return { todoData: [ { id: 0, text: '蔬菜' }, { id: 1, text: '奶酪' }, { id: 2, text: '随便其它什么人吃的东西' } ] }; }, template: ` <ul> <li v-for='(d, i) in todoData' :key="i"> {{ d.text }} </li> </ul> `, methods: { change() { setTimeout(() => { this.todoData.push( { id: 3, text: 'hi3' }); }, 2000); }, }, mounted() { this.change(); } }); new todoItem().$mount('#todoItem'); </script> </html>
也可以在挂载时动态设置值:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="https://cdn.bootcss.com/vue/2.4.2/vue.js"></script> </head> <body> <author></author> </body> <script type="text/javascript"> var author = Vue.extend({ template: "<p><a :href='url'>{{author}} & {{name}}</a></p>", data: function() { return { author: 'vamous', url: 'http://blog.csdn.net/Dear_Mr/article/details/72614370' }; }, props: ['name'] }); new author({ propsData: { name: 'dear_mr' } }).$mount('author'); </script> </html>
可以动态调用方法改变extend里面的值
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="https://cdn.bootcss.com/vue/2.4.2/vue.js"></script> </head> <body> <author></author> </body> <script type="text/javascript"> var author = Vue.extend({ template: `<div> <p><a :href='url'>{{author}} & {{name}}</a></p> <div @click="change">change</div> </div>`, data: function() { return { author: 'vamous', url: 'http://blog.csdn.net/Dear_Mr/article/details/72614370' }; }, methods: { change() { this.name = "abc"; }, }, props: ['name'] }); new author({ propsData: { name: 'dear_mr' } }).$mount('author'); </script> </html>
data也可以动态改变,比如:
methods: {
change() {
this.name = "abc";
this.author = "zy";
},
},
注意组件只能有一个根元素,下面这样写不对:
template: ` <p><a :href='url'>{{author}} & {{name}}</a></p> <div @click="change">change</div> `