Vue基础

Vue快速使用

编辑器选择

只要能编写html的编辑器都可以。

引入

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

快速使用

在js中创建vue对象:

<script>
    // 新建vue对象
    const vm = new Vue({
        el: '#app', //  键名称固定,值为选择器,#app即id为app的标签
        data: { //  键名称固定,值为各种变量
            name: 'tom',
            age: '18'
        }
    })
</script>

使用模板语法:

<div id="app">
    <!-- name,age为vue对象data中的变量 -->
    <p>我的名字是:{{ name }}</p>
    <p>我的年龄是:{{ age }}</p>
</div>
<script>
    // 新建vue对象
    const vm = new Vue({
        el: '#app', //  键名称固定,值为选择器,#app即id为app的标签
        data: { //  键名称固定,值为各种变量
            name: 'tom',
            age: '18'
        }
    })
</script>

image

模板语法之插值

基本插值

vue对象的data键中可以放各种变量:

<script>
    // 新建vue对象
    const vm = new Vue({
        el: '#app',
        data: { 
            name: 'tom',
            age: '18'
        }
    })
</script>

模板语法插值(根据变量名):

<div id="app">
    <p>字符串:{{ name }}</p>
    <p>数值:{{ age }}</p>
    <p>数组:{{ hobby }}</p>
    <p>对象:{{ obj }}</p>
    <p>标签字符串:{{ link }}</p>
</div>

image

三目运算符

age变量大于等于18,返回值为成年人,否则返回值为未成年人

<p>三目运算符:{{ age>=18?"成年人":"未成年人" }}</p>

image

文本指令

文本指令,写在标签上的,以 v- 开头的属性。

文本指令 作用
v-text 把变量值显示在标签上,不做渲染,与模板语法一样
v-html 标签字符串会渲染后在显示,其余与-v-text一样
v-show 显示与不显示,修改display属性,会一直在页面上
v-if 显示与不显示,不显示就是直接删除

使用:

<div id="app">
    <p v-text="link1"></p>
    <p v-html="link1"></p>
    <p v-show="show1">显示文字1</p>
    <p v-if="show1">显示文字2</p>
</div>
<script>
    const vm = new Vue({
        el: '#app',
        data: {
            link1: '<a href="https://www.baidu.com">百度一下 你就知道</a>',
            show1: false,
        }
    })
</script>

页面效果:

image

f12查看元素:

image

v-show与v-if的区别

v-show为false时是设置display属性为none,而v-if为false时是直接删除标签。

双向数据绑定

v-model

双向数据绑定使用v-model指令:

<div id="app">
    <input type="text" v-model="name"> name的值为{{ name }}
</div>
<script>
    const vm = new Vue({
        el: '#app',
        data: {
            name: '',
        }
    })
</script>

image

进阶

v-model有三种模式:

模式 作用
.lazy input框失焦后才会变化
.number 只保留数字,但是字母开头就会失效
.trim 移除首尾空格
<body>
<div id="app">
    lazy模式:<input type="text" v-model.lazy="name1"> name的值为:{{ name1 }}<br>
    number模式:<input type="text" v-model.number="name2"> name的值为:{{ name2 }}<br>
    trim模式:<input type="text" v-model.trim="name3"> name的值为:{{ name3 }}<br>
</div>
<script>
    const vm = new Vue({
        el: '#app',
        data: {
            name1: '',
            name2: '',
            name3: '',
        }
    })
</script>

image

事件指令

v-on

按钮,标签的事件:单击事件、双击事件...

语法结构:

<p v-on:事件名='函数'></p>

简写:

<p @事件名='函数'></p>

函数需要放在vue对象的methods中。

<script>
    const vm = new Vue({
        methods:{ // 函数要放在methods中,可以放多个
            myFunc:function () {
            },
        }
    })
</script>

案例:点击按钮后名字更改:

<div id="app">
    <button v-on:click="myFunc">名字更改</button>
    <p>名字:{{ name }}</p>
</div>
<script>
    const vm = new Vue({
        el: '#app',
        data:{
           name:'tom'
        },
        methods:{ // 函数要放在methods中,可以放多个
            myFunc:function () {
                this.name = 'john'
            },
        }
    })
</script>

image

输入框常见事件

事件 作用
v-on:change 失去焦点并且内容变化会触发
v-on:blur 失去焦点会触发
v-on:input 只要内容发生变化就会触发

事件修饰符

修饰事件 作用
.stop 只处理自己的事件,父控件冒泡的事件不处理
.self 只处理自己的事件,子控件冒泡的事件不处理
.prevent 阻止a链接的跳转
.once 事件只会触发一次(适用于抽奖页面)

.stop

<div id="app">
    <ul @click="ulClick" style="background-color: aqua">
        <li @click.stop="liClick" style="background-color: red">文本</li>
    </ul>
</div>
<script>
    const vm = new Vue({
        el: '#app',
        methods: {
            ulClick(){
                alert('ul')
            },
            liClick(){
                alert('li')
            },
        }
    })
</script>

.prevent

<div id="app">
    <a href="https://www.baidu.com" @click.prevent="aClick">百度一下</a>
</div>
<script>
    const vm = new Vue({
        el: '#app',
        methods: {
            aClick(){
            }
        }
    })
</script>

按键修饰符

普通使用

监测按下了哪个键。

<div id="app">
    <input type="text" @keydown="down($event)">
</div>
<script>
    const vm = new Vue({
        el: '#app',
        methods: {
            down(e) {
                console.log(e)
            }
        }
    })
</script>

image

监听enter键

<div id="app">
    <input type="text" @keydown.enter="enterDown">
</div>
<script>
    const vm = new Vue({
        el: '#app',
        methods: {
            enterDown() {
                alert('你按下了enter键')
            }
        }
    })
</script>

image

其他按键监听

大部分按键需要配合键码监听,比如a键监听:

<input type="text" @keydown.65="">

字母与数字键的对应关系:

按键 键码 按键 键码 按键 键码 按键 键码
A 65 J 74 S 83 1 49
B 66 K 75 T 84 2 50
C 67 L 76 U 85 3 51
D 68 M 77 V 86 4 52
E 69 N 78 W 87 5 53
F 70 O 79 X 88 6 54
G 71 P 80 Y 89 7 55
H 72 Q 81 Z 90 8 56
I 73 R 82 0 48 9 57

数字键盘与功能键:

按键 键码 按键 键码 按键 键码 按键 键码
0 96 8 104 F1 112 F7 118
1 97 9 105 F2 113 F8 119
2 98 * 106 F3 114 F9 120
3 99 + 107 F4 115 F10 121
4 100 Enter 108 F5 116 F11 122
5 101 - 109 F6 117 F12 123
6 102 . 110
7 103 / 111
按键 键码 按键 键码 按键 键码 按键 键码
BackSpace 8 Esc 27 Right Arrow 39 -_ 189
Tab 9 Spacebar 32 Dw Arrow 40 .> 190
Clear 12 Page Up 33 Insert 45 /? 191
Enter 13 Page Down 34 Delete 46 `~ 192
Shift 16 End 35 Num Lock 144 [{ 219
Control 17 Home 36 ;: 186 | 220
Alt 18 Left Arrow 37 =+ 187 ]} 221
Cape Lock 20 Up Arrow 38 ,< 188 '" 222

属性指令

标签都是有属性的,想要动态变化属性,可以使用v-bind。

<img v-bind:属性='值' />

简写:

<img :属性='值' />

动态变化属性:

<div id="app">
    <button v-on:click="changeImg">图片更改</button>
    <img v-bind:src=imgUrl alt="" width="500px">
</div>
<script>
    const vm = new Vue({
        el: '#app',
        data:{
           imgUrl:'https://img0.baidu.com/it/u=530426417,2082848644&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500'
        },
        methods:{
            changeImg:function () {
                this.imgUrl = 'https://img1.baidu.com/it/u=700675537,3936578503&fm=253&fmt=auto&app=138&f=JPEG?w=889&h=500'
            },
        }
    })
</script>

image

style和class使用

标签属性style和class是可以有多个值的,所以在使用v-bind指令时可以让它等于数组或者对象。

class属性

css样式:

<style>
    .red {
        color: red;
    }
    .big {
        font-size: 32px;
    }
</style>

使用:

<div id="app">
    <p v-bind:class=myClass_str>文本</p>
    <p v-bind:class=myClass_array>文本</p>
    <p v-bind:class=myClass_obj>文本</p>
</div>
<script>
    const vm = new Vue({
        el: '#app',
        data: {
            myClass_str: 'red', // 字符串类型
            myClass_array: ['red', 'big'], // 数组类型
            myClass_obj: {'red': false, 'big': true}, // 对象类型
        }
    })
</script>

等价于:

<div id="app">
    <p class='red'>文本</p>
    <p class='red big'>文本</p>
    <p class='red'>文本</p>
</div>

数组类型和对象类型都可以添加多个值,字符串只能添加单个值,其中数组类型最好用

image

style属性

style使用键值对添加值时,css属性可以使用驼峰,比如font-size,可以写成fontSize,也可以加引号'font-size'不变。

<div id="app">
    <p v-bind:style=myStyle_str>文本</p>
    <p v-bind:style=myStyle_array>文本</p>
    <p v-bind:style=myStyle_obj>文本</p>
</div>
<script>
    const vm = new Vue({
        el: '#app',
        data: {
            myStyle_str: 'color:red;font-size:32px;', // 字符串类型
            myStyle_array: [{color:'red'}, {fontSize:'32px'}], // 数组类型
            myStyle_obj: {color: 'red', fontSize: '32px'}, // 对象类型
        }
    })
</script>

字符串类型、数组类型和对象类型都可以添加多个值,其中对象类型最好用

image

条件渲染

vue的三个判断条件指令:

  • v-if:符合条件就显示
  • v-else-if:与v-if搭配使用,与v-if差不多
  • v-else:与v-if搭配使用,以上条件都不符合显示。
<p v-if="条件1">优秀</p>
<p v-else-if="条件2">良好</p>
<p v-else>不及格</p>

如果score大于等于90,显示优秀;如果score大于等于60小于90,显示良好;如果以上都不符合,显示不及格。

<div id="app">
    <p v-if="score>=90">优秀</p>
    <p v-else-if="score >= 60 && score< 90">良好</p>
    <p v-else>不及格</p>
</div>
<script>
    const vm = new Vue({
        el: '#app',
        data: {
            score: 85,
        }
    })
</script>

循环渲染

v-for

循环使用v-for指令。

<p v-for="变量名 in 被循环的变量">{{ 变量名 }}</p>

循环数字:

<div id="app">
    <h1>循环整型</h1>
    <span v-for="item in num">{{ item }}, </span>
</div>
<script>
    const vm = new Vue({
        el: '#app',
        data: {
            num: 10,
        }
    })
</script>

循环字符串:

<div id="app">
    <h1>循环字符串</h1>
    <span v-for="item in str">{{ item }}, </span>
</div>
<script>
    const vm = new Vue({
        el: '#app',
        data: {
            str: 'abcdefg',
        }
    })
</script>

循环数组:

<div id="app">
    <h1>循环数组</h1>
    <span v-for="item in for_list">{{ item }}, </span>
</div>
<script>
    const vm = new Vue({
        el: '#app',
        data: {
            for_list: [1, 'asd', 555],
        }
    })
</script>

循环对象:

<div id="app">
    <h1>循环列表</h1>
    只拿对象的值:<span v-for="item in for_obj">{{ item }}, </span><br>
    拿对象的键和值:<span v-for="(value, key) in for_obj">{{ key }}:{{ value }}, </span>
</div>
<script>
    const vm = new Vue({
        el: '#app',
        data: {
            for_obj: {name:'tom', age:18},
        }
    })
</script>

key属性

vue会先复制原生的DOM,生成一个虚拟的DOM。数据修改时,会先在虚拟DOM上更改,然后和原生DOM比较,再进行页面上数据的更新,这样做提高了数据的刷新速度。

在使用v-for时,可以写一个key属性:

<span v-for="item in 4" :key="item">{{ item }}</span>

这个作用相当于给标签写了个唯一属性key,它可以在数据更改时提高页面的刷新速度。

对于小项目来说,这个作用几乎没有。

数组的检测与更新

有时候,我们用一些数组,对象的方法更新数组或对象时,发现页面没有变化。

使用以下方法操作数组:

  • 可以检测变动:push、pop、shift、unshift、splice、sort、reverse
  • 不会检测变动:filter()、concat()、slice()、map(),新数组替换旧数组
<div id="app">
    <button @click="myClick">改变数据</button>
    <span v-for="item in myList">{{ item }}, </span>
</div>
<script>
    const vm = new Vue({
        el: '#app',
        data: {
            myList: [1, 2, 3],
        },
        methods: {
            myClick(){
                this.myList[0] = 222
            },
        }
    })
</script>

上面这个例子点击按钮后并不会改变页面上的数据。

解决方法:

<div id="app">
    <button @click="myClick">改变数据</button>
    <span v-for="item in myList">{{ item }}, </span>
</div>
<script>
    const vm = new Vue({
        el: '#app',
        data: {
            myList: [1, 2, 3],
        },
        methods: {
            myClick(){
                Vue.set(vm.myList, 0, 222)
            },
        }
    })
</script>

根据输入过滤案例

<div id="app">
    <input type="text" v-model="name" @input="handlerInput"><br>
    <p v-for="item in newList">{{ item }}</p>

</div>
<script>
    const vm = new Vue({
        el: '#app',
        data: {
            name: '',
            dataList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'],
            newList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'],
        },
        methods: {
            handlerInput() {
                this.newList = this.dataList.filter(item=>{
                    return item.indexOf(this.name)>=0
                })
            }
        }
    })
</script>

image

表单控制

checkbox

单个多选框:

<div id="app">
    <input type="checkbox" v-model="checkOne">记住密码
    <p>checkbox状态:{{ checkOne }}</p>
</div>
<script>
    const vm = new Vue({
        el: '#app',
        data:{
            checkOne:true
        },
        methods: {

        }
    })
</script>

image

多个多选框:

<div id="app">
    <input type="checkbox" v-model="checkMany" value="篮球">篮球
    <input type="checkbox" v-model="checkMany" value="足球">足球
    <input type="checkbox" v-model="checkMany" value="乒乓球">乒乓球
    <p>checkbox选中:{{ checkMany }}</p>
</div>
<script>
    const vm = new Vue({
        el: '#app',
        data:{
            checkMany:[]
        },
        methods: {

        }
    })
</script>

image

radio

<div id="app">
    <input type="radio" v-model="check" value="男">男
    <input type="radio" v-model="check" value="女">女
    <input type="radio" v-model="check" value="保密">保密
    <p>radio选中:{{ check }}</p>
</div>
<script>
    const vm = new Vue({
        el: '#app',
        data:{
            check:''
        },
        methods: {

        }
    })
</script>

image

购物车案例

选择商品实现

点击查看代码
<div id="app">
    <table>
        <thead>
        <tr>
            <th>商品名</th>
            <th>数量</th>
            <th>单价</th>
            <th>选择</th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="item in dataList">
            <td>{{ item.name }}</td>
            <td>{{ item.quantity }}</td>
            <td>{{ item.price }}</td>
            <td><input type="checkbox" v-model="checkList" :value="item" @change="checkChange"></td>
        </tr>
        </tbody>
    </table>
    <p>商品:{{ checkList }}</p>
    <p>总价:{{ total }}</p>
</div>
<script>
    const vm = new Vue({
        el: '#app',
        data: {
            dataList: [
                {name: '牛奶', quantity: 2, price: 65},
                {name: '娃娃', quantity: 1, price: 144},
                {name: '钢笔', quantity: 5, price: 8},
                {name: '电脑', quantity: 1, price: 5565},
            ],
            checkList: [],
            total: 0,
        },
        methods: {
            checkChange() {
                let total = 0
                this.checkList.forEach((item, index)=>{
                    total += item.price * item.quantity
                })
                this.total = total
            }
        }
    })
</script>

image

全选/反选实现

点击查看代码
<div id="app">
    <table>
        <thead>
        <tr>
            <th>商品名</th>
            <th>数量</th>
            <th>单价</th>
            <th>全选<input type="checkbox" v-model="checkAll" @change="checkAllChange"></th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="item in dataList">
            <td>{{ item.name }}</td>
            <td>{{ item.quantity }}</td>
            <td>{{ item.price }}</td>
            <td><input type="checkbox" v-model="checkList" :value="item" @change="checkChange"></td>
        </tr>
        </tbody>
    </table>
    <p>商品:{{ checkList }}</p>
    <p>总价:{{ getPrice() }}</p>
</div>
<script>
    const vm = new Vue({
        el: '#app',
        data: {
            dataList: [  // 商品详情
                {name: '牛奶', quantity: 2, price: 65},
                {name: '娃娃', quantity: 1, price: 144},
                {name: '钢笔', quantity: 5, price: 8},
                {name: '电脑', quantity: 1, price: 5565},
            ],
            checkList: [],  // 选中的商品
            checkAll:false,  // 全选框
        },
        methods: {
            // 获取总价
            getPrice() {
                // 临时存储商品总价
                let total = 0
                // 计算总价
                this.checkList.forEach((item, index)=>{
                    total += item.price * item.quantity
                })
                return total
            },
            // 单选选框变化
            checkChange() {
                // 商品没有全选时,全选框应该不打勾
                this.checkAll = this.dataList.length === this.checkList.length
            },
            // 全选框变化
            checkAllChange() {
                if (this.checkAll) {
                    this.checkList = this.dataList
                }else {
                    this.checkList = []
                }
            }
        }
    })
</script>

image

数量加减实现

点击查看代码
<div id="app">
    <table>
        <thead>
        <tr>
            <th>商品名</th>
            <th>数量</th>
            <th>单价</th>
            <th>全选<input type="checkbox" v-model="checkAll" @change="checkAllChange"></th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="item in dataList">
            <td>{{ item.name }}</td>
            <td>
                <button @click="reduce(item)">-</button>
                {{ item.quantity }}
                <button @click="item.quantity++">+</button>
            </td>
            <td>{{ item.price }}</td>
            <td><input type="checkbox" v-model="checkList" :value="item" @change="checkChange"></td>
        </tr>
        </tbody>
    </table>
    <p>商品:{{ checkList }}</p>
    <p>总价:{{ getPrice() }}</p>
</div>
<script>
    const vm = new Vue({
        el: '#app',
        data: {
            dataList: [  // 商品详情
                {name: '牛奶', quantity: 2, price: 65},
                {name: '娃娃', quantity: 1, price: 144},
                {name: '钢笔', quantity: 5, price: 8},
                {name: '电脑', quantity: 1, price: 5565},
            ],
            checkList: [],  // 选中的商品
            checkAll: false,  // 全选框
        },
        methods: {
            // 获取总价
            getPrice() {
                // 临时存储商品总价
                let total = 0
                // 计算总价
                this.checkList.forEach((item, index) => {
                    total += item.price * item.quantity
                })
                return total
            },
            // 单选选框变化
            checkChange() {
                // 商品没有全选时,全选框应该不打勾
                this.checkAll = this.dataList.length === this.checkList.length
            },
            // 全选框变化
            checkAllChange() {
                if (this.checkAll) {
                    this.checkList = this.dataList
                } else {
                    this.checkList = []
                }
            },
            // 数量减少
            reduce(item) {
                if (item.quantity === 1) {
                    alert('不能在减少了!')
                } else {
                    item.quantity--
                }
            },
        }
    })
</script>

image

posted @ 2022-06-24 16:53  Yume_Minami  阅读(88)  评论(0编辑  收藏  举报