Vue组件总结。父组件与子组件的运用,组件的基本使用。
1.基础组件
1. 基本概念
组件是可复用的Vue实例。如果网页中的某一个部分需要在多个场景中使用,那么我们可以把这部分功能抽取出来形成一个组件。这样可以大大提高代码的复用率。
2. 基础实例
第一步:在js代码中注册一个组件:
Vue.component("hello-ni", {
template: '<h1>{{haijun}}</h1>',
data: function () {
return {
haijun: "hello haijun"
}
}
})
上面代码注册了一个名为hello-ni的组件,template为组件中的内容,data为组件的模板数据data。
第二步:我们可以在一个通过 new Vue 创建的 Vue 根实例中,把这个组件作为自定义元素来使用:
第三步: 运行代码,会在页面上显示 hello haijun
3. 组件的复用
因为组件是可复用的 Vue 实例,所以它们与 new Vue 接收相同的选项,例如 data、computed、watch、methods 以及生命周期钩子等。仅有的例外是像 el 这样根实例特有的选项。
你可以将组件进行任意次数的复用:
注意:
data必须是一个函数,不能像之前写成对象的形式,因此每个实例可以维护一份被返回对象的独立的拷贝:
data: function () {
return {
haijun: “hello haijun”
}
}
4. 组件的组织
以组件树的形式来组织:
你的每一个组件中都还有可能细分成更小的组件。所以Vue组件化的意思就是说页面由很多个组件层层递进形成一个最终的网页。
两种组件的注册类型:全局注册和局部注册。上面的实例所使用的是全局注册的例子:
Vue.component(‘my-component-name’, {
// … options …
})
全局注册的组件可以使用在你创建之后的任何Vue根实例中或者所有子组件的模板中。
5. 父组件向子组件传递数据
方式: 通过op
Prop 是你可以在组件上注册的一些自定义 attribute。当一个值传递给一个 prop attribute 的时候,它就变成了那个组件实例的一个 property。
实例:
- //对根组件中的chanpin数组对象进行循环,然后把其中的每一项传递给子组件product
<script>
Vue.component('product-com',{
props: ['product'], //父组件要向子组件传递的东西
template: `<li>
<h3>产品名称{{product.title}}</h3>
<h4>产品描述{{product.brief}}</h4>
<p>产品价格{{product.price}}</p>
</li>`
})
let app = new Vue({
el: "#app",
data: {
chanpin: [
{
title: '产品1',
brief: '好吃1',
price: 10
},
{
title: '产品2',
brief: '好吃2',
price: 20
},
{
title: '产品3',
brief: '好吃3',
price: 30
},
{
title: '产品4',
brief: '好吃4',
price: 40
},
]
}
})
</script>
注意: 当模板template中的东西不只一个时,要将模板中的内容包裹在一个大的div中。
6. 子组件向父组件传值
实例:
<body>
<div id="app">
<!-- 循环传值组件 -->
<school v-for="item,index in schoolList" :school-name="item" :index="index" @cschool="changeEvent"></school>
<h3> 选中的学校是:{{chooseshool}}</h3>
</div>
<script>
Vue.component("school",{
props: ['schoolName','index'],
template: `<li>
<h3>{{schoolName}}-学校名称{{index}}</h3>
<button @click="chooseEvent(schoolName)">选择学校</button>
</li>`,
methods: {
chooseEvent: function (schoolName) {
console.log(schoolName);
//想要将子元素的数据传递给父元素,需要自定义触发事件,实现数据的传值
this.$emit("cschool",schoolName)
}
},
})
let app = new Vue({
el: "#app",
data: {
schoolList: ['刘海军小学','刘海军中学','刘海军大学'],
chooseshool: ''
},
methods: {
//data中就是从子组件中传过来的值
changeEvent: function (data) {
console.log("触发学校选择事件");
this.chooseshool = data;
}
}
})
</script>
</body>
7. 把父组件的方法传递给子组件
方法一:把父组件的方法传递给子组件,然后在子组件中调用方法,从而达到修改父组件数据的目的。
<body>
<div id="app">
<!-- 循环传值组件 -->
<!--
因为父元素的方法可以直接修改父元素的数据
所以将父元素的方法传递给子元素
然后由子元素进行调用,从而修改父元素的数据
-->
<school v-for="item,index in schoolList" :school-name="item" :index="index" :action="changeEvent" ></school>
<h3> 选中的学校是:{{chooseshool}}</h3>
</div>
<script>
Vue.component("school",{
props: ['schoolName','index','action'], //从根组件中传过来的数据
template: `<li>
<h3>{{schoolName}}-学校名称{{index}}</h3>
<button @click="chooseEvent(schoolName)">选择学校</button>
</li>`,
methods: {
chooseEvent: function (schoolName) {
console.log(schoolName);
console.log(this.action);
this.action(schoolName); //将子组件调用方法之后得到的schoolName通过action修改父元素的数据。
}
},
})
let app = new Vue({
el: "#app",
data: {
schoolList: ['刘海军小学','刘海军中学','刘海军大学'],
chooseshool: ''
},
methods: {
changeEvent: function (data) {
console.log("触发学校选择事件");
this.chooseshool = data;
}
}
})
</script>
</body>
方法二:子组件可以通过$parent属性找到父组件的Vue对象,从而找到父组件的方法,达到修改数据的目的。
<body>
<div id="app">
<!-- 循环传值组件 -->
<school v-for="item,index in schoolList" :school-name="item" :index="index" ></school>
<h3> 选中的学校是:{{chooseshool}}</h3>
</div>
<script>
Vue.component("school",{
props: ['schoolName','index'],
template: `<li>
<h3>{{schoolName}}-学校名称{{index}}</h3>
<button @click="chooseEvent(schoolName)">选择学校</button>
</li>`,
methods: {
chooseEvent: function (schoolName) {
console.log(schoolName);
console.log(this);
//组件可以通过$parent属性找到父元素的vue对象
this.$parent.changeEvent(schoolName)
}
},
})
let app = new Vue({
el: "#app",
data: {
schoolList: ['刘海军小学','刘海军中学','刘海军大学'],
chooseshool: ''
},
methods: {
changeEvent: function (data) {
console.log("触发学校选择事件");
this.chooseshool = data;
}
}
})
</script>
</body>
方法三:在子组件的template视图中直接调用父组件的方法,从而达到修改数据的目的。
<body>
<div id="app">
<!-- 循环传值组件 -->
<school v-for="item,index in schoolList" :school-name="item" :index="index" ></school>
<h3> 选中的学校是:{{chooseshool}}</h3>
</div>
<script>
Vue.component("school",{
props: ['schoolName','index'],
//在视图直接调用父元素的方法
template: `<li>
<h3>{{schoolName}}-学校名称{{index}}</h3>
<button @click="$parent.changeEvent(schoolName)">选择学校</button>
</li>`,
})
let app = new Vue({
el: "#app",
data: {
schoolList: ['刘海军小学','刘海军中学','刘海军大学'],
chooseshool: ''
},
methods: {
changeEvent: function (data) {
console.log("触发学校选择事件");
this.chooseshool = data;
}
}
})
</script>
</body>
2. 组件注册
1. 组件名
在注册一个组件的时候,我们始终需要给它一个名字。组件名是其第一个参数。
强烈推荐遵循 W3C 规范中的自定义组件名 (字母全小写且必须包含一个连字符)。这会帮助你避免和当前以及未来的 HTML 元素相冲突。
当使用驼峰命名法时,在引用这个自定义元素时两种命名法都可以使用。也就是说 和 都是可接受的。注意,尽管如此,直接在 DOM (即非字符串的模板) 中使用时只有 这种样式是有效的。
2. 全局注册与局部注册。
全局注册:也就是说它们在注册之后可以用在任何新创建的 Vue 根实例 (new Vue) 的模板中。
局部注册:通过一个普通的 JavaScript 对象来定义组件。
var ComponentA = { /* ... */ }
var ComponentB = { /* ... */ }
var ComponentC = { /* ... */ }
注意:局部注册的组件在其子组件中不可用
3. 模块系统
import ComponentA from './ComponentA'
import ComponentC from './ComponentC'
export default {
components: {
ComponentA,
ComponentC
},
// ...
}