vue进阶
计算属性
# 插值的普通函数,只要页面一刷新,函数就会重写计算,跟函数没关的值的变化,函数也会重写计算
# 计算属性把函数当成属性来用---》只有这个函数使用的属性(变量)变化,函数才重写运算
<!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="mytest2">-->{{mytest2}} <br> <input type="text" v-model="mytext">--->{{mytext.substring(0,1).toUpperCase()+mytext.substring(1)}} <br> 函数方式:{{getName()}} <br> 计算属性:{{getName2}} </div> </body> <script> var vm = new Vue({ el: '#app', data: { mytext: '', mytest2: '', }, methods:{ getName(){ console.log("我执行了") return this.mytext.substring(0,1).toUpperCase()+this.mytext.substring(1) } }, // 8生命周期 computed:{ getName2(){ console.log("计算属性我执行了") return this.mytext.substring(0,1).toUpperCase()+this.mytext.substring(1) } } }) </script> </html>
通过计算属性重写过滤案例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>过滤案例</title> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script> </head> <body> <div id="box"> <p><input type="text" v-model="myText" placeholder="请输入要筛选的内容:"></p> <ul> <li v-for="data in newList">{{data}}</li> </ul> </div> </body> <script> var vm = new Vue({ el: '#box', data: { myText: '', dataList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'], }, computed:{ newList(){ console.log('我执行了') var datalist2 = this.dataList.filter(item => { return item.indexOf(this.myText) > -1 }) return datalist2 } } }) </script> </html>
侦听属性
只要变量发生变化,就会执行监听属性中的方法
<!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}} </div> </body> <script> var vm = new Vue({ el: '#app', data: { mytext: '', }, watch: { // 只要mytext发生变化,就会执行该函数 mytext: function () { console.log('我变化了,执行') } } }) </script> </html>
组件
局部组件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.js"></script> </head> <body> <div id="app"> <Top></Top> <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br> <Bottom></Bottom> </div> </body> <script> var vm = new Vue({ // el data methods watch computed 8个 el: '#app', data: {}, // 定义再这里面的叫局部组件,只能再局部使用,只能再id为app的标签内使用 components: { 'Top': { template: ` <div> <h1 style="background: pink;font-size: 60px;text-align: center">{{name}}</h1> <hr> <button @click="handleC">点我看美女</button> </div> `, data() { return { name: "我是头部" } }, methods: { handleC() { alert('美女') } }, }, 'Bottom': { template: ` <div> <hr> <h1 style="background: green;font-size: 60px;text-align: center">{{name}}</h1> </div> `, data() { return { name: "我是尾部" } }, }, }, }) </script> </html>
全局组件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.js"></script> </head> <body> <div id="app"> <top></top> </div> </body> <script> // 定义全局组件--->任意位置都可以用 Vue.component('top', { template: ` <div> <h1 style="background: pink;font-size: 60px;text-align: center">{{name}}</h1> <hr> <button @click="handleC">点我看美女</button> </div> `, data() { return { name: "我是头部" } }, methods: { handleC() { alert('美女') } }, },) var vm = new Vue({ // el data methods watch computed 8个 el: '#app', data: {}, }) </script> </html>
注意事项
# 扩展 HTML 元素,封装可重用的代码,目的是复用
-例如:有一个轮播,可以在很多页面中使用,一个轮播有js,css,html
-组件把js,css,html放到一起,有逻辑,有样式,有html
# 局部组件,全局组件
-
# 注意事项
1 自定义组件需要有一个root element,一般包裹在一个div中
2 父子组件的data是无法共享
3 组件可以有data,methods,computed....,但是data 必须是一个函数
组件通信之父传子
通过自定义属性传值
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.js"></script> </head> <body> <div id="app"> <!--通过自定义属性:myheader--> <top :myheader="headerName"></top> {{headerName}} <input type="text" v-model="headerName"> </div> </body> <script> // 定义全局组件--->任意位置都可以用 Vue.component('top', { template: ` <div> <h1 style="background: pink;font-size: 60px;text-align: center">{{myheader}}</h1> </div> `, data() { return { name: "我是头部" } }, // 必须叫props,数组内放自定义属性的名字 // props:['myheader',], // 属性验证 props:{ myheader:String, // key是自定义属性名,value是类型名,如果是别的类型就报错 }, },) var vm = new Vue({ // el data methods watch computed 8个 el: '#app', data: { headerName:999 }, }) </script> </html>
组件通信之子传父
通过自定义事件传值
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.js"></script> </head> <body> <div id="app"> <!-- 自定义了一个myevent事件 --> <top @myevent="handelRecv"></top> <hr> 接收到子组件的数据是:{{childText}} </div> </body> <script> // 定义全局组件--->任意位置都可以用 Vue.component('top', { template: ` <div> <h1 style="background: pink;font-size: 60px;text-align: center">{{myheader}}</h1> <input type="text" v-model="text"> <button @click="handleSend">点我传出去</button> </div> `, data() { return { myheader: "我是头部", text: '', } }, methods:{ handleSend(){ // 触发绑定在该组件上的事件,myevent---》父组件中会执行事件对应的函数handelRecv--》 this.$emit('myevent',this.text) } } },) var vm = new Vue({ // el data methods watch computed 8个 el: '#app', data: { childText: '' }, methods:{ handelRecv(text){ // 接收一个参数,赋值给父组件的childText this.childText=text } } }) </script> </html>
ref属性
# ref属性,如果放在普通标签上,就是普通标签的原生html,操作,设置
# ref属性,如果放在组件上,就是当前组件对象
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.js"></script> </head> <body> <div id="app"> <top ref="top"></top> <input type="text" v-model="text" ref="myinput"> <img src="" alt="" ref="myimg" height="80px" width="80px"> <hr> <button @click="handleC">点我</button> </div> </body> <script> // 定义全局组件--->任意位置都可以用 Vue.component('top', { template: ` <div> <h1>{{myheader}}</h1> <button @click="handleC">点我看美女</button> <hr> </div> `, data() { return { myheader: "我是头部", } }, methods:{ handleC(){ alert("美女") } } },) var vm = new Vue({ el: '#app', data: { text:'' }, methods:{ handleC(){ console.log('我被点了') //把所有有ref属性的标签 弄到 一个对象中 console.log(this.$refs) // 是所有标签写了ref属性的对象{myinput:真正的标签,myimg:真正的标签} //111111 放在普通标签上示例 // 取到input的value值 // console.log(this.$refs.myinput.value) // this.$refs.myinput.value='lqz is nb' // this.$refs.myimg.src='https://tva1.sinaimg.cn/large/00831rSTly1gd1u0jw182j30u00u043b.jpg' //222222 放在组件上示例 // console.log(this.$refs.top) // 既然能够拿到组件对象,组件中的data中的值也可以拿到,组件中的方法也可调用 console.log(this.$refs.top.myheader) // 父组件中拿到了子组件的值 // 不区分是子传父还是父传子了 // 想子传父--》下面就是子传父 // console.log(this.$refs.top.myheader) // this.text=this.$refs.top.myheader // 想父传子 // this.$refs.top.myheader='刘清政 is nb' // this.$refs.top.myheader=this.text // 还可以调用组件的方法 this.$refs.top.handleC() //如果有参数,是不是也可以传到子组件中 } } }) </script> </html>
动态组件与keep-alive
keep-alive:组件不销毁
component:有个is属性,指定显示的组件是哪个
<!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="changeC('index')">首页</li> <li @click="changeC('order')">订单</li> <li @click="changeC('good')">商品</li> </ul> <!-- 笨办法--> <!--<index v-if="index_show"></index>--> <!--<order v-if="order_show"></order>--> <!--<good v-if="good_show"></good>--> <keep-alive> <component :is='who'></component> </keep-alive> </div> </body> <script> // 定义全局组件--->任意位置都可以用 Vue.component('index', { template: ` <div> <h1>我是首页</h1> </div> `, },) Vue.component('order', { template: ` <div> <h1>我是订单</h1> 请输入要查询的订单:<input type="text"> </div> `, },) Vue.component('good', { template: ` <div> <h1>我是商品</h1> </div> `, },) var vm = new Vue({ el: '#app', data: { // index_show:true, // order_show:false, // good_show:false, who:'index' }, methods:{ changeC(i){ this.who=i } } }) </script> </html>
插槽与具名插槽
普通插槽
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.js"></script> </head> <body> <div id="app"> <index> <div> 用户名:<input type="text"> 密码:<input type="text"> </div> </index> </div> </body> <script> Vue.component('index', { template: ` <div> <h1>我是首页</h1> <slot></slot> </div> `, },) var vm = new Vue({ el: '#app', data: { }, methods:{ } }) </script> </html>
具名插槽
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="./js/vue.js"></script> </head> <body> <div id="app"> <index> <p slot="a">pppp</p> <div slot="b"> div--div </div> </index> </div> </body> <script> Vue.component('index', { template: ` <div> <slot name="a"></slot> <h1>我是首页</h1> <slot name="b"></slot> </div> `, },) var vm = new Vue({ el: '#app', data: {}, }) </script> </html>

浙公网安备 33010602011771号