Vue 根组件,局部,全局组件 | 组件间通信,案例组件化
一 组件
<div id="app"> <h1>{{ msg }}</h1> </div> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> // 通过new Vue创建的实例就是根组件(实例与组件一一对应,一个实例就是一个组件) // 每个组件组件均拥有模板,template var app = new Vue({ // 根组件的模板就是挂载点 el: "#app", data : { msg: "根组件" }, // 根组件可以显式书写模板吗? 可以 // 模板: 由""包裹的html代码块,出现在组件的内部,赋值给组件的$template变量 // 根组件如果不书写自身模板,那么模板就采用挂载点,如果显式书写模块,就会替换挂载点,但根组件必须拥有挂载点 template: "<div>显式模板</div>" }) // app.$template </script>
<script type="text/javascript"> // 一个满足vue语法规则的对象就是一个组件 // 直接来定义这样的组件,用一个变量名来接收,就是创建了一个局部组件, // 变量名就是局部组件的组件名 // 通过组件名就可以使用该组件 // 局部组件要在父组件中使用,一定要提前在父组件中进行注册 // 语法规则 // 有自身模板template,有data/methods/computed/watch... var localTag = { template: "<div class='sup'><div class='sub'></div></div>" } var btnTag = { // template: "<div><button>按钮1</button><button>按钮2</button></div>" template: "<button @click='btnAction'>点击了{{ num }}下</button>", // data需要绑定方法,数据通过方法返回值进行处理,达到组件复用时,数据的私有化 data: function() { return { num: 0 } }, methods: { btnAction: function () { this.num++ } } } // 根组件 new Vue({ el: "#app", // 注册子组件 components: { // 1 // "localtag": localTag // 2 // "localTag": localTag // 3 // "local-tag": localTag // 4 // localTag: localTag // 5 ES6对象语法,key value写法相同,可以省略value localTag, btnTag, } }) </script>
<body> <div id="app"> <global-tag v-for="(o, i) in ls" :key="i"></global-tag> </div> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> // 全局组件 // 用Vue.component("组件名", {})来创建全局组件 // 全局组件附属于Vue实例,可以不需要注册就可以使用 Vue.component("global-tag", { template: "<button @click='btnClick'>{{ n }}</button>", data () { return { n: 0 } }, methods: { btnClick () { this.n++ } } }) new Vue({ el: "#app", data: { ls: [0, 0, 0] } }) </script>
二 组件间通信
<body> <div id="app"> <local-tag :num="num" :sup_data="sup_data"></local-tag> </div> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> // 父组件与子组件建立联系的关键点 // 同绑定属性的方式进行数据传输 // 1.给在父组件中出现的子组件名定义标签的全局属性 // 2.全局属性的值赋值为父组件的数据变量 // 3.在子组件内部,通过props拿到标签中的全局属性名 var localTag = { props: ['num', 'sup_data'], template: "<div @click='divActive'>{{ num }}</div>", methods: { divActive () { console.log(this.num); console.log(this.sup_data); } } } // 数据属于父组件,子组件来接收使用数据 new Vue({ el: "#app", components: { localTag }, data: { num: 10, sup_data: [1, 2, 3, 4, 5] } }) </script>
<div id="app"> <global-tag @send_data="receive_data"></global-tag> {{ n }} </div> <script type="text/javascript"> // 1.数据由子级提供 // 2.在子级中通过某个事件对外(this.$emit("事件名", ...args))发送一个事件 // 3.在父级的模板中,子组件名上,为发送的事件绑定一个回调方法,该回调方法由父级来完成实现体 // 4.在实现体中就可以拿到回调参数 Vue.component("global-tag", { #子绑定事件 template: "<div @click='divAction'>我是div</div>", data () { return { num: 10, arrList: [1, 2, 3, 4, 5] } }, methods: { divAction () { this.$emit("send_data", this.num, this.arrList) } } }); new Vue({ el: "#app", data: { n: 0 }, methods: { receive_data (num, arrList) { console.log("接收到的数据:", num, arrList); this.n = num; } } }) </script>
<body> <div id="app"> <div> <input type="text" v-model="val"> <button type="button" @click="submitMsg">提交</button> </div> <ul> <!-- <li v-for="(v, i) in list" :key="i" @click="removeMsg(i)">{{ v }}</li> --> <todo-list v-for="(v, i) in list" :key="i" :v="v" :i="i" @delect_action="delect_action"></todo-list> </ul> </div> </body> <script src="js/vue-2.5.17.js"></script> <script type="text/javascript"> Vue.component("todo-list", { template: "<li @click='delect_action'><span>第{{ i + 1 }}条: </span><span>{{ v }}</span></li>", props: ['v', 'i'], methods: { delect_action () { this.$emit("delect_action", this.i) } } }) new Vue({ el: "#app", data: { val: "", list: [] }, methods: { submitMsg () { // 往list中添加input框中的value if (this.val) { this.list.push(this.val); this.val = "" } }, delect_action(index) { this.list.splice(index, 1) } } }) </script>