Vue 学习(一)


一、认识Vuejs

1.1 Vue是一个渐进式的框架。

1.1.1 渐进式:

渐进式意味着你可以将Vue作为你应用的一部分嵌入其中,带来更丰富的交互体验。
或者如果你希望将更多的业务逻辑使用Vue实现,那么Vue的核心库以及其生态系统。
比如Core+Vue-router+Vuex,也可以满足你各种各样的需求。

1.2 第一个Vue实例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app"></div>
<script src="../js/vue.js"></script>
<script>
    //let(变量)/const(常量)
    //编程范式:声明式编程
    const app = new Vue({
        el: '#app',//用于挂载要管理的元素
        data: {//定义数据
            message: '你好!'
        }
    })
    //元素js的做法(编程范式:命令式编程)
    //1.创建div元素,设置id属性
    //2.定义一个message变量
    //3.将message变量放在前面的div元素中显示
    //4.修改message数据,并替换
</script>
</body>
</html>

1.3 第二个Vue实例-列表

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <ul>
        <li v-for="item in movies"></li>
    </ul>
</div>
<script src="../js/vue.js"></script>
<script>
    const app = new Vue({
        el: '#app',
        data: {
            messages: '你好啊',
            movies: ['魔界契约', '海王', '哪吒', '盗墓笔记']
        }
    })

</script>
</body>
</html>

1.4 第三个Vue实例-计数器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <h2>当前计数:</h2>
    <!--    v-on监听-->
    <!--    <button v-on:click="counter++">+</button>-->
    <!--    <button v-on:click="counter&#45;&#45;">-</button>-->
    <button v-on:click="add">+</button>
    <button @click="sub">-</button>
</div>
<script src="../js/vue.js"></script>
<script>
    //语法糖:简写 @click是v-on:click的语法糖
    const app = new Vue({
        el: '#app',
        data: {
            counter: '0'
        },
        methods: {
            add: function () {
                console.log('add被执行')
                this.counter++
            },
            sub: function () {
                console.log('sub被执行')
                this.counter--
            }
        }
    })

</script>
</body>
</html>

1.5 MVVM

Model View ViewModel

    View层:
  • 视图层
  • 在我们前端开发中,通常就是DOM层。
  • 主要的作用是给用户展示各种信息。
    Model层:
  • 数据层
  • 数据可能是我们固定的死数据,更多的是来自我们服务器,从网络上请求下来的数据。
  • 在我们计数器的案例中,就是后面抽取出来的obj,当然,里面的数据可能没有这么简单。
    VueModel层:
  • 视图模型层
  • 视图模型层是View和Model沟通的桥梁。
  • 一方面它实现了Data Binding,也就是数据绑定,将Model的改变实时的反应到View中
  • 另一方面它实现了DOM Listener,也就是DOM监听,当DOM发生一些事件(点击、滚动、touch等)时,可以监听到,并在需要的情况下改变对应的Data。

1.6 开发中什么是函数,什么是方法?

  • 函数:function,直接在script里面定义
  • 方法:method,一般定义在类里面
  • 1.7 vue的生命周期

    初始化->更新->死亡

    1.8 模板语法

    1.8.1 Mustache语法(双括号):可以使用简单的表达式

    1.8.2 v-once:只渲染一次,之后不会随数据更改,并且后面不跟表达式

    1.8.3 v-html:设置有标签的超链接

    1.8.4 v-text:类似于Mustache语法,但不可拼接,使用较少

    1.8.5 v-pre:原封不动的显示标签内的内容,不用解析

    1.8.6 v-cloak:在vue解析之前有效,避免显然出未编译的Mustache标签

    1.8.7 v-bind:

  • 动态绑定链接属性
  • 语法糖:':'
  • 动态绑定class可使用对象、数组绑定
  • 动态绑定style可使用对象、数组绑定
  • 1.9 计算属性

    1.9.1 计算属性的定义:

    把数据进行一些转化后再显示,或者把多个数据结合起来进行显示

    1.9.2 计算属性的案例:

    案例一:firstName+lastName
    案例二:books->price
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>计算属性复杂操作</title>
    </head>
    <body>
    <div id="app">
        <h2>总价格:</h2>
    </div>
    <script src="../js/vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                books: [
                    {id: 110, name: 'Vue框架', price: 120},
                    {id: 111, name: '一行代码', price: 69},
                    {id: 112, name: '操作系统', price: 100},
                    {id: 113, name: '代码大全', price: 70}
                ]
            },
            //computed计算属性
            computed: {
                totalPrice: function () {
                    let result = 0
                    for (let i = 0; i < this.books.length; i++) {
                        result += this.books[i].price
                    }
                    return result
                }
            },
            methods: {}
        })
    </script>
    </body>
    </html>
    计算属性完整写法:
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                firstName: 'jerry',
                lastName: 'tom'
            },
            //computed计算属性
            // 属性一般没有set方法,只读属性
            computed: {
                fullName: {
                    set: function (newValue) {
                        // 截取拿到结果的字符串并赋值
                        const name = newValue.split(' ')
                        this.firstName = name[0]
                        this.lastName = name[1]
                    },
                    get: function () {
                        return this.firstName+' '+this.lastName
                    }
                }
            },
            methods: {}
        })
    </script>

    1.9.3 计算属性的缓存:

    计算属性性能比方法更高,因为计算属性有缓存,执行时只调用一次,而方法用几次调用几次

    1.10 事件监听

    1.10.1 v-on

    定义:绑定事件监听器,语法糖为'@监听事件'

    1.10.2 v-on参数问题

  • 情况一:如果该方法不需要额外参数,那么方法后的()可以不添加。
  • 但是注意:如果方法本身中有一个参数,那么会默认将原生事件event参数传递进去
  • 情况二:如果需要同时传入某个参数,同时需要event时,可以通过$event传入事件。
  • 1.10.3 v-on修饰符

  • .stop:阻止冒泡
  • .prevent:阻止默认事件,如自动提交
  • .{keyCode | keyAlias}:监听某个键盘按键的点击,如:‘input type="text" v-on:keyup.enter="keyUp"(点击enter键,松开时触发)’
  • .native:监听组件根元素的原生事件。
  • .once:只触发一次回调。
  • 1.10.4 v-if和v-show区别

    v-if当条件为false时,压根不会有对应的元素在DOM中。
    v-show当条件为false时,仅仅是将元素的display属性设置为none而已。
    当需要在显示与隐藏之间切片很频繁时,使用v-show
    当只有一次切换时,通过使用v-if

    1.10.5 遍历循环

    使用v-for时最好加上key,为了更好的复用
    1.10.5.1 遍历数组
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>v-for遍历数组</title>
    </head>
    <body>
    <div id="app">
        <!--    1.在遍历的过程中,没有使用索引值-->
        <ul>
            <li v-for="item in names"></li>
        </ul>
        <!--    2.在遍历的过程中,获取索引值-->
        <ul>
            <li v-for="(item,index) in names">NaN.</li>
        </ul>
    </div>
    <script src="../js/vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                names: ['why', 'Mois', 'Tom', 'Jerry']
            }
        })
    </script>
    </body>
    </html>
    1.10.5.2 遍历对象
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>v-for遍历对象</title>
    </head>
    <body>
    <div id="app">
        <!--    1.在遍历的过程中,如果只是获取一个值,那么获取的是value-->
        <ul>
            <li v-for="item in info"></li>
        </ul>
        <!--    2.获取key和value (value,key)-->
        <ul>
            <li v-for="(item,key) in info">:</li>
        </ul>
    <!--    3.获取key、value和index-->
        <ul>
            <li v-for="(item,key,index) in info">:-</li>
        </ul>
    </div>
    <script src="../js/vue.js"></script>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                info: {
                    name: 'Mois',
                    age: 20,
                    height: 1.88
                }
            }
        })
    </script>
    </body>
    </html>
    1.10.5.3 v-for中最好加入key,但key不能是index(index会有变化)

    1.10.6 响应方法

    观察数组编译的方法,使用它们改变数组也会触发视图的更新。
  • push():在数组后面添加元素,可添加多个
  • pop():删除最后一个元素
  • shift():删除第一个元素
  • unshift():在数组最前面添加元素,可添加多个
  • splice():删除元素、插入元素、替换元素
  • 删除元素,splice(开始位置,删除几个元素),
    删除元素splice(开始位置),删除除开始位置后的元素
    替换元素,splice(start,替换几个元素,‘替换的元素’,‘替换的元素’)
    插入元素,splice(开始元素,0,‘插入的元素’,‘插入的元素’)
  • sort():排序
  • reverse():反转
  • set():添加元素,set(添加位置,添加变量名字,添加变量内容)
  • 1.11 书籍购物车的案例

    index.html
    <!DOCTYPE html>
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
    <div id="app">
        <div v-if="books.length">
            <table>
                <thead>
                <tr>
                    <th></th>
                    <th>书籍名称</th>
                    <th>出版日期</th>
                    <th>价格</th>
                    <th>购买数量</th>
                    <th>操作</th>
                </tr>
                </thead>
                <tbody>
                <tr v-for="(book,index) in books">
                    <td>book.id</td>
                    <td>book.name</td>
                    <td>book.data</td>
                    <td>book.price|showPrice</td>
                    <td>
                        <button @click="decrement(index)" v-bind:disabled="book.count<=1">-</button>
                        <button @click="increment(index)">+</button>
                    </td>
                    <td>
                        <button @click="removeHandler(index)">移除</button>
                    </td>
                </tr>
                </tbody>
            </table>
            <h2>总价格:totalPrice|showPrice</h2>
        </div>
        <div v-else>
            <h2>购物车为空</h2>
        </div>
    </div>
    <script src="../js/vue.js"></script>
    <script src="main.js"></script>
    <script>
    
    </script>
    </body>
    </html>

    main.js
    const app = new Vue({
        el: '#app',
        data: {
            books: [
                {
                    id: 1,
                    name: '《算法导论》',
                    data: '2019-03-12',
                    price: 89.00,
                    count: 1
                },
                {
                    id: 2,
                    name: '《UNIX编程艺术》',
                    data: '2018-07-13',
                    price: 49.00,
                    count: 5
                },
                {
                    id: 3,
                    name: '《编程珠玑》',
                    data: '2020-01-12',
                    price: 85.00,
                    count: 11
                },
                {
                    id: 4,
                    name: '《代码大全》',
                    data: '2020-03-22',
                    price: 109.00,
                    count: 2
                },
            ]
        },
        methods: {
            //价格格式化
            getFinalPrice(price) {
                return '¥' + price.toFixed(2)
            },
            increment(index) {
                this.books[index].count++
            },
            decrement(index) {
                this.books[index].count--
            },
            removeHandler(index) {
                this.books.splice(index, 1)
            }
        },
        // 计算属性
        computed: {
            totalPrice() {
                let totalPrice = 0
                //1.普通for循环
                for (let i = 0; i < this.books.length; i++) {
                    totalPrice += this.books[i].price * this.books[i].count
                }
                return totalPrice
                // 2.for(let i in this.books)
                //3.for(let i in/of this.books)
            }
        },
        //过滤器
        filters: {
            showPrice(price) {
                return '¥' + price.toFixed(2)
            }
        }
    })

    style.css
    table {
        border: 1px solid #e9e9e9;
        border-collapse: collapse;
        border-spacing: 0;
    }
    
    th, td {
        padding: 8px 16px;
        border: 1px solid #e9e9e9;
        text-align: left;
    }
    
    th {
        background-color: #f7f7f7;
        color: #5c6b77;
        font-weight: 600;
    }

    文章作者: Mois
    版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Mois !
      目录