vue3基础------ 下

目录

二.vue3基础

5.事件处理器

5-1 事件处理器 - 告别原生事件

5-2 事件修饰符 - 事件偷懒符?

6.表单控件绑定

6-1表单输入绑定-一根绳上的蚂蚱

 6-2购物车案例

6-3表单修饰符

7.计算属性

7-1计算属性-很聪明,会缓存

7-2 可写计算属性

7-3之前案例的小改造 

7-4侦听器watch的对比

7-5深层侦听器

8.数据请求

8-1Fetch

8-2 axios

9.过滤器

9-1vue3过滤器不支持了-怎么办?


二.vue3基础

5.事件处理器


5-1 事件处理器 - 告别原生事件

内联事件处理器

<button @click="count++">Add 1</button>
<button @click="test('hello',$event)">test hello</button>

方法事件处理器

<button @click="test">test</button>
<button @click="(e)=>test(e)">test hello</button>

5-2 事件修饰符 - 事件偷懒符?

Vue为v-on提供了事件修饰符。修饰符是用.表示的指令后缀,包含以下这些:

  • .stop 阻止冒泡
  • .prevent 阻止默认行为
  • .self 只有点击自己才触发
  • .capture 捕获阶段触发
  • .once 只触发一次
  • .passive

 按键修饰符

Vue为一些常用的按键提供了别名:

  • .enter
  • .tab
  • .delete(捕获“Delete”和“Backspace”两个按键)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right
<body>
    <div id="app">
        <ul @click.self="handleUlClick">
            <li @click.stop="test">111</li>
            <li @click="test2">22</li>
        </ul>
        <input type="text" @keyup.a='test2'>
        <input type="text" @keyup.enter.ctrl='test2'>
    </div>
</body>
<script>
    const { createApp } = Vue
    let obj = {
        data() {
            return {

            }
        },
        methods: {
            test2() {
                console.log(222);
            },
            test() {
                console.log(11);
            },
            handleUlClick() {
                console.log('ul');
            }
        }

    }
    createApp(obj).mount('#app')

6.表单控件绑定

6-1表单输入绑定-一根绳上的蚂蚱

普通文本

<input v-model="message" placeholder="editme" />

复选框

        <input type="checkbox" id="checkbox" v-model="checked" />

单选框

 <div>Picked:{
   
   { picked }}</div>
 <input type="radio" id="one" value="One" v-model="picked" /

选择器

    <div id="app">
        <div>Selected: {
   
   { selected }}</div>
        <select v-model="selected">
            <option disabled value="">Please select one</option>
            <option value="a">A</option>
            <option>B</option>
            <option>C</option>
        </select>
    </div>

 6-2购物车案例

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<style>
    li {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 10px;
        border: 1px solid lightgray;
    }

    li img {
        width: 100px;
    }
</style>

<body>
    <div id="app">

        <ul>
            <li>
                <div>
                    <input type="checkbox" v-model="isAllChecked" @change="handleAllChange">
                    <span>全选/全不选</span>
                </div>
            </li>
            <template v-if="datalist.length">
                <li v-for='item in datalist' :key='item.id'>
                    <div>
                        <input type="checkbox" v-model="checkList" :value="item" @change="handleItemChange">
                    </div>
                    <div>
                        <img :src="item.poster">
                    </div>
                    <div>
                        <div>{
   
   {item.title}}</div>
                        <div style="color:red;">价格:{
   
   {item.price}}</div>
                    </div>
                    <div>
                        <!-- 虽然操作的是datalist.item  但是 checkList的item存放的是datalist的引用 所有sum函数会执行-->
                        <button @click="item.number--" :disabled="item.number===1">-</button>
                        {
   
   {item.number}}
                        <button @click="item.number++" :disabled="item.number===item.limit">+</button>
                    </div>
                    <div>
                        <button @click="handleDel(index,item.id)">删除</button>
                    </div>
                </li>
            </template>
            <li v-else>购物车空空如也</li>
            <li>
                <!-- checkList 变化 sum函数就会执行 -->
                <div>总金额:{
   
   { sum()}}</div>
            </li>

        </ul>
    </div>
</body>
<script>
    const { createApp } = Vue
    let obj = {
        data() {
            return {
                isAllChecked: false,
                checkList: [],//勾选的商品列表
                datalist: [{
                    id: 1,
                    title: "商品1",
                    price: 10,
                    number: 1,
                    poster: "https://p0.meituan.net/movie/dc2fed6001e809e4553f90cc6fad9a59245170.jpg@1l_1e_1c_128w_180h",
                    limit: 5
                },
                {
                    id: 2,
                    title: "商品2",
                    price: 20,
                    number: 2,
                    poster: "https://p0.meituan.net/moviemachine/3084e88f63eef2c6a0df576153a3fad0327782.jpg@1l_1e_1c_128w_180h",
                    limit: 6
                },
                {
                    id: 3,
                    title: "商品3",
                    price: 30,
                    number: 3,
                    poster: "https://p0.meituan.net/movie/897b8364755949226995144bfc2261ee4493381.jpg@1l_1e_1c_128w_180h",
                    limit: 7
                }
                ]
            }


        },
        methods: {
            sum() {
                // var total = 0
                // for(var i=0;i<this.checkList.length;i++){
                //     total+=this.checkList[i].number*this.checkList[i].price
                // }

                // return total

                //reduce

                return this.checkList.reduce((total, item) => total + item.price * item.number, 0)
            },
            //处理删除
            handleDel(index, id) {
                this.datalist.splice(index, 1)
                //同步更新checklist
                this.checkList = this.checkList.filter(item => item.id !== id)

                //同步全选
                this.handleItemChange()
            },
            handleAllChange() {
                this.checkList = this.isAllChecked ? this.datalist : []
            },
            handleItemChange() {
                if (this.datalist.length === 0) {
                    this.isAllChecked = false
                    return
                }
                this.isAllChecked = this.checkList.length === this.datalist.length
            }
        }
    }
    createApp(obj).mount('#app')
</script>

</html>

6-3表单修饰符

.lazy   

change事件 数据发生变化 并失去焦点触发

    <!--在"change"事件后同步更新而不是"input"-->
    <input v-model.lazy="msg" />

.number

用户输入自动转换为数字,你可以在v-model后添加.number修饰符来管理输入:

    <input v-model.number="age" />

.trim

默认自动去除用户输入内容中两端的空格,你可以在v-model后添加.trim修饰符:

    <input v-model.trim="msg" />

7.计算属性

7-1计算属性-很聪明,会缓存

模板中的表达式虽然方便,但也只能用来做简单的操作。如果在模板中写太多逻辑,会让模板变得臃肿,难以维护。因此我们推荐使用计算属性来描述依赖响应式状态的复杂逻辑。

<script>

    const { createApp } = Vue
    let obj = {
        data() {
            return {
                books: [
                    'Vue 2 - Advanced Guide',
                    'Vue 3 - Basic Guide',
                    'Vue 4 - The Mystery'
                ]
            }
        },
        computed: {
            publishedBooksMessage() {
                return this.books.length > 0 ? 'Yes' : 'No'
            }

        }

    }
    createApp(obj).mount('#app')
</script>

若我们将同样的函数定义为一个方法而不是计算属性,两种方式在结果上确实是完全相同的,然而,不同之处在于计算属性值会基于其响应式依赖被缓存。一个计算属性仅会在其响应式依赖更新时才重新计算。

7-2 可写计算属性

计算属性默认是只读的。当你尝试修改一个计算属性时,你会收到一个运行时警告。只在某些特殊场景中你可能才需要用到“可写”的属性,你可以通过同时提供 getter 和 setter 来创建:


<script>

    const { createApp } = Vue
    let obj = {
        data() {
            return {
                "myname": "kerwin",
                "year": 2023,
                "month": 12,
                "day": 31
            }
        },

        computed: {
            compuntedDate: {
                get() {
                    return this.year + "-" + this.month + "-" + this.day
                },
                set(value) {
                    // console.log(value.split("-"))
                    // this.year = value.split("-")[0]
                    // this.month = value.split("-")[1]
                    // this.day = value.split("-")[2]

                    [this.year, this.month, this.day] = value.split("-")
                }
            },
        }

    }
    let app = createApp(obj).mount('#app')
</script>

7-3之前案例的小改造 

   computed:{
                isAllChecked:{
                    get(){
                        return this.checkList.length ===this.datalist.length
                    },
                    set(checked){
                        // console.log(value)
                        this.checkList = checked?this.datalist:[]
                    }
                },

注意: 

(1)Getter不应有副作用

计算属性的getter应只做计算而没有任何其他的副作用,这一点非常重要,请务必牢记。举例来说,不要在getter中做异步请求或者更改DOM!

(2)避免直接修改计算属性值

从计算属性返回的值是派生状态。可以把它看作是一个“临时快照”,每当源状态发生变化时,就会创建一个新的快照。更改快照是没有意义的,因此计算属性的返回值应该被视为只读的,并且永远不应该被更改——应该更新它所依赖的源状态以触发新的计算。

7-4侦听器watch的对比

watch选项期望接受一个对象,其中键是需要侦听的响应式组件实例属性(例如,通过data或computed声明的属性)——值是相应的回调函数。该回调函数接受被侦听源的新值和旧值。

 computed&& watch

计算属性允许我们声明性地计算衍生值。然而在有些情况下,我们需要在状态变化时执行一些“副作用”:例如更改 DOM,或是根据异步操作的结果去修改另一处的状态。

fetch函数返回一个Promise对象,可以使用.then()方法来处理成功的响应,使用.catch()方法来处理错误。在成功的响应处理函数中,可以通过response.json()方法获取响应体的JSON数据。 

<body>
    <div id="app">
        <p>
            Ask a yes/no question:
            <input v-model="question" />
        </p>
        <p>{
   
   { answer }}</p>
    </div>
</body>
<script>
    const { createApp } = Vue
    let obj = {
        data() {
            return {
                question: '',
                answer: 'Questions usually contain a question mark. ;-)'
            }
        },
        watch: {
            // 每当 question 改变时,这个函数就会执行
            question(newQuestion, oldQuestion) {
                if (newQuestion.includes('?')) {
                    this.getAnswer()
                }
            }
        },
        methods: {
            async getAnswer() {
                this.answer = 'Thinking...'
                try {
                    const res = await fetch('https://yesno.wtf/api')
                    console.log(res);
                    this.answer = await (res.json()).answer
                } catch (error) {
                    this.answer = 'Error! Could not reach the API. ' + error
                }
            }
        }
    }
    createApp(obj).mount('#app')
</script>

7-5深层侦听器

watch 默认是浅层的:被侦听的属性,仅在被赋新值时,才会触发回调函数——而嵌套属性的变化不会触发。如果想侦听所有嵌套的变更,你需要深层侦听器:

watch 默认是懒执行的:仅当数据源变化时,才会执行回调。但在某些场景中,我们希望在创建侦听器时,立即执行一遍回调。举例来说,我们想请求一些初始数据,然后在相关状态更改时重新请求数据。

我们可以用一个对象来声明侦听器,这个对象有 handler 方法和 immediate: true 选项,这样便能强制回调函数立即执行:

<body>
    <div id="box">
        <input type="text" v-model="mytext">
        <select v-model="obj.year">
            <option value="2021">2021</option>
            <option value="2022">2022</option>
            <option value="2023">2023</option>
            <option value="2024">2024</option>
        </select>
        <select v-model="obj.month">
            <option value="10">10</option>
            <option value="11">11</option>
            <option value="12">12</option>
        </select>
        <select v-model="obj.day">
            <option value="31">31</option>
            <option value="1">1</option>
            <option value="2">2</option>
        </select>
    </div>

    <script>
        var obj = {
            data() {
                return {
                    mytext: "",
                    obj: {
                        year: 2023,
                        month: 12,
                        day: 31
                    }
                }
            },

            watch: {
                // mytext:function(){}
                mytext: "anyfunc",
                // "obj.year":"anyfunc",
                // "obj.month":"anyfunc",
                // "obj.day":"anyfunc"

                obj: {
                    handler(value) {
                        console.log(value, "ajax")
                    },
                    deep: true,//复杂对象进行深度监听
                    immediate: true
                }
            },
            methods: {
                anyfunc(value, oldvalue) {
                    console.log(value)

                }
            }
        }
        Vue.createApp(obj).mount("#box")
    </script>
</body>

8.数据请求

8-1Fetch

XMLHttpRequest是一个设计粗糙的API,配置和调用方式非常混乱,而且基于事件的异步模型写起来不友好。兼容性不好

https://github.com/camsong/fetch-ie8

 fetch函数返回一个Promise对象,可以使用.then()方法来处理成功的响应,使用.catch()方法来处理错误。在成功的响应处理函数中,可以通过response.json()方法获取响应体的JSON数据。

response.text()方法获取相应主体文本形式

    <div id="box">
       <button @click="handleClick">click</button>

       <ul>
        <li v-for="item in datalist">
            {
   
   {item.name}}-{
   
   {item.age}}
        </li>
       </ul>
    </div>
    <script>
      
        var obj = {
            data() {
               return {
                 datalist:[]
               }
            },
            methods:{
                handleClick(){
                    //基于promise 
                    // fetch("http://localhost:3000/list")
                    // .then(res=>res.json() )
                    // .then(res=>{
                    //     console.log(res)
                    //     this.datalist = res
                    // })

                    // fetch("http://localhost:3000/list",{
                    //     method:"post",//post ,POST
                    //     headers:{
                    //         "content-type":"application/x-www-form-urlencoded",
                        
                    //     },
                    //     body:"name=xiaoming&age=19"
                    // }).then(res=>res.json())
                    // .then(res=>{
                    //     console.log(res)
                    // })

                    // fetch("http://localhost:3000/list",{
                    //     method:"post",//post ,POST
                    //     headers:{
                    //         "content-type":"application/json",
                        
                    //     },
                    //     body:JSON.stringify({
                    //         name:"gandaner",
                    //         age:20
                    //     })
                    // }).then(res=>res.json())
                    // .then(res=>{
                    //     console.log(res)
                    // })

                    // fetch("http://localhost:3000/list/5",{
                    //     method:"put",//post ,POST
                    //     headers:{
                    //         "content-type":"application/json",
                        
                    //     },
                    //     body:JSON.stringify({
                    //         name:"gandaner1111",
                    //         age:200
                    //     })
                    // }).then(res=>res.json())
                    // .then(res=>{
                    //     console.log(res)
                    // })

                    fetch("http://localhost:3000/list/5",{
                        method:"delete",//post ,POST
                    }).then(res=>res.json())
                    .then(res=>{
                        console.log(res)
                    })
                }
            }
        }
        var app = Vue.createApp(obj).mount("#box")
    </script>

8-2 axios

Axios是一个基于promise的HTTP库,可以用在浏览器和node.js中。

axios - npm

<body>
    <div id="box">
       <button @click="handleClick">click</button>

       <ul>
        <li v-for="item in datalist">
            {
   
   {item.name}}-{
   
   {item.age}}
        </li>
       </ul>
    </div>
    <script>
      
        var obj = {
            data() {
               return {
                 datalist:[]
               }
            },
            methods:{
                handleClick(){
                //    console.log(axios)
                //get
                    // axios.get("http://localhost:3000/list").then(res=>{
                    //     console.log(res.data)

                    //     this.datalist = res.data
                    // }).catch(err=>{
                    //     console.log(err)
                    // })
                //post-json
                    // axios.post("http://localhost:3000/list",{
                    //     name:"gangdaner",
                    //     age:20
                    // }).then(res=>{
                    //     console.log(res.data)
                    // }).catch(err=>{
                    //     console.log(err)
                    // })
                 //post-form
                    // axios.post("http://localhost:3000/list","name=zhugeshanzhen&age=30").then(res=>{
                    //     console.log(res.data)
                    // }).catch(err=>{
                    //     console.log(err)
                    // })
                //put
                // axios.put("http://localhost:3000/list/6","name=zhugeshanzhen111&age=300").then(res=>{
                //         console.log(res.data)
                //     }).catch(err=>{
                //         console.log(err)
                //     })
                //delete
                // axios.delete("http://localhost:3000/list/6").then(res=>{
                //         console.log(res.data)
                //     }).catch(err=>{
                //         console.log(err)
                //     })

                    axios({
                        // header:{

                        // }
                        method:"delete",
                        url:"http://localhost:3000/list/5",
                        // data:{
                        //     "name": "gangdaner111",
                        //     "age": 200,
                        // }
                    }).then(res=>{
                        console.log(res)
                    })
                }
            }
        }
        var app = Vue.createApp(obj).mount("#box")
    </script>
</body>

9.过滤器

9-1vue3过滤器不支持了-怎么办?

在2.x中,开发者可以使用过滤器来处理通用文本格式。 

<body>
    <div id="box">
       <!-- {
   
   {myname}} -->
        {
   
   {mydate | mydatefilter}}
    </div>
    <script>
      
        var obj = {
            el:"#box", //element
            data() {
               return {
                myname:"kerwin",
                mydate:1679458576574
               }
            },

            filters:{
                mydatefilter(timestamp){
                    // console.log(timestamp)
                    var mydate = new Date(timestamp)
                    return mydate.getFullYear()+"-"+(mydate.getMonth()+1)
                }
            }
            
        }
        // var app = Vue.createApp(obj)
        // .mount("#box")


        new Vue(obj)
    </script>
</body>

虽然这看起来很方便,但它需要一个自定义语法,打破了大括号内的表达式“只是JavaScript”的假设,这不仅有学习成本,而且有实现成本。在3.x中,过滤器已移除,且不再支持。取而代之的是,我们建议用方法调用或计算属性来替换它们。

<body>
    <div id="box">
        {
   
   {mydatefilter(mydate)}}
    </div>
    <script>

        var obj = {

            data() {
                return {

                    mydate: 1679458576574
                }
            },

            methods: {
                mydatefilter(timestamp) {
                    // console.log(timestamp)
                    var mydate = new Date(timestamp)
                    return mydate.getFullYear() + "-" + (mydate.getMonth() + 1)
                }
            }

        }
        var app = Vue.createApp(obj)
            .mount("#box")


    </script>
</body>

猜你喜欢

转载自blog.csdn.net/qq_63358859/article/details/131348685
今日推荐