vue3学习随便记4
Posted sjg20010414
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue3学习随便记4相关的知识,希望对你有一定的参考价值。
模板语法
插值
文本插值:插值 Mustache语法,会将数据解释为普通文本
<span>Message: msg </span>
组件实例 msg property 改变时,插值内容自动改变。如果希望插值处的内容只被替换一次,可以附加使用 v-once 指令
<span v-once>这个将不会改变: msg </span>
原始HTML:Mustache语法会将数据解释为普通文本,如果希望输出html,需要使用 v-html 指令
<html>
<head>
<script src="vue.global.js"></script>
</head>
<body>
<div id="app">
<p>Using mustaches: <span> rawHtml </span></p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>
</div>
<script>
const App =
data()
return
rawHtml: `<span style="color:red">红色文本</span>`
Vue.createApp(App).mount('#app')
</script>
</body>
</html>
查看结果
相关源码
所以,表面看源码一样,主要是解析方式不同(Mustache语法中,直接变量值替换,而 v-html 指令中的变量值会去解析 property值中的数据绑定)。
不能期望用 v-html 来复合局部模板,因为Vue不是基于字符串的模板引擎,Vue中应该用组件方式复合。一般较少使用原始HTML,因为它容易导致 XSS攻击,只对可信内容使用原始HTML插值,绝对不能将用户提供的内容作为原始HTML插值。
Attribute:对于元素属性Attribute,不能用 Mustache语法,应该用 v-bind指令
<div v-bind:id="dynamicId"></div>
上述 v-bind 指令表示,id属性的值是变量dynamicId的值,简单理解就是这个id的值是需要解析获得的,不是表面看到的。对于 Attribute 的值绑定,有几种特别情况需要了解。
如果绑定的值是 null 或 undefined (表示“空”),那么这个 attribute 就不会包含在渲染的元素中。
对于布尔型属性 (它们存在就是 true,例如 checkbox 的 checked),如果绑定的值等价于 true,那么该属性就会被包含,如果绑定的值是空字符串,该属性也会被包含(即空字符串这里等价于true),其他绑定的值等价于false,该属性就被省略。
<html>
<head>
<script src="vue.global.js"></script>
</head>
<body>
<div id="app">
<button v-bind:disabled="b1">按钮b1</button>
<button v-bind:disabled="b2">按钮b2</button>
<button v-bind:disabled="b3">按钮b3</button>
</div>
<script>
const App =
data()
return
b1: 3 + 5 > 7,
b2: '',
b3: 3 + 5 > 9
Vue.createApp(App).mount('#app')
</script>
</body>
</html>
效果
使用Javascript表达式: 绑定的值,还可以是 javascript表达式 (但不能是语句或流控制)
<html>
<head>
<script src="vue.global.js"></script>
</head>
<body>
<div id="app">
<p> number+1 </p>
<p> ok ? 'YES' : 'NO' </p>
<p> message.split('').reverse().join('') </p>
<div :id="'list-' + id">List1</div>
<!-- <p> var a = 1 </p>
<p> if (ok) return message </p> -->
</div>
<script>
const App =
data()
return
number: 999,
ok: false,
message: 'Hello, Vue3',
id: 1
Vue.createApp(App).mount('#app')
</script>
</body>
</html>
上述代码中,注释部分如果去掉注释符号,将编译出错。效果如下:
指令
指令是带有 v- 前缀的特殊 attribute,多数指令的值是单个Javascript表达式。指令的作用是,表达式的值改变时,将这种影响响应式地作用到DOM,例如,我们用 v-if 指令,根据表达式值的真假来决定渲染该DOM还是移除该DOM。
指令参数:像 v-bind 这样的指令,需要用指令参数来明确要把值绑定给谁(这个谁往往是HTML本身的attribute)
<a v-bind:href="url"> ... </a>
<a v-on:click="doSomething"> ... </a>
动态参数: 所谓动态参数,就是前面的这个“谁”是不确定的,是变量,语法是用方括号括起来
<a v-bind:[attributeName]="url"> ... </a>
<a v-on:[eventName]="doSomething"> ... </a>
修饰符:修饰符是对指令参数的额外说明,语法是用句号
<form v-on:submit.prevent="onSubmit">...</form>
对 submit事件使用了修饰符 .prevent,这等于告诉 v-on 指令,在触发该事件执行对应方法时,需要额外调用 submit.preventDefault(),即 .prevent 修饰符等价于额外调用事件的 preventDefault()方法。
缩写
对于 v-bind缩写,就是把它去掉,即冒号:开头的就是 v-bind。
对于 v-on缩写,是连同后面的冒号替换成@
Data Property 和方法
组件的 data 对应的是一个函数,而非数据对象,尽管这个函数本身是返回一个对象。Vue在创建新组件实例的过程中会调用 data() 函数,Vue通过响应性系统把data()返回的对象包裹起来,以 $data 的形式存储在组件实例中。
<html>
<head>
<script src="vue.global.js"></script>
</head>
<body>
<div id="app">
<p> message </p>
<input v-model="message" />
<p> nonReactive </p>
<input v-model="nonReactive" />
</div>
<script>
const App =
data()
return
message: 'Hello Vue3'
var vm = Vue.createApp(App).mount('#app')
setInterval(function ()
console.log(vm.$data.message)
console.log(vm.message)
console.log(vm.$data.nonReactive)
console.log(vm.nonReactive)
, 5000)
vm.message = 'New message'
console.log(vm.$data.message)
vm.$data.message = 'Message from $data'
console.log(vm.message)
vm.nonReactive = 'Add nonReactive data'
</script>
</body>
</html>
对于第一个input文本框,它绑定了data()内的变量message,这样,input值改变立刻影响message,再影响上部<p>显示。对于第二个文本框,它试图绑定动态添加到vm的属性nonReactive,这个属性不会被包裹到 $data,不会被监视,从而不具有响应性,即修改第二个文本框的值不会影响到它上面的<p>中的显示。但神奇的是,vm.nonReactive 修改后,等到上面一个文本框的值改变从而影响上一个<p>时,同时会影响到下一个<p>的显示。这似乎表明,初始vm.* 包裹到 vm.$data.*,后者是被监视的变量,并且值总是和前者保持一直,渲染值总是从vm.*读取,被监视的变量有改变时,触发渲染更新。
(上图不代表内部工作原理 ),红色路径表示触发了响应,vm.* 的值投射到 <p> ... </p>,绿色路径不会触发投射。
方法
组件的 methods 对应的是对象,只是对象中每个键值对都是函数,使用 ES2015+ 语法可以将键值对直接写成函数。Vue自动为 methods 中的函数绑定组件实例,所以这些函数称为方法,在方法中可以用 this 引用组件实例。
<html>
<head>
<script src="vue.global.js"></script>
</head>
<body>
<div id="app">
<p> count </p>
<button @click="increment">投票</button>
<p><span :title="toTitleDate(date)"> formatDate(date) </span></p>
</div>
<script>
const app = Vue.createApp(
data()
return
count: 4,
date: new Date()
,
methods:
increment()
this.count++
this.date = new Date()
,
toTitleDate(d)
return d.toString()
,
formatDate(d)
let year = d.getFullYear()
let month = d.getMonth()
let date = d.getDate()
let hours = d.getHours()
let minutes = d.getMinutes()
let seconds = d.getSeconds()
return year + '年' + month + '月' + date + '日'
+ hours + '时' + minutes + '分' + seconds + '秒'
)
var vm = app.mount('#app')
console.log(vm.count)
vm.increment()
console.log(vm.count)
</script>
</body>
</html>
方法通常被当作事件监听的handler使用,如上图中的 increment。也可以直接从模板中调用方法,如上图中的 toTitleDate、formatDate,这两个方法访问了响应式数据(调用时的参数date是data()中定义的),从而它们作为渲染依赖项被跟踪,即我们点击按钮触发事件,执行 increment,date被修改后,toTitleDate(date) 和 formatDate(date) 也会自动执行更新。当然,多数情况下,用计算属性替换直接从模板中调用方法会更好。
防抖(debounce)和节流(throttle)
函数防抖(debounce)就是说事件触发后,在一定时间范围内只能执行一次,如果在这个时间范围内又触发了该事件,则重新计算函数延迟执行的时间。debounce/throttle 存在的目的是,对于前端的一些事件,例如onresize、scroll、mousemove、mousehover等,会频繁触发,如果响应函数内部执行了其他函数,尤其是操作 DOM 或者 ajax 请求,就会卡死浏览器或造成网络拥塞。
debounce 其实就类似电路中的施密特触发,延迟触发,只执行一次。但有些场合,只执行一次是不合适的,例如鼠标拖拽一个东西,只执行一次就会出现突跳感,这时需要节流(throttle),就是减少触发,但保持在一个感觉流畅的水平。
Vue没有内置的 debounce 和 throttle,可以使用 Lodash 库(Lodash Documentation)有关功能实现。
<html>
<head>
<script src="vue.global.js"></script>
</head>
<body>
<div id="app">
<save-button :text="label"></save-button>
</div>
<script src="https://unpkg.com/lodash@4.17.20/lodash.min.js"></script>
<script>
const app = Vue.createApp(
data()
return
label: '保存'
)
app.component('save-button',
created()
this.debouncedClick = _.debounce(this.click, 500)
,
unmounted()
this.debouncedClick.cancel()
,
methods:
click()
alert('保存数据')
,
props: ['text'],
template: `
<button @click="debouncedClick"> text </button>
`
)
var vm = app.mount('#app')
</script>
</body>
</html>
例子中,我们为保存按钮组件的点击事件创建了带防抖的处理方法 debouncedClick,值得注意的是,debouncedClick 并不是组件 methods 中定义的方法,因为 methods 中定义的方法,是所有实例共享的,而 debounce 的特点是延迟响应且响应一次,这对于可复用组件有潜在问题(多个实例会相互影响),解决办法是让 debounce方法局限于每个实例,即在 created钩子中动态创建(debounce方法包裹了原始点击处理方法),在 unmounted钩子中调用 debounce方法随带的cancel方法取消掉延迟调用的方法。对实际点击事件,是 debounce方法(代理者)进行响应的。
以上是关于vue3学习随便记4的主要内容,如果未能解决你的问题,请参考以下文章