vue学习(三)组件传值
组件
官网(https://cn.vuejs.org/v2/guide/components.html)
组件分为局部组件和全局组件
局部组件:是内容中国的一部分 只是在当前组件加载的时候
全部组件:如:导航栏 侧边栏 运用到任意地方
一 局部组件
简单版
<div id="app"> <!--3. 用子--> <App></App> </div> <script> // App 组件 有 template + css + js // 1 生子 const App = { template:`<h3>我是App组件</h3>` }; let app = new Vue({ el:'#app', data:{ }, // 2.挂子 components:{ App } }) </script>
复杂版-----主要是在生子处
<div id="app"> <!--3. 用子--> <App></App> </div> <script> // App 组件 有 template + css + js // 1 生子 // 在组件中的data数据 必须是一个函数,返回一个对象 const App = { data() { return { msg: '我是App组件1' } }, // template 标签必须在一个 template: ` <div> <h3>{{ msg }}</h3> <button @click="handelClick">提交</button> </div> `, methods:{ handelClick(){ alert(123) } } }; let app = new Vue({ el: '#app', data: {}, // 2.挂子 components: { App } }) </script>
二 全局组件
全局组件
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width ,initial-scale=1"> <!--<script src="https://cdn.jsdelivr.net/npm/vue"></script>--> <script src="vue.js"></script> </head> <body> <div id="app"> <!--3. 用子--> <App></App> </div> <script> // 定义一个全局组件 Vue.component('Vheader',{ template:`<h1>我的导航组件</h1>` }); Vue.component('Vaside',{ template:`<h1>我的左侧导航</h1>` }); // 局部组件 const VConent = { template: ` <div> <h1>我是内容局部组件</h1> </div> ` }; const App = { components:{ VConent // 挂载子组件 }, template: ` <div> <Vheader></Vheader> <Vaside></Vaside> <VConent></VConent> </div> ` }; let app = new Vue({ el: '#app', data: {}, // 2.挂子 components: { App } }) </script> </body> </html>
父传子组件
① 在子组件中写 props=[xxx] 接收父组件挂载的属性---也可以接收对象 【可以参考vue(四)作用域插槽】
② 父组件中 绑定 xxx=‘msg’
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width ,initial-scale=1"> <!--<script src="https://cdn.jsdelivr.net/npm/vue"></script>--> <script src="vue.js"></script> </head> <body> <div id="app"> <!--3. 用子--> <App></App> </div> <script> Vue.component('Vchild',{ template:` <div> <div style="color: red">我是子组件</div> <h3>{{ childMsg }}</h3> </div> `, props:['childMsg'] }); const App = { data(){ return{ msg:'我是父组件传值' } }, template: ` <div> <Vchild :childMsg="msg"></Vchild> </div> ` }; let app = new Vue({ el: '#app', data: {}, // 2.挂子 components: { App } }) </script> </body> </html>
子传父
① 在父组件中要绑定自定义事件 如: @input="inputHandler"
② 在子组件中触发原生事件,在事件函数中通过this.$emit触发自定义事件
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width ,initial-scale=1"> <!--<script src="https://cdn.jsdelivr.net/npm/vue"></script>--> <script src="vue.js"></script> </head> <body> <div id="app"> <!--3. 用子--> <App></App> </div> <script> // 子组件 // 子传父 // ① input框 在inputHandler使用 Vue.component('Vchild', { template: ` <div> <div style="color: red">我是子组件</div> <h3>{{ childMsg }}</h3> <input type="text" @input="inputHandler"> </div> `, props: ['childMsg'], methods: { inputHandler(e) { // console.log(e.target.value) const val = e.target.value; this.$emit('Handlerinput', val) } } }); // 父组件 const App = { data() { return { msg: '我是父组件传值', newVal:'' } }, methods:{ inputVal(newVal){ this.newVal = newVal } }, template: ` <div> <Vchild :childMsg="msg" @Handlerinput="inputVal"></Vchild> <div class="father"> 数据:{{ newVal }} </div> </div> ` }; let app = new Vue({ el: '#app', data: {}, // 2.挂子 components: { App } }) </script> </body> </html>
平行通信
① 创建一个 bus
② 通过bus.$on 绑定事件
③ 通过 bus.$emit 触发事件
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width ,initial-scale=1"> <!--<script src="https://cdn.jsdelivr.net/npm/vue"></script>--> <script src="vue.js"></script> </head> <body> <div id="app"> <App></App> </div> <script> const bus = new Vue(); Vue.component('B', { data(){ return { count:0 } }, template: `<div>{{count}}</div>`, // 当组件被创建出来的时候 就会立即被调用 created(){ // $on 绑定事件 bus.$on('add',(n)=>{ this.count+=n }) } }); Vue.component('A', { template: ` <button @click="handleClick">加入购物车</button> `, methods:{ handleClick(){ // $emit 触发事件 bus.$emit('add',1); } } }); const App = { template: ` <div> <A></A> <B></B> </div> ` }; let app = new Vue({ el: '#app', components: { App } }) </script> </body> </html>
组件通信其他方式(provide和inject)
在父组件中 provide 中提供变量,然后在子组件中通过inject来注入变量,无论组件嵌套多深,只要是调用了inject 就能拿到父组件中的变量
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width ,initial-scale=1"> <!--<script src="https://cdn.jsdelivr.net/npm/vue"></script>--> <script src="vue.js"></script> </head> <body> <div id="app"> <App></App> </div> <script> Vue.component('A', { inject:['msg'], // 数组接收 template: `<div>{{msg}}</div>`, }); const App = { provide(){ return{ msg:'老爹的数据' } }, template: ` <div> <A></A> </div> ` }; let app = new Vue({ el: '#app', components: { App } }) </script> </body> </html>