vue之计算属性&监听属性&生命周期&组件介绍&组件间通信&ref属性

1.计算属性computed

# 1 计算属性是基于它们的依赖变量进行缓存的
# 2 延缓计算,计算属性只有在它的相关依赖变量发生改变时才会重新求值,否则不会变(函数只要页面变化,就会重新运算)
# 3 计算属性就像Python中的property,可以把方法/函数伪装成属性,可以被for循环
# 4 计算属性,必须有返回值
<!--计算属性start-->
<div id="countattr">
    <h1>input输入框的首字母大写</h1>
    <input type="text" v-model="name">----->{{upperFirst}}
    <h1>重写过滤案例</h1>
    <input type="text" v-model="search">
    <ul>
        <li v-for="str in getdataList">
            <p>{{str}}</p>
        </li>
    </ul>

</div>
<!--计算属性end-->
let vm1 = new Vue({
    el: "#countattr",
    data: {
        name: '',
        search: '',
        dataList: ['a', 'at', 'atom', 'attoo', 'be', 'beyond', 'cs', 'csrf'],
    },
    methods: {},
    computed: {
        upperFirst() {
            return this.name.substring(0, 1).toUpperCase() + this.name.substring(1)
        },
        getdataList() {
            return this.dataList.filter(str => str.indexOf(this.search) >= 0)
        },

    }
})

2.监听(侦听)属性watch

# 属性如果发生变化,就会执行某个函数
# 函数有2个参数,分别是新变量和老变量
<!--监听属性start-->
<div id="looking">
    <input type="text" v-model="title">
</div>
<!--监听属性end-->
let vm2 = new Vue({
    el: "#looking",
    data: {
        title: '',
    },
    watch: {
        title(fresh, raw) {
            console.log(fresh, '--', raw)
            console.log('changechange')
        }
    }
})

3.Vue生命周期

# new Vue()---->创建出来---》页面关闭---》被销毁掉----》整个整个过程经历了一个周期----》vue帮咱们提供了一些钩子函数[写了就会执行,不写就不执行],到某个阶段,就会触发某个函数的执行

# 8 个生命周期钩子函数
    beforeCreate	            创建Vue实例之前调用
    created	                    创建Vue实例成功后调用
    beforeMount	            渲染DOM之前调用
    mounted	                渲染DOM之后调用
    beforeUpdate	            重新渲染之前调用(数据更新等操作时,控制DOM重新渲染)
    updated	                    重新渲染完成之后调用
    beforeDestroy	        销毁之前调用
    destroyed	                销毁之后调用
	
    
# vue实例有生命周期,每个组件也有这8个生命周期

# 8个声明周期钩子,什么情况会用到
	-created:用的最多,变量初始化完成了(data中得数据),在这里,我们发送ajax请求
    -beforeDestroy:组件销毁之前会执行,资源清理工作
    	-组件创建,就执行一个定时任务[每隔1s,打印一个helloworld]
        -组件销毁,定时任务要销毁,如果定时任务不销毁,会一直执行

<!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="username"> --->{{username}}

    <h1>使用组件</h1>
    <button @click="handleShow">显示组件,隐藏组件</button>
    <hr>
    <child v-if="show"></child>
    <hr>
</div>


</body>
<script>
    // 组件有自己的html,css,js,事件。。。。
    // ``  模板字符串,es6语法
    // 在组件中,data必须是个函数,返回对象
    //1  定义一个全局组件
    Vue.component('child', {
        template: `
          <div>
          <button @click="back">后退</button>
          {{ name }}
          <button @click="forword">前进</button>
          </div>`,
        data() {
            return {
                name: '首页',
                t: null
            }
        },
        methods: {
            back() {
                alert('后退了')
            },
            forword() {
                alert('前进了')
            }
        },
        beforeCreate() {
            console.log('beforeCreate')
            console.log('当前el状态:', this.$el)
            console.log('当前data状态:', this.$data)
            console.log('当前name状态:', this.name)
        },
        created() {
            console.log('created')
            console.log('当前el状态:', this.$el)
            console.log('当前data状态:', this.$data)
            console.log('当前name状态:', this.name)

            // 启动一个定时器
            this.t = setInterval(() => {
                console.log('hello world')
            }, 1000)
        },
        beforeMount() {
            console.log('beforeMount')
            console.log('当前el状态:', this.$el)
            console.log('当前data状态:', this.$data)
            console.log('当前name状态:', this.name)
        },
        mounted() {
            console.log('mounted')
            console.log('当前el状态:', this.$el)
            console.log('当前data状态:', this.$data)
            console.log('当前name状态:', this.name)
        },
        beforeUpdate() {
            console.log('beforeUpdate')
            console.log('当前el状态:', this.$el)
            console.log('当前data状态:', this.$data)
            console.log('当前name状态:', this.name)
        },
        updated() {
            console.log('updated')
            console.log('当前el状态:', this.$el)
            console.log('当前data状态:', this.$data)
            console.log('当前name状态:', this.name)
        },
        beforeDestroy() {
            console.log('beforeDestroy')
            console.log('当前el状态:', this.$el)
            console.log('当前data状态:', this.$data)
            console.log('当前name状态:', this.name)
            // 销毁定时器
            clearInterval(this.t)
            this.t = null
        },
        destroyed() {
            console.log('destroyed')
            console.log('当前el状态:', this.$el)
            console.log('当前data状态:', this.$data)
            console.log('当前name状态:', this.name)
        },


    })


    var vm = new Vue({
        el: '#app',
        data: {
            username: '',
            show: false
        },
        methods: {
            handleShow() {
                this.show = !this.show
            }
        }


        // beforeCreate() {
        //     console.log('beforeCreate')
        // },
        // created() {
        //     console.log('created')
        // },
        // beforeMount() {
        //     console.log('beforeMount')
        // },
        // mounted() {
        //     console.log('mounted')
        // },
        // beforeUpdate() {
        //     console.log('beforeUpdate')
        // },
        // updated() {
        //     console.log('updated')
        // },
        // beforeDestroy() {
        //     console.log('beforeDestroy')
        // },
        // destroyed() {
        //     console.log('destroyed')
        // },


    })
</script>
</html>

4.组件介绍和使用

# 组件就是:扩展 HTML 元素,封装可重用的代码,目的是复用
例如:有一个轮播图,可以在很多页面中使用,一个轮播有js,css,html
组件把js,css,html放到一起,有逻辑,有样式,有html


# 组件的分类:
    全局组件:可以放在根中,可以在所有组件中使用
    局部组件:只能在当前组件中使用
    
# 1 全局组件是使用Vue.component定义的,可以在全局任意组件中使用
# 2 局部组件是定义在某个组件内的:components,只能用在当前组件中
# 3 组件可以嵌套定义和使用

# 扩展:elementui,提供给咱们很多全局组件
<!--组件介绍和使用start-->
<div id="assembly">
    <h1>全局组件</h1>
    <queque></queque>
    <smallque></smallque>
</div>
<!--组件介绍和使用end-->
// 定义全局组件,vue2中,组件必须在一个标签中,可以多次使用,且相互隔离
Vue.component('queque', {
    template: `
      <div>
      <button @click="back">后退</button>
      {{ title }}
      <button @click="forward">前进</button>
      </div>`,
    data() {
        return {
            title: 'nbplus',
        }
    },
    methods: {
        back() {
            console.log('退了')
        },
        forward() {
            console.log('进了')
        },

    }
})
// 根组件
// 局部组件是定义在某个组件内,可以定义多个,只能在它父组件中使用,不能到别的地方使用
let vm3 = new Vue({
    el: '#assembly',
    components: {
        'smallque': {
            template: `
              <div>
              <h1>局部组件</h1>
              </div>`,
            data() {
                return {}
            },
            methods: {},
        }
    }
})
// 小结:可以用变量的形式来定义局部组件,同理全局也可以
// var smallque = {
//             template: `
//               <div>
//               <h1>局部组件</h1>
//               </div>`,
//             data() {
//                 return {}
//             },
//             methods: {},
//         }
// 全局 Vue.component('queque',smallque)
// 局部 let vm3 = new Vue({
//         el: '#assembly',
//         components: {smallque},})

5.组件间通信(父传子、子传父、ref、事件总线)

# 组件嵌套,
	-父组件把数据传递给子组件
    	-自定义属性
        -1 在父组件中自定义属性,使用属性指令绑定父组件的变量,可以写多个
        -2 在子组件中,使用props接受 ['属性名','属性名2']
        -3 在子组件中,使用属性名即可
    -子组件把数据传递给父组件
    	-自定义事件
        -1 父组件中自定义事件:<lqz @myevent="handelEvent"></lqz>
        -2 子组件中只要执行 this.$emit('myevent'),就会触发自定义事件对应的函数
<!--组件间通信start-->
<div id="dadnson">
    <h3>父传子</h3>
    <aque :link="url" @move="comecome"></aque>
    <h3>子传父</h3>
    <h4>从子组件接收到的数据是--->{{secret}}</h4>

</div>
<!--组件间通信end-->
var aque={template:'<div>\n' +
        '    <h6>局部组件的图片</h6>\n' +
        '    <img :src="link" alt="" style="height:300px">\n' +
        ' <input type="text" v-model="name"> <button @click="gogogo">数据去父组件</button></div>',data(){return{username:'',name:'', }},methods:{gogogo(){this.$emit('move',this.name)}},props:['link']}
let vm4 = new Vue({
    el:'#dadnson',
    data:{url:'https://img1.baidu.com/it/u=3982595127,2952567964&fm=253&app=138&size=w931&n=0&f=JPEG&fmt=auto?sec=1686243600&t=5817bff8182836b64f3fa271893b8c2f',
    secret:''},
    methods:{comecome(name){this.secret=name}},
    components: {aque}
})

6.ref属性

# ref属性,vue提供的,写在标签上
	可以写在普通标签:在vue中使用 this.$refs.名字  拿到原生dom对象,可以原生操作
    可以写在组件上:在vue中使用 this.$refs.名字  拿到[组件]对象,组件属性,方法直接使用即可
<!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>ref属性放在普通标签上</h1>
    <input type="text" v-model="username" ref="myinput">
    <br>
    <img src="http://pic.imeitou.com/uploads/allimg/230331/7-230331110I0.jpg" alt="" height="300px" ref="myimg">


    <h1>ref放在组件上</h1>
    <hr>
    <lqz ref="mylqz"></lqz>
    <hr>

    <button @click="handleClick">点我执行函数</button>

    <br>
    {{username}}

</div>
</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            username: ''
        },
        methods: {
            handleClick() {
                console.log(this.$refs)
                // 通过key,取到标签,拿到原生dom,通过dom操作,控制标签
                // this.$refs.myinput.value = 'lqz'
                // this.$refs.myimg.src='https://img2.woyaogexing.com/2021/09/22/3c686eb61fe34696840c478584b73d36!400x400.jpeg'

                // 放在组件上---》现在在父组件中,能拿到子组件对象,对象中的属性和方法直接用即可
                console.log(this.$refs.mylqz)
                // this.$refs.mylqz.title = 'sb'
                // this.username=this.$refs.mylqz.title
                this.$refs.mylqz.handleBack()


            }
        },
        components: {
            lqz: {
                template: `
                  <div>
                  <button @click="handleBack">后退</button>
                  {{ title }}
                  <button>前进</button>
                  </div>`,
                data() {
                    return {
                        title: "首页"
                    }
                },
                methods: {
                    handleBack() {
                        alert('后退了')
                    }
                }
            }
        }

    })
</script>
</html>

7.补充

# 以后前后端分离
  -前端是前端(小程序)
  -后端是后端,完全没联系
        -后端只写接口,没有template和static
    	-media 要有

8.作业

1 购物车使用计算属性,过滤案例使用计算属性

2 写一个books接口,带按价格排序,前端页面创建完成,向后端发送请求,获取图书属性,表格显示在前端
	前端使用监听属性实现点击价格正序和倒序排列

3 定义组件,组件创建成功,向后端发送请求,后端返回一张图片地址,显示在组件上
	-1 网络图片
    -2 media下的图片

4 在上面的子组件就中写一个按钮,点击按钮,把子组件的图片地址,传递到父组件中打印出来(alert)


# 补充:
	1 图片
    	在接口中返回一些数据和图片地址,而不是图片的二进制内容
      {code:100,msg:'成功',img:地址}
        
    2 md5 不是加密,  摘要算法
posted @ 2023-06-08 16:56  雀雀飞了  阅读(56)  评论(0编辑  收藏  举报