vue篇:组件间通信、ref属性、slot插槽、数据总线

  • 计算属性和监听属性
  • 组件化开发之局部和全局组件
  • 组件间通信之父传子
  • 组件间通信之子传父
  • ref属性
  • 数据总线
  • 动态组件
  • slot插槽

1 计算属性和监听属性

1.1 计算属性

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
1 computed 对象写函数,函数就可以当属性使用 {{getName}} computed:{ getName(){ return this.myText3.substr(0,1).toUpperCase()+this.myText3.substr(1) } 2 计算属性只有在它的相关依赖发生改变时才会重新求值
复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.js"></script> </head> <body> <div id="app"> <input type="text" v-model="myText"> --->{{myText.substr(0,1).toUpperCase()+myText.substr(1)}} <hr> <input type="text" v-model="myText2"> --->{{getText()}} <hr> <input type="text" v-model="myText3"> --->{{getName}} </div> </body> <script> var vm = new Vue({ el: '#app', data: { myText: '', myText2:'', myText3:'', }, methods:{ getText(){ console.log('函数执行了') return this.myText2.substr(0,1).toUpperCase()+this.myText2.substr(1) } }, computed:{ // 计算属性 getName(){ console.log('计算属性执行了') return this.myText3.substr(0,1).toUpperCase()+this.myText3.substr(1) } }, }) </script> </html>

重写过滤案例

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"> <script src="./js/vue.js"></script> </head> <body> <div id="app"> <div class="row"> <div class="col-md-6 col-md-offset-3"> <h1>过滤案例</h1> <input type="text" v-model="myText"> <hr> <p v-for="item in newList">{{item}}</p> </div> </div> </div> </body> <script> var vm = new Vue({ el: '#app', data: { myText: '', dataList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'], }, methods: { }, computed:{ newList(){ return this.dataList.filter(item=> { return item.indexOf(this.myText) >= 0 }) } } }) </script> </html>

1.2 监听属性

复制代码
  • 1
1 watch对象中写函数---》函数名就是data中得变量名,只要这个“变量发生变化”,就会“触发该函数的执行”
复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.js"></script> </head> <body> <div id="app"> <input type="text" v-model="myText"> --->{{myText}} <hr> </div> </body> <script> var vm = new Vue({ el: '#app', data: { myText: '', }, watch:{ myText(val){ console.log('执行了',val) } } }) </script> </html>

2 组件化开发之局部和全局组件

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
# 组件是什么?有什么用 扩展 HTML 元素,封装可重用的代码,目的是复用 -例如:有一个轮播,可以在很多页面中使用,一个轮播有js,css,html -组件把js,css,html放到一起,有逻辑,有样式,有html # 定义全局组件 Vue.component('Child', { template: ` <div> <h1>我是一个组件--{{ myText }}</h1> <button @click="handleClick">点我看美女</button> <br> <input type="text" v-model="myText"> <Jason></Jason> </div>`, data() { return { myText: '', } }, methods: { handleClick() { alert('美女') } }, components: { Jason: { template: ` <div> <h1>我是局部组件--jason</h1> </div>`, } } }) # 局部组件,写在Vue实力或者组件实例中 components: { Lqz: { template: ` <div> <h1>我是局部组件</h1> </div>`, } }

注意

复制代码
  • 1
  • 2
  • 3
  • 4
# 1 自定义组件需要有一个root element(根标签),一般包裹在一个div中 # 2 父子组件的data,methods是无法共享 # 3 组件可以有data,methods,computed....,但是data 必须是一个函数

3 组件间通信之父传子(自定义属性)

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.js"></script> </head> <body> <div id="app"> 自定义属性: myname <Child :myname="name"></Child> </div> </body> <script> //全局组件 Vue.component('Child', { template: ` <div> <h1>我是一个组件--{{ myText }}--{{myname}}</h1> <button @click="handleClick">点我看美女</button> <br> <input type="text" v-model="myText"> </div>`, data() { return { myText: '', } }, methods: { handleClick() { alert('美女') } }, props:['myname',] }) // 局部组件只能在局部使用 var vm = new Vue({ el: '#app', data: { name:'lqz' }, }) </script> </html>

3.1 属性验证

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.js"></script> </head> <body> <div id="app"> <h1>父组件中输入值</h1> 名字:<input type="text" v-model="name"> <br> 年龄:<input type="text" v-model.number="age"> <h1>子组件中显示</h1> <hr> <Child :myname="name" :myage="age"></Child> </div> </body> <script> //全局组件 Vue.component('Child', { template: ` <div> 名字是:{{ myname }} <br> 年龄是:{{ myage }} </div>`, // props:['myname',] props: { 'myname': String, myage: Number } }) // 局部组件只能在局部使用 var vm = new Vue({ el: '#app', data: { name: 'lqz', age:19 }, }) </script> </html>

4 组件间通信之子传父(自定义事件)

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.js"></script> </head> <body> <div id="app"> <h1>子组件中myText的数据是:{{name}}</h1> <hr> <Child @myevent="handleEvent"></Child> </div> </body> <script> //全局组件 Vue.component('Child', { template: ` <div> <input type="text" v-model="myText"> <button @click="handleClick">点我把数据传给父亲</button> <br> </div>`, data() { return { myText: '', } }, methods: { handleClick() { // 触发自定义事件myevent,后面有几个参数,就传几个参数,这样就会执行myevent绑定的函数,handleEvent this.$emit('myevent', this.myText) } }, }) // 局部组件只能在局部使用 var vm = new Vue({ el: '#app', data: { name:'' }, methods: { handleEvent(myText) { // console.log('我执行了') // console.log(myText) this.name=myText } } }) </script> </html>

5 ref属性

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
# ref 属性是什么 ref放在普通标签上,拿到的是原生节点,原生dom操作 ref放在组件上,拿到的是组件对象, 通过这种方式实现子传父(this.$refs.mychild.text) 通过这种方式实现父传子(调用子组件方法传参数) <p ref='pp'></p> <Child ref='cc'></Child>
复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.js"></script> </head> <body> <div id="app"> <!-- <input type="text" ref="pp">--> <p ref="pp">我是个p</p> <button @click="handleClick">点我执行函数</button> <hr> <Child ref="cc"></Child> </div> </body> <script> Vue.component('Child',{ template:`<div> <h1>我是组件</h1> 名字:{{name}} <br> 年龄:{{age}} </div>`, data(){ return { name:'彭于晏', age:37 } }, methods:{ handleClick(aaa){ console.log(this.name,this.age) } } }) var vm = new Vue({ el: '#app', data: { }, methods:{ handleClick(){ console.log(this.$refs) // this.$refs['pp'].value='lqz is handsome' // this.$refs['pp'].innerText='xxxx' // alert(this.$refs['cc'].name) // alert(this.$refs['cc'].age) //调用子组件的方法 this.$refs['cc'].handleClick('asdfasdfasdfasdf') } } }) </script> </html>

6 数据总线

复制代码
  • 1
  • 2
  • 3
  • 4
# 不同层级的不通组件通信 -数据总线 -vuex--->状态管理器---》 -cookie,localStorage,sessionStorage
复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.js"></script> </head> <body> <div id="app"> <child1></child1> <hr> <child2></child2> </div> </body> <script> // 1 定义一个数据总线----》本质就是一个vue对象 var bus = new Vue() //new一个vue的实例,就是中央事件总线 // 2 定义两个全局组件 Vue.component('child1', { template: ` <div> <input type="text" v-model="myText"> <button @click="handleClick">点我</button> </div>`, data() { return { myText: '' } }, methods: { handleClick() { bus.$emit('suibian',this.myText) } } }) Vue.component('child2', { template: ` <div> 接受到的数据是:{{ myText }} </div>`, data() { return { myText: '' } }, mounted(){ // 等着,监听,如果谁触发我,我就执行 bus.$on('suibian',(name)=>{ this.myText=name }) } }) var vm = new Vue({ el: '#app', data: {}, }) </script> </html>

7 动态组件

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
# 通过component配合is属性,决定显示的组件是哪个 # keep-alive 保证组件切换走后不被销毁 <keep-alive> <component :is="who"> </component> </keep-alive>
复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.js"></script> </head> <body> <div id="app"> <ul> <li @click="who='home'">首页</li> <li @click="who='goods'">商品</li> <li @click="who='order'">订单</li> </ul> <keep-alive> <component :is="who"> </component> </keep-alive> </div> </body> <script> Vue.component('home', { template: ` <div> 首页 </div>`, }) Vue.component('goods', { template: ` <div> 商品 <input type="text"> </div>`, }) Vue.component('order', { template: ` <div> 订单 </div>`, }) var vm = new Vue({ el: '#app', data: { who: 'home' }, }) </script> </html>

8 slot插槽

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
# 在组件标签中间加插槽的内容 <home> <div><button>美女</button></div> </home> # slot决定插槽的位置 Vue.component('home', { template: ` <div> <input type="text"> <hr> <slot></slot> # 插槽位置 <button>点我</button> </div>`, }) # 具名插槽 <home> <div slot="a">我是div</div> # 参数slot=a决定插槽位置 <img src="https://tva1.sinaimg.cn/large/00831rSTly1gd1u0jw182j30u00u043b.jpg" alt="" slot="b"> # # 参数slot=b决定插槽位置 </home> Vue.component('home', { template: ` <div> <input type="text"> <hr> <slot name="a"></slot> # 按名字a作为插入位置 navbar <slot name="b"></slot> # 按名字b作为插入位置 <button>点我</button> </div>`, })

无名插槽:

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.js"></script> </head> <body> <div id="app"> <home> <div><button>美女</button></div> </home> </div> </body> <script> Vue.component('home', { template: ` <div> <input type="text"> <hr> <slot></slot> <button>点我</button> </div>`, }) var vm = new Vue({ el: '#app', data: { }, }) </script> </html>

具名插槽:

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.js"></script> </head> <body> <div id="app"> <home> <div slot="a">我是div</div> <img src="https://tva1.sinaimg.cn/large/00831rSTly1gd1u0jw182j30u00u043b.jpg" alt="" slot="b"> </home> </div> </body> <script> Vue.component('home', { template: ` <div> <input type="text"> <hr> <slot name="a"></slot> navbar <slot name="b"></slot> <button>点我</button> </div>`, }) var vm = new Vue({ el: '#app', data: { }, }) </script> </html>

vue cli 创建出一个vue项目

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
-先装nodejs,http://nodejs.cn/ 一路下一步 -node:就是python npm命令:就是pip -npm install -g @vue/cli #装了vue脚手架 相当于 pip install django -vue create hello-world #相当于 djagno-admin startproject 项目名 -选很多东西 -pycharm打开即可 -pycharm打开即可
posted @   马氵寿  阅读(302)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开