Vue 组件
<!-- 一个包含html,css,js的独立集合体,这样的集合体可以完成页面结构的代码复用 -->
组件分类:
<!-- 组件分为: 根组件,全局组件,局部组件 - 根组件:所有被new Vue()产生的组件,在项目开发阶段,一个项目只会出现一个根组件 - 全局组件:不用注册,就可以成为任何一个组件的子组件 - 局部组件:必须注册,才可以成为注册该局部组件的子组件 -->
<!-- 每一个组件都有自身的html结构,css样式,js逻辑 - 每一个组件其实都有自己的template,就是用来标识自己html结构的 - template模板中有且只能有一个跟标签(<dev></dev>) - 根组件内一般不需要提供template,就由挂载点的真实DOM提供html结构 --> 补充: - template模板为组件提供所需的html结构 - template模板中的html结构是虚拟DOM,仅存在内存中 - 根组件中的template模板中的标签会替换根组件所挂载的真是DOM标签(挂载点不能是html和body标签的原因)
- 根组件:
<body> <div id="app"> <!-- 不会被渲染,因为div标签被tempalte模板中的标签替换 --> <p>{{ msg }}</p> </div> </body> <script src="js/vue.js"></script> <script> new Vue({ el: '#app', data: { msg: 'message', c1: 'red' }, template: ` <div :style="{color: c1}" @click="fn">{{ msg }} {{ msg }}</div> `, methods: { fn() { alert(this.msg) } } }); </script>
- 局部组件
<!-- 步骤: 1) 创建局部组件(同创建字典方式) 2) 创建该局部组件的html结构 3) 在父组件中的components内注册该局部组件 4) 在父组件的template模板(所挂载的标签)中以自定义标签的形式渲染该局部组件 -->
<body> <div id="app"> <!-- 4.在父组件的template模板(所挂载的标签)中以自定义标签的形式渲染该局部组件 --> <local-tag></local-tag> </div> </body> <script src="js/vue.js"></script> <script> // 1.创建局部组件(同创建字典方式) let localTag = { // 2.创建该局部组件的html结构 template:` <div class="box"> <img src="img/666.jpg" alt=""> <h3>❤</h3> <p>lilei❤hamm</p> </div> ` }; new Vue({ el: '#app', // 3.在父组件中注册局部组件 components:{ 'local-tag': localTag, } })
- 全局组件
<!-- 1) 创建全局组件(全局组件类似Vue实例) 2) 在父组件的template模板(所挂载的标签)中以自定义标签的形式渲染该局部组件 注意: - 你不需要在父组件中注册 -->
<script> Vue.component('组件名',{ // 组件成员 }); </script>
<body> <div id="app"> <!-- 2)在父组件的template模板(所挂载的标签)中以自定义标签的形式渲染该局部组件 --> <global-tag></global-tag> <global-tag></global-tag> <global-tag></global-tag> </div> </body> <script src="js/vue.js"></script> <script> // 1) 创建全局组件(全局组件类似Vue实例) Vue.component('global-tag',{ template:` <div class="box" @click="action"> <img src="img/666.jpg" alt=""> <h3>❤</h3> <p>❤{{ num }}</p> </div> `, // 数据局部化分析导入(利用函数的名称空间知识点:函数每实例化一次都会产生新的名称空间) data:function () { return { num:0 } }, methods:{ action(){ this.num++ } } }); // 全局组件不需要再父组件中注册 new Vue({ el: '#app' }) </script>
- 组件交互 | 父传子
<!-- 数据交互 - 父传子 - 通过绑定属性的方式 1) 父组件提供数据 2) 在父组件模板中,为子组件标签设置自定义属性,属性的值由父组件提供 3) 在子组件实例中,通过props实例成员获得自定义属性 -->
<body> <div id="app"> <info v-for="item in infos" :myinfo="item" :key="info.image"></info> </div> </body> <script src="js/vue.js"></script> <script> let infos = [ { image: 'img/001.png', title: '小猫' }, ]; let info = { template:` <div class="info"> <img :src="myinfo.image" alt=""> <p><b>{{ myinfo.title }}</b></p> </div> `, // 获取自定义属性 myinfo,此时的myinfo是个字典 props:['myinfo'] }; new Vue({ el: '#app', // 父组件提供数据 data:{ infos, }, components:{ info, } }) </script>
- 组件交互 | 子传父
<!-- 组件交互-子传父 1) 数据由子组件提供 2) 子组件内部通过触发系统事件,发送一个自定义事件,将数据携带出来 3) 父组件为子组件标签的自定义属性通过方法实现,就可以通过参数拿到子组件传递处理的参数 -->
<body> <div id="app"> <p> <input type="text" v-model="userMsg"> <button @click="sendMsg">留言</button> </p> <ul> <msg-li @remove_msg="removeAction" v-for="(msg, i) in msgs" :msg="msg" :index="i" :key="msg"></msg-li> </ul> </div> </body> <script src="js/vue.js"></script> <script> let msgLi = { template: ` <li> <span class="close" @click="deleteMsg(index)">x </span> <span>第{{ index + 1 }}条:</span> <span>{{ msg }}</span> </li> `, props: ['msg', 'index'], methods: { // 系统的click事件 deleteMsg(i) { // $emit('自定义事件名', 参数们) this.$emit('remove_msg', i); this.$emit('myclick', 1, 2, 3, 4, 5) } } }; // 组件交互-子传父 // 1) 数据由子组件提供 // 2) 子组件内部通过触发系统事件,发送一个自定义事件,将数据携带出来 // 3) 父组件位子组件标签的自定义属性通过方法实现,就可以通过参数拿到子组件传递处理的参数 new Vue({ el: '#app', data: { msgs: [], userMsg: '' }, methods: { sendMsg() { if (this.userMsg) { this.msgs.push(this.userMsg); this.userMsg = ""; } }, removeAction(i) { this.msgs.splice(i, 1) } }, components: { msgLi } }) </script>