【Vue】操作标签元素

数据显示

文本插值 {{ }}

  • 插值符 {{ }} 里面可以写 JS 表达式
Vue2
  • 插值符 {{ }} 可以直接获取 data 中的数据

    实际上,{{ }} 中能直接获取 Vue 实例的所有属性

<body>
    <div id="app">
        <p>msg: {{`${msg}!!!`}}</p>
    </div>
</body>

<!-- vue2 -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.10/dist/vue.js"></script>

<script>
    let vm = new Vue({
        el: "#app",
        data: { msg: "superman" }
    });
</script>
Vue3
<template>
    <h1>{{ message }}</h1>
</template>

<script setup lang="ts">
import { ref } from "vue";
const message = ref<string>("Hello World!");
</script>
v-cloak & 闪动问题
  • 闪动问题:网速较慢时,{{ }} 渲染的数据可能还没加载出来,就会先显示源码。待加载好了,再显示数据
  • v-cloak:用于解决 {{ }} 闪动问题;
    原理:先将标签元素隐藏,待 Vue 实例创建完成,再显示内容
  • 本质是一个特殊属性,Vue 实例创建完毕并接管容器后 会自动删掉该属性
<!-- 在标签元素中设置 v-cloak 属性 -->
<p v-clock>msg: {{`${msg}!!!`}}</p>
/* 配合 CSS 使用,使用属性选择器 */
[v-cloak] {
    display: none;
}
  • 如果把引入 Vue 的 script 标签放到 head 标签内:先加载 script 标签、再渲染页面,也不会出现闪动问题
  • 使用脚手架的话,也不会出现闪动问题

v-text & v-html

  1. v-textv-text 指令值会替换掉标签元素里面的内容,且不会出现闪动问题;会解析内容中的 HTML 代码
  2. v-htmlv-html 指令值会替换掉标签元素里面的内容,且不会出现闪动问题;会解析内容中的 HTML 代码
<p v-text="msg"></p>
<p v-html="msg"></p>
|
<p v-text="html"></p>
<p v-html="html"></p>
new Vue({
    el: '#app',
    data: {
        msg: "hello world1",
        html: '<a href="https://www.baidu.com/">点击跳转百度</a>'
    }
});
  • v-htmlv-text 的属性值可以是表达式
<!-- 使用表达式作为 v-html 的属性值 -->
<div v-html="num >= 18 ? ele1 : ele2">
    <h1>大哥</h1>
</div>
new Vue({
    el: "#app",
    data: {
        num: 19,
        ele1: "<h2>已成年</h2>",
        ele2: "<h2>尚未成年</h2>",
    }
});
  • 在网站上动态渲染 HTML 是非常危险的,因为容易导致 XSS 攻击;
    v-html 只用在可信内容上,永远不要用在用户提交的内容上

v-once

  • v-once:设置该属性的标签,为静态标签,初次渲染完毕后,内容不再改变
<p v-once>{{num}}</p>
<button @click.once="change">点击</button>
let vm = new Vue({
    el: "#app",
    data: { num: 100 },
    methods: {
        change() {
            console.log("事件已触发!");
            console.log(++this.num);;
        }
    }
});

可以发现,点击按钮后,执行事件函数、更新数据,但页面不会再重新渲染


v-pre

  • v-pre:跳过当前元素及其子元素的编译过程
  • 给没有使用 Vue 语法的标签元素设置,可以稍微加快编译速度 ~
<!-- 里面写什么就显示什么,不会进行编译操作 -->
<p v-pre> {{ msg }} </p>



属性绑定 v-bind

  • v-bind:属性="值",可简写为 :属性="值"
  • 使用属性绑定后,"值" 不再是字符串,"" 里面可以写任何 JS 表达式
  • 使用属性绑定后,"" 里面可以直接获取 data 中的数据(Vue 的属性都可直接获取)

普通属性

.redBg {
    background: rgb(253, 167, 167);
}

.blueBg {
    background: rgb(153, 180, 255);
}

div {
    width: 200px;
    height: 100px;
    margin: 2px;
}
<div id="app">
    <!-- ① v-bind:属性="值" -->
    <div v-bind:class='value'>v-bind:class='value'</div>
    <!-- ② :属性="值" -->
    <div :class='value'>:class='value'</div>
    <!-- ③ 属性值可以是字符串 -->
    <div :class='"redBg"'>:class='"bgR"'</div>
    <!-- ④ 属性值也可以写表达式 -->
    <div :class='isOk ? "redBg" : "blueBg"'></div>
</div>
let vm = new Vue({
    el: "#app",
    data: {
        value: "redBg", // ① ②
        isOk: false, // ④
    },
});
  • 除了系统属性,我们也可以设置自定义属性:
<div id="app">
    <!-- 设置 name 属性,属性值为 superman -->
    <div :[key]='"superman"'>:[key]='"superman"'</div>
    <div :name='value'>:my-name='value'</div>
</div>
let vm = new Vue({
    el: "#app",
    data: {
        key: "name",
        value: "superman",
    },
});

class

因为 class 属性可以设置多个属性值,所以属性值可以为对象 / 数组

.red {
    color: red;
}

.green {
    color: green;
}

.yellow {
    background-color: yellow;
}
  • string 写法:适用于 [样式的类名不确定] 的时候
  • 如果设置一个原生 class 属性、绑定一个 class 属性,则会合并 class 属性值

<!-- 通过原生 JS 设置 class -->
<p class="red">原生 JS</p>
<!-- 通过 `v-bind` 绑定 class 属性,属性值为字符串 -->
<p :class="vGreen">string</p>
<!-- 原生 JS 设置的 class 与 `v-bind` 绑定的 class 会合并 -->
<p class="red" :class="vYellow">string</p>
let vm = new Vue({
    el: "#app",
    data: {
        vGreen: "green",
        vYellow: "yellow"
    }
});
  • 数组写法:适用于 [样式的个数、类名都不确定] 的时候
<!-- 原生 JS:设置多个 class -->
<p class="red yellow">多个类名</p>
<!-- 通过 `v-bind` 绑定 class 属性,属性值为数组 -->
<p :class="[vRed]">array</p>
<p :class="[vRed, vYellow]">array</p>
<p :class="arr">array</p>
let vm = new Vue({
    el: "#app",
    data() {
        return {
            vYellow: "yellow",
            vRed: "red",
            arr: ["red", "yellow"]
        };
    }
});
  • 对象写法:适用于 [样式个数、类名都确定,但要动态控制用不用] 的时候
<!-- 单个 class -->
<p :class="{red: vRed}">object</p>
<!-- 多个 class -->
<p :class="{red: vRed, yellow: vYellow}">object</p>
<p :class="obj">object</p>
let vm = new Vue({
    el: "#app",
    data: {
        vRed: true,
        vYellow: true,
        obj: {
            red: true,
            yellow: true,
        }
    }
});

style

因为 style 属性可以设置多个属性值,所以属性值可以为对象 / 数组

  • string 写法
<p style="color: red">原始 JS</p>
<p :style="vRed">string</p>
let vm = new Vue({
    el: "#app",
    data: {
        vRed: "color: red"
    }
});
  • 对象写法:对象的属性是样式,属性值是样式值
  • 属性名不能乱写,得是样式名!

  • 属性名中,诸如 font-sizefontSize

<p :style="{fontSize: vFontSize, color: vRed}">object</p>
<p :style="styleObj">object</p>
let vm = new Vue({
    el: "#app",
    data: {
        vRed: "red",
        vFontSize: '50px',
        styleObj: {	
            fontSize: "50px",
            color: "red"
        }
    }
});
  • 数组写法:元素是对象,对象的属性名是样式名,属性值是样式值
<div id="app">
    <p :style="[styleObj1, styleObj2]">object</p>
</div>
let vm = new Vue({
    el: "#app",
    data: {
        styleObj1: {
            fontSize: "50px",
            color: "red"
        },
        styleObj2: {
            backgroundColor: "yellow",
        }
    }
});
  • 那你是不是可以直接在 data 里面写 styleArr: [{...}, {...}] ? 自己试~



双向绑定 v-model

  • v-model:value="值" 可简写为 v-model="值",用于双向绑定 [表单] 的数据
  • 双向绑定:更新表单的 value,data 中的数据也会更新;更新 data 中的数据,表单的 value 也会更新
  • 本质上,v-model 是由 v-bind 配合 input 事件实现的
    ① v-bind 绑定 value 属性、② 在 input 事件的回调函数中,修改 value 的值

文本 input [text]

<div id="app">
    <p>Message is: {{ msg }}</p>
    <!-- 给 input 标签元素设置 v-model 属性 -->
    <input v-model="msg" type="text">
</div>
let vm = new Vue({
    el: "#app",
    data: { msg: "superman" }
});

上例中,input 的默认值为 data 中的 msg,更新 input 的 value 值 → msg 也会被更新 → p 显示的内容也会被更新


多行文本 textarea

  • 对于文本域标签 <textarea>,用法与 type=“text” 的 input 标签一样
  • 虽然 <textarea> 是双标签,但 <textarea> {{msg}} </textarea> 并不会生效,要设置 v-model 属性来替代
<textarea v-model="msg"></textarea>

单选框 input [radio]

  • 因为 v-model 绑定的是 value 值

    所以,我们需要设置 value 属性;如果没有设置 value 属性,则获取到的值为 null

<input type="radio" id="male" value="male" v-model="sex">
<label for="male">male</label>
<br>
<input type="radio" id="female" value="female" v-model="sex">
<label for="female">female</label>
<br>
<span>sex: {{ sex }}</span>
let vm = new Vue({
    el: "#app",
    data: {
        sex: ""
        // sex: "male" // 设置默认值 'male',默认选中 male 选项
    }
});

复选框 input [checkbox]

  1. 没有配置 value 属性,收集的是 checkbox 的 checked 状态,所以会收集到布尔值
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{checked}}</label>
let vm = new Vue({
    el: "#app",
    data: { checked: true } // 绑定 [布尔值]
});
  1. 配置了 value 属性,绑定 [非数组],收集的也还是 checkbox 的 checked 状态
    所以也还是会收集到布尔值 → ture-全选、false-全不选
篮球<input type="checkbox" value="篮球" v-model="checked">
足球<input type="checkbox" value="足球" v-model="checked">
网球<input type="checkbox" value="网球" v-model="checked">
<p>{{checked}}</p>
  1. 配置了 value 属性,绑定 [数组],才能收集到多选框的 value
篮球<input type="checkbox" value="篮球" v-model="checked">
足球<input type="checkbox" value="足球" v-model="checked">
网球<input type="checkbox" value="网球" v-model="checked">
<p>{{checked}}</p>
let vm = new Vue({
    el: "#app",
    data: {
        checked: [] // 绑定到数组   
    }
});
  • 能获取到多个值的表单元素,都应该绑定 [数组],以存储多个数据

选择框 select > option

  • 对于下拉菜单,推荐提供一个值为空的禁用选项,作为默认显示选项
<select v-model="selected">
    <option disabled value="">国家</option>
    <option value="China">中国</option>
    <option value="America">美国</option>
    <option value="Japan">日本</option>
</select>
<span>Selected: {{ selected }}</span>
let vm = new Vue({
    el: "#app",
    data: {
        selected: ""
        // selected: "China" // 设置默认值
    }
});
  • 如果 option 标签不设置 value 属性,则获取到的是 option 标签的内容
<select v-model="selected">
    <option disabled value="">国家</option>
    <option>中国</option>
    <option>美国</option>
    <option>日本</option>
</select>
<span>Selected: {{ selected }}</span>
  • 多选时,绑定到一个数组
<select multiple v-model="selected">
    <option disabled value="">国家</option>
    <option>中国</option>
    <option>美国</option>
    <option>日本</option>
</select>
<span>Selected: {{ selected }}</span>
let vm = new Vue({
    el: "#app",
    data: {
        selected: [] // 绑定到数组
    }
});

标签修饰符

  1. .lazy:在 change 事件之后同步,即失焦再同步(默认 input 事件之后同步,即一边写一边同步)
  2. .trim:过滤首尾空白字符
  3. .number:将获取到的数据转为 number 类型,如果这个值无法被 parseFloat() 解析,则会返回数字前缀
<input type="text" v-model.lazy="username" />
<span>{{username}}</span><br>

<input type="text" v-model.trim="password" />
<span>{{password}}</span><br>

<!-- type="number" 控制 input 只能输入数字,但传给 Vue 的数据还是字符串格式的 -->
<!-- v-model.number="age" 将数据转为 Number 类型 -->
<input type="number" v-model.number="age" />
<span>{{age}}</span><br>
let vm = new Vue({
    el: "#app",
    data: {
        username: "",
        password: "",
        age: ""
    }
});
表单提交事件
  • submit 提交表单时触发
  • .prevent 阻止默认行为
<form @submit.prevent="console.log('submit successfully')"></form>

说白了,使用 Vue 后,我们不用直接操作 DOM~ 我们操作 Vue,Vue 帮我们操作 DOM~

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JS.Huang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值