首页 > 其他分享 >Day04 - Vue的请求方式、计算属性、监听、ref

Day04 - Vue的请求方式、计算属性、监听、ref

时间:2023-09-22 12:46:49浏览次数:58  
标签:username el Vue console log data Day04 组件 ref

与后端交互的三种方式

// 后端接口写好了,前后端分离的项目,前端如何与后端进行交互?

前后端要打通----->从前端发送Ajax请求------>核心:使用JavaScript发送HTTP请求,接受返回的数据
	-使用原生JS,可以开启Ajax,但是使用原生JS,比较麻烦,需要做浏览器兼容,现在基本不使用
	-jQuery,写了个兼容所有的浏览器,$.ajax(),但是它里面不仅仅有Ajax还有一些dom操作,如果在Vue中使用不太合适
	-axios:第三方的Ajax包,可以使用
	-fetch:原生JS发送Ajax强求,有的浏览器也不兼容

后端

class UserInfo(ViewSetMixin, APIView):
    @action(methods=["GET"], detail=False)
    def user(self, request):
        response = Response({"username": "彭于晏", "age": "19"})
        response.headers = {"Access-Control-Allow-Origin": "*"}
        return response

使用jQuery的Ajax

<script>
    new Vue({
        el: "#app1",
        data: {
            username: "",
            age: "",
        },
        methods: {
            handeruserinfo() {
                let _this = this
                $.ajax({
                    url: "//127.0.0.1:8000/user/",
                    method: "get",
                    success: function (args) {
                        console.log(typeof args)
                        console.log(args)
                        _this.username = args.username
                        _this.age = args.age
                    }
                })
            }
        },
    })
</script>

使用fetch

handleLoad() {
    // 2 使用js原生的fetch(目前也不用)
    // fetch('http://127.0.0.1:5000').then(function (response) {
    //     // console.log(response)
    //     return response.json();
    // }).then(function (res) {
    //     console.log(res);
    // });
    // 了解,箭头函数一会讲
    fetch('http://127.0.0.1:5000').then(res=>res.json()).then(res=>{
        console.log(res)
    })

使用axios

// cdn 导入axios:<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script>
    new Vue({
    el: "#app1",
    data: {
        username: "",
        age: "",
    },
    methods: {
        handeruserinfo() {
            let _this = this

            axios.get("http://127.0.0.1:8000/user/").then(function (args) {
                console.log(args)
                _this.username = args.data.username
                _this.age = args.data.age
            })
        }
    },
})
</script>

计算属性

// 计算属性是基于他们所依赖的变量进行缓存的

// 计算属性只有在他们的相关依赖变量发生改变时才会重新求值,否则不会变,(函数是只要页面发生变化,就会重新运算)

// 计算属性就像python中的property一样, 将方法伪装成属性

// 计算属性必须要有返回值

计算属性要写在----->computed中

基础使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="icon" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="src/JS/Vue.js"></script>
    <script src="src/JS/jQuery.js"></script>
    <script src="src/bootstrap/js/bootstrap.min.js"></script>
    <script src="src/JS/axios.js"></script>
    <link rel="stylesheet" href="src/bootstrap/css/bootstrap.min.css">
    <script type="module" src="/src/main.js"></script>
    <title></title>
</head>

<body>
<div id="app1">
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <div class="text-center">
                    <h1>计算属性的基本使用</h1>
                    <p><input type="text" v-model="username">------>{{ cat_username() }}</p>
                    <!--                    当我使用插值语法进行插值的时候,我在password框中输入值的时候也会触发username这个函数的执行-->
                    <input type="text" v-model="password">------>{{ password }}

                    <h2>通过计算属性实现---->当属性使用</h2>
                    <input type="text" v-model="username1">----------》{{ get_username }}
                </div>
            </div>
        </div>
    </div>
</div>
</body>
<script>
    new Vue({
        el: "#app1",
        data: {
            username: "",
            password: "",
            username1: "",
        },
        methods: {
            cat_username() {
                console.log("我是username的函数我执行了")
                return this.username.substring(0, 1).toUpperCase() + this.username.substring(1)
            }
        },
        computed: {
            get_username() {
                console.log("我是计算属性,我执行了")
                return this.username1.substring(0, 1).toUpperCase() + this.username1.substring(1)
            }
        }
    })
</script>

</html>

重写过滤案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="icon" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="src/JS/Vue.js"></script>
    <script src="src/JS/jQuery.js"></script>
    <script src="src/bootstrap/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="src/bootstrap/css/bootstrap.min.css">
    <script type="module" src="/src/main.js"></script>
    <title></title>
</head>

<body>
<div id="app1">
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <div class="text-center">
                    <h1>过滤案例</h1>
                    <input type="text" v-model="myText">
                    <hr>
                    <ul>
                        <li v-for="item in handleInput">{{ item}}</li>
                    </ul>
                </div>
            </div>
        </div>
    </div>
</div>
</body>
<script>
    let vm = new Vue({
        el: "#app1",
        data: {
            myText: "",
            dataList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf', 'e', 'egg', 'agg'],

        },
        methods: {
        },
        computed: {
            handleInput(){
                return this.dataList.filter((item => item.indexOf(this.myText) >= 0))
            }
        }
    })
</script>

</html>

监听(侦听)属性

// 只要属性发生了变化,就会执行某个函数

这个函数要写在watch中

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="icon" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="src/JS/Vue.js"></script>
    <script src="src/JS/jQuery.js"></script>
    <script src="src/bootstrap/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="src/bootstrap/css/bootstrap.min.css">
    <script type="module" src="/src/main.js"></script>
    <title></title>
</head>

<body>
<div id="app1">
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <div class="text-center">
                    <h1>监听</h1>
                    <input type="text" v-model="username">-------{{ username }}
                </div>
            </div>
        </div>
    </div>
</div>
</body>
<script>
    new Vue({
        el: "#app1",
        data: {
            username: ""
        },
        methods: {},
        watch: {
            username(newValue, oldValue) {
                // 修改过后的值
                console.log(newValue)
                // 修改前的值
                console.log(oldValue)
                // 只要我的属性发生了变化,就会触发我这个函数的执行
                console.log("我执行了")
            }
        }
    })
</script>

</html>

Vue的生命周期

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

8个生命周期钩子函数:
beforeCreate	        创建Vue实例之前调用
created	                创建Vue实例成功后调用
beforeMount	            渲染DOM之前调用
mounted	                渲染DOM之后调用
beforeUpdate	        重新渲染之前调用(数据更新等操作时,控制DOM重新渲染)
updated	                重新渲染完成之后调用
beforeDestroy	        销毁之前调用
destroyed	            销毁之后调用
        
8个生命周期钩子,什么情况下会用得到?
    created:用的最多,变量初始化完成了(data中的数据),在这里,我们可以发送Ajax请求
beforDestroy:组件销毁之前会执行
    -组件创建,就会执行一个定时任务,[每隔15秒,打印一个HelloKitty]
    -组件销毁,定时任务被销毁,如果定时任务不被销毁就会一直执行
// 每一个钩子函数都是一个独立的函数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="icon" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="src/JS/Vue.js"></script>
    <script src="src/JS/jQuery.js"></script>
    <script src="src/bootstrap/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="src/bootstrap/css/bootstrap.min.css">
    <script type="module" src="/src/main.js"></script>
    <title></title>
</head>

<body>
<div id="app1">
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <div class="text-center">
                    <h1>Vue的生命周期</h1>
					// 当我input框的内容发生改变时就会触发updated的钩子函数
                    <input type="text" v-model="username">---------{{ username }}
                </div>
            </div>
        </div>
    </div>
</div>
</body>
<script>
    new Vue({
        el: "#app1",
        data: {
            username: ""
        },
        methods: {},
        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)
        },
    })
</script>

</html>

组件介绍和使用

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


// 组件的分类:
    全局组件:可以放在根中,可以在所有组件中使用
    局部组件:只能在当前组件中使用

定义一个全局组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="icon" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="src/JS/Vue.js"></script>
    <script src="src/JS/jQuery.js"></script>
    <script src="src/bootstrap/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="src/bootstrap/css/bootstrap.min.css">
    <script type="module" src="/src/main.js"></script>
    <title></title>
</head>

<body>
<div id="app1">
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <div class="text-center">
                    <h1>组件的使用</h1>
                </div>
            </div>
        </div>
    </div>
    <child></child>
</div>
</body>
<script>
    Vue.component("child", {
        template:
                `
                  <div>
                    <p><img src="img/测试图4.jpg" alt="" height="400px" width="400px"></p>
                    <button @click="come">前进</button>
                    {{ title }}
                    <button @click="go">后退</button>
                  </div>
                `,
        data() {
            return {
                title: "我是首页"
            }
        },
        methods: {
            come() {
                alert("我前进了")
            },
            go() {
                alert("我后退了")
            }
        }
    })
    new Vue({
        el: "#app1",
        data: {
            username: ""
        },
        methods: {},
    });
</script>

</html>

定义局部组件

// 要在Vue实例中的components里面定义组件,就是局部组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="icon" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="src/JS/Vue.js"></script>
    <script src="src/JS/jQuery.js"></script>
    <script src="src/bootstrap/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="src/bootstrap/css/bootstrap.min.css">
    <script type="module" src="/src/main.js"></script>
    <title></title>
</head>

<body>
<div id="app1">
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <div class="text-center">
                    <h1>组件的使用</h1>
                </div>
            </div>
        </div>
    </div>
    <child></child>
</div>
</body>
<script>
    let child = {
        template:
                `
                  <div>
                    <p><img :src="url" alt="" height="700px" width="700px"></p>
                    <button @click="come">前进</button>
                    {{ title }}
                    <button @click="go">后退</button>
                  </div>
                `,
        data() {
            return {
                title: "我是首页",
                url: "img/测试图2.jpg"
            }
        },
        methods: {
            come() {
                alert("我前进了")
            },
            go() {
                alert("我后退了")
            }
        }
    }

    new Vue({
        el: "#app1",
        data: {
            username: ""
        },
        methods: {},
        // 局部组件是定义在某个组件内,可以定义多个,只能在它父组件中使用,不能到别的地方使
        components: {
            child
        }
    });
</script>

</html>
// 全局组件是使用Vue.component定义的,可以在全局任意组件中使用

// 局部组件是定义在某个组件内:components,只能用在当前组件中

// 组件可以嵌套定义和使用

// 扩展:elementui,提供给咱们很多全局组件

组件之间的通信

// 组件嵌套
	-父组件把数据传递给子组件
		-自定义属性
			-1、在子组件中自定义属性,使用属性指令绑定父组件的变量、
             -2、在子组件中,使用props接收["属性名","属性名2"]
			-3、在子组件中,使用属性名即可
            
    -子组件把数据传递给父组件
		-自定义事件
			-1、父组件中自定义一个事件:<xxx @myevent="handelEvent"></xxx>
			-2、子组件只要执行 this.$emit('xxx'),就会触发自定义事件对应的函数

组件间通信父传子

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="icon" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="src/JS/Vue.js"></script>
    <script src="src/JS/jQuery.js"></script>
    <script src="src/bootstrap/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="src/bootstrap/css/bootstrap.min.css">
    <script type="module" src="/src/main.js"></script>
    <title></title>
</head>

<body>
<div id="app1">
    <h1>组件的使用</h1>
    <hr>
    <child :url="url"></child>
    <hr>
</div>
</body>
<script>
    let child = {
        template:
                `
                  <div>
                    <h2>这是局部组件</h2>
                    <p><img :src="url" alt="" height="700px" width="700px"></p>
                    <button @click="go">后退</button>
                  </div>
                `,
        data() {
            return {}
        },
        methods: {
            go() {
                alert("我后退了")
            }
        },
        props:["url"]
    }

    new Vue({
        el: "#app1",
        data: {
            url: "img/测试图2.jpg"
        },
        methods: {},
        components: {
            child
        }
    });
</script>

</html>

总结

我在根组件中的数据如何被我的子组件拿到?
1、先在我子组件的标签中自定义一个属性,然后再在我子组件中使用我这个自定义的属性,再在我子组件中使用props以数组的形式接收

组件间通信值子传父

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="icon" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="src/JS/Vue.js"></script>
    <script src="src/JS/jQuery.js"></script>
    <script src="src/bootstrap/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="src/bootstrap/css/bootstrap.min.css">
    <script type="module" src="/src/main.js"></script>
    <title></title>
</head>

<body>
<div id="app1">
    <h1>组件的使用</h1>
    接收到的子组件输入的内容是:{{ username}}
    <hr>
    <child @myclick="xxx"></child>
    <hr>
</div>
</body>
<script>
    let child = {
        template:
                `
                  <div>
                    <h2>这是局部组件</h2>
                    <input type="text" v-model="username">
                    <button @click="handersend">传递到父组件</button>
                  </div>
                `,
        data() {
            return {
                username: ""
            }
        },
        methods: {
            handersend() {
                console.log("jjjjjjjj")
                this.$emit('myclick', this.username)
            }
        },
    }

    new Vue({
        el: "#app1",
        data: {
            username: ""
        },
        methods: {
            xxx(username) {
                console.log("执行到了父组件")
                console.log(username)
                this.username = username
            }
        },
        components: {
            child
        }
    });
</script>

</html>

总结

1、需要在我子组件产生的标签中自定义一个事件:<child @myclick="xxx"></child>
2、在我子组件中绑定一个事件,当我子组件触发了事件,就会执行绑定方法里面的:this.$emit('myclick', this.username),一个是我自定义事件的名称,一个是我要传给父组件的数据
3、我在父组件中需要调用我自定义绑定事件的方法,接收一个参数,这个参数就是我子组件传给我父组件的参数:
    xxx(username) {
        console.log("执行到了父组件")
        console.log(username)
        this.username = username
    }

ref属性

ref属性,vue提供的,写在标签上
	可以写在普通标签:在vue中使用 this.$refs.名字  拿到dom对象,可以原生操作
    可以写在组件上:在vue中使用 this.$refs.名字  拿到[组件]对象,组件属性,方法直接使用即可
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="icon" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="src/JS/Vue.js"></script>
    <script src="src/JS/jQuery.js"></script>
    <script src="src/bootstrap/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="src/bootstrap/css/bootstrap.min.css">
    <script type="module" src="/src/main.js"></script>
    <title></title>
</head>

<body>
<div id="app">
    <h1>ref属性放在普通标签上</h1>
    <input type="text" v-model="username" ref="myinput">
    // 当我普通标签中有了ref这个特殊属性以后,就有不用再在data中放入我变量的值,也可以渲染出来饿了
    <br>
    <img src="img/测试图3.jpg" alt="" height="300px" ref="myimg">


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

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

    <br>
    {{ username }}

</div>
</body>
<script>
    let 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>

作业

1 上课讲的代码写一遍
	-购物车使用计算属性,过滤案例使用计算属性
2 写一个books接口,带按价格排序,前端页面创建完成,向后端发送请求,获取图书属性,表格显示在前端
	前端使用监听属性实现点击价格正序和倒序排列
3 定义组件,组件创建成功,向后端发送请求,后端返回一张图片地址,显示在组件上
	-1 网络图片
    -2 media下的图片

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

标签:username,el,Vue,console,log,data,Day04,组件,ref
From: https://www.cnblogs.com/chao0308/p/17722007.html

相关文章

  • Day03 - Vue语法使用
    JS循环方式JS循环方式//方式一:js循环----->for()------>基于索引的循环leti=0for(;i<10;){console.log(i)i++}letlist=[1,2,3,4,5,6,7,8]for(letj=0;j<list.length;j++){console.log(lis......
  • Day02 - Vue 基础知识
    模版语法<body><divid="app1"><h1>模版语法</h1><p>渲染字符串,------姓名:{{name}}</p><p>渲染字符串,------年龄:{{age}}</p><p>渲染数组类型,------>:{{list1}}</p><p>渲染数组类型按照索引取值......
  • Day01 - Vue介绍
    前端介绍1HTML(5)、CSS(3)、JavaScript(ES5、ES6、ES11):编写一个个的页面->给后端(PHP、Python、Go、Java)->后端嵌入模板语法->后端渲染完数据->返回数据给前端->在浏览器中查看2Ajax的出现->后台发送异步请求,Render+Ajax混合3单用Ajax(加载数据,DOM渲染页面):......
  • Day06 - Vue项目的使用
    解析Vue项目//1为什么浏览器中访问某个地址,会显示某个页面组件 -根组件:App.Vue必须是:<template><divid="app"><router-view></router-view></div></template> -配置路由: //先导入 importy......
  • Day05 - Vue之动态组件、插槽、项目的创建
    动态组件//关键字: component//使用方法:<component:is="who"></component>//component标签的is属性等于组件名字,这里就会显示这个组件<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><link......
  • Vue中qs的使用
    1、qs是什么qs是一个增加了一些安全性的查询字符串解析和序列化字符串的库。可以进行对象与字符串之间的一个转换。2、qs安装qs,是axios中自带的,也是npm仓库所管理的包。安装方式:npminstallqsVue项目导入:importqsfrom'qs'Vue项目中的main.js中设置全局属性的方式:Vue......
  • 已解决local variable ‘str‘ referenced before assignment
    已解决localvariable‘str’referencedbeforeassignment文章目录报错问题解决方法声明报错问题之前在工作中遇到过这个坑,记录一下问题以及解决方法,不一定针对所有情况都能用,但是可以供大家参考。问题描述如下:localvariable‘str’referencedbeforeassignment局部变量......
  • VUE中的data(){return}与data:{}区别
    组件是一个可复用的实例,当你引用一个组件的时候,组件里的data是一个普通的对象,所有用到这个组件的都引用的同一个data,就会造成数据污染。data:{}data:{msg:0}使用return包裹后数据中变量只在当前组件中生效,不会影响其他组件。data(){return}data(){......
  • vue3 父子组件通信 setup
    父传子father<template><div><h2>父传子Father</h2><!--<buttonclass="bg-green-300roundedp-1">父按钮</button>--><divclass="w-[200px]h-[200px]bg-violet-200">......
  • VUE3+vite+arco design 项目初始化
    意见反馈系统总结创建项目首先选择一个文件夹进入命令窗口使用vite创建项目npmcreatevite@latest初始化项目后进入项目安装依赖npminstall运行npmrundev使用arcodesign组件库安装npminstall--save-dev@arco-design/web-vue引入import{createApp}fr......