前后端分离人不分离,这就是为什么我在学前端。
<h1>插值语法{{name}}h1>
<a :href="url">指令语法a>
<input type="text" v-bind:value="name">单向数据绑定input>
<input type="text" v-model:value="name">双向数据绑定(只能应用在表单类元素上)input>
// 第一种写法(el和data的写法是分离的,可以排列组合得到四种不同写法)
new Vue({
el:'#root',
data:{
name:'尚硅谷',
}
})
// 第二种写法
const vm = new Vue({
data:{
return {
name:'尚硅谷',
}
}
})
vm.$mount('#root')
解释:
M:模型->data数据
V:视图->模板,DOM
VM:视图模型->Vue实例对象
双向绑定:
利用defineProperty给对象添加属性,并将属性的值与其他数据绑定。
let number = 18
Object.defineProperty(person,'age',{
value:18,
enumerable:true, // 可枚举forin
writable:true, // 可修改
configurable:true, // 可删除
get:function(){
return number;
},
set:function(value){
number=value;
}
})
vm.name是通过defineProperty代理data.name得到的:
/** vm._data===data */
let data = {
name:'尚硅谷',
}
const vm = new Vue({
el:'#root',
data:data,
})
<button v-on:click="clickButton">button>
<button @click="clickButton(123, $event)">button>
<myButton @click.native="clickButton">自定义组件myButton使用native修饰符接收原生事件myButton>
<button @click.prevent="clickButton">阻止默认事件button>
<button @click.stop="clickButton">阻止事件冒泡button>
<button @click.once="clickButton">事件只触发一次button>
<button @click.capture="clickButton">使用事件捕获模式button>
<button @click.self="clickButton">只有event.target是当前操作的元素时才触发button>
<button @click.passive="clickButton">事件的默认行为立即执行,无需等待事件的回调执行完成button>
// 滚动事件
<ul @scroll="scroll">滚动条事件ul>
<ul @wheel="wheel">鼠标滚动ul>
// 键盘事件
<input @keyup.enter="search">释放回车键触发函数input>
// 特殊按键:tab、ctrl、alt、shift、meta(windows徽标键)
<input @keyup.ctrl="search">按键同时按下其他键,然后释放其他键,事件触发input>
<input @keydown.ctrl="search">正常触发事件input>
<input @keydown.tab="search">tab必须配合keydown使用,因为它会让当前元素失去焦点input>
<input @keyup.ctrl.y="search">同时按下ctrl和yinput>
底层借助Object.defineProperty方法提供的getter和setter
new Vue({
computed:{
fullName:{
// get调用时机:1.初次被读取;2.所依赖的数据发生变化;否则直接走缓存
get(){
return firstName + '-' + lastName;
}
set(value){
const arr = value.split('-')
this.firstName = arr[0]
this.lastName = arr[1]
}
},
// 只读时的简写
fullName(){
return firstName + '-' + lastName;
}
}
})
new Vue{
watch:{
isHot:{
immediate:true, // 初始化时调用
deep:true, // 开启深度监视
handler(newValue, oldValue){
console.log('值修改了')
}
},
// 简写
isHot(newValue, oldValue){
console.log('值修改了')
}
}
}
computed无法开启异步任务而watch可以
<div :class="mood">字符串写法,样式类名不确定,需动态指定div>
<div :class="classArr">数组写法,要绑定的样式个数不确定,样式类名也不确定div>
<div :class="classObject">对象写法,个数确定,样式类名也确定,但要动态决定用不用div>
<div :style="styleObject">对象写法,key不能乱写div>
new Vue({
data:{
mood:"normal", // normal是样式名
classArr:['atguigu1','atguigu2'],
classObject:{
atguigu1:true,
atguigu2:false,
},
styleObject:{
fontSize: '40px',
color:'red',
}
}
})
<div v-show='false'>隐藏,但是元素还在div>
<div v-if='n===1'>隐藏,但是元素不在了div>
<div v-else-if='n===2'>else-ifdiv>
<div v-else>elsediv>
<template v-if='n === 1'>
<div/>
<div/>
template>
key的作用: 列表中的key是虚拟DOM对象的标识,数据发生变化时,Vue根据新数据生成新的虚拟DOM,然后根据key对比新旧虚拟DOM,判断是否需要更新真实DOM。
index作为key可能出现的问题: 在数组的非末尾增删数据,会导致没有必要的真实DOM更新。如果结构中包含输入类的DOM,界面显示会有问题。
<li v-for='(item, index) in persons' :key='item.key'>{{ item.name }}li>
<li v-for='(value, key) of persons' :key='key'>{{ key }}:{{ value }}li>
computed:{
filPersons(){
const arr = this.persons.filter((p)=>{
return p.name.indexOf(this.keyWord) !== -1;
})
if(this.sortType){
arr.sort((p1, p2)=>{
return p1.age-p2.age;
})
}
return arr;
}
}
let data = {
name:'尚硅谷',
}
function Observer(obj){
// 汇总对象中所有的属性,遍历,配置setter和getter
const keys = Object.keys(obj)
keys.forEach((k)=>{
Object.defineProperty(this, k, {
get(){
return obj[k];
},
set(val){
obj[k] = val;
}
})
})
}
// 创建一个监视的实例对象,用于监视data中属性的变化
const obs = new Observer(data)
// 准备一个vm对象
let vm = {}
vm._data = data = obs
vue还做了两件事:
向响应式数据添加属性,并确保新的属性也是响应式的
注意:只能给data里的对象添加属性,不能给Vue实例或Vue实例的根数据对象(_data)添加
this.$set(this.student, 'sex', '女')
Vue没有给数组的下标配置监测,所以Vue监视不到通过下标修改数组数据。
对数组的修改要通过push、pop、shift、unshift、splice、sort、reverse进行,Vue才能监视到数据的变化(Vue对这些函数进行了包装)。
<div v-text="name">你好,div>
严重注意:在网页上动态渲染HTML是非常危险的,容易导致XSS攻击
<div v-html="htmlStr">你好,div>
<div v-cloak>{{ name }}div>
[v-cloak]{
display:none;
}
<div v-once>{{ n }}div>
<div v-pre>Vuediv>
big-num函数被调用的时机:(1)指令与元素成功绑定时;(2)指令所在的模板被重新解析时
注意:指令内函数的this是windows
<h2>当前的n值是:<span v-text="n">span>h2>
<h2>放大10倍后的n值是:<span v-big-num="n">span>h2>
<input type='text' v-fbind:value='n'/>
directives:{
// 函数式
'big-num'(element, binding){
element.innerText = binging.value*10
},
// 对象式
fbind:{
// 指令与元素成功绑定时
bind(element, binding){
element.value = binding.value;
},
// 指令所在元素被插入页面时
inserted(element, binding){
element.focus();
},
// 指令所在模板被重新解析时
update(){
element.value = binding.value;
},
}
}
倦了,下次继续(咕咕咕)