Vue核心

article/2025/10/20 5:37:19

1. Vue核心(一)

1.1 模板语法

  1. 插值语法

    功能:用于解析标签体的内容

    写法:{{xxx}}, xxx是 js 表达式,且可以直接读取到 data 中的所有属性

  2. 指令语法:

    功能:用于解析标签,(包括标签属性,标签体内容,绑定事件…)

    形式都是 v-???

v-band

<a v-bind:href="url">baidu</a>

v-band 相当于把后面引号内的属性当作 js 表达式,可以简写为 :

1.2 数据绑定

Vue中有2中数据绑定的方式:

  1. 单向绑定 v-bind : 数据只能从 data 流向页面
  2. 双向绑定 v-model: 数据不仅能从 data 流向页面,还可以从页面流向 data
    • 双向绑定一般都应用在表单类元素上
    • v-model:value 可以简写为 v-model
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>初识Vue</title><script type="text/javascript" src="../js/vue.js"></script>
</head>
<body><div id="root"><div>单向数据绑定:<input type="text" :value="data1"></div><div>双向数据绑定:<input type="text" v-model:value="data1"></div></div><script type="text/javascript">Vue.config.productionTip = false // 阻止 vue 启动时生成生产提示const x = new Vue({el: '#root', // el 用于指定当前 Vue 实例为哪个容器服务,值通常为css选择器字符串data: { // data中用于存储数据,数据供el所指定的容器去使用,值我们暂定先写成一个对象data1: '中国',}})</script>
</body>
</html>

v-model 只能用在表单,输入类元素中

简写

<div>单向数据绑定:<input type="text" :value="data1">
</div>
<div>双向数据绑定:<input type="text" v-model="data1">
</div>

1.3 el 与 data 两种写法

el

Vue.config.productionTip = false // 阻止 vue 启动时生成生产提示
const x = new Vue({// el: '#root', // 方式一data: { // data中用于存储数据,数据供el所指定的容器去使用,值我们暂定先写成一个对象data1: '中国',}
})setTimeout(() => {x.$mount('#root') // 方式二
}, 1000);

data

对象式

data:{data1:'xxxx'
}

函数式

data:function(){return{data1:'xfdsaf'}
}data(){return{data1:'fdsfa'}
}

一个重要原则:

Vue 管理的函数,一定不要写箭头函数,一旦写了箭头函数,this 就不再是 Vue 的实例了

1.4 MVVM模型

  1. M:模型:data中的数据
  2. V:视图:模板代码
  3. VM:视图模型:Vue实例

image-20220804094917992

观察发现:

  1. data 中所有属性,最后都出现在 vm
  2. vm 上所有的属性及 Vue原型上所有属性,在 Vue 模板中都可以直接使用

1.5 数据代理

Object.defineProperty

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>初识Vue</title><script type="text/javascript" src="../js/vue.js"></script>
</head>
<body><script type="text/javascript">let number = 18let person = {name:'wy',sex:'male'}Object.defineProperty(person, 'age',{// value:13,enumerable:true, // 控制属性是否可以枚举,默认值为false// writable:true, // 控制属性是否可以被修改,默认值为false// configurable:true, // 控制属性是否可以被删除,默认值为false// 当 age 属性被读取时,get函数会被调用,且返回值是 ageget(){return number},// 当 age 属性被修改时,set函数会被调用,且会收到修改的值set(value){number = value;}})console.log(person);console.log(Object.keys(person));</script>
</body>
</html>

深入理解

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Vue核心</title><script type="text/javascript" src="../js/vue.js"></script>
</head>
<body><script type="text/javascript">let obj1 = {x:1}let obj2 = {y:2}Object.defineProperty(obj2, 'x',{get(){return obj1.x},set(value){obj1.x = value;}})</script>
</body>
</html>

控制台验证

image-20220804102505512

image-20220804102635176

Vue中的数据代理

  1. 通过 vm 对象来代理 data 对象中属性的操作 (读/写)

  2. 更加方便地操作 data 中的数据

  3. 基本原理

    通过 Object.defineProperty()data 对象中所有属性添加到 vm 上。为每一个添加到 vm 上的属性,都指定一个 getter/setter ,在 getter/setter 内部去操作 data 中对应的属性

1.6 事件处理

事件基本使用

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Vue核心</title><script type="text/javascript" src="../js/vue.js"></script>
</head>
<body><div id="root"><h1>{{name}}</h1><button v-on:click="showInfo1">点我提示信息1</button><button @click="showInfo2(666, $event)">点我提示信息2</button></div><script type="text/javascript">const vm = new Vue({el:'#root',data:{name:'hh',},methods:{showInfo1(event){console.log(event.target.innerText);},showInfo2(number, event){console.log(number);console.log(event);}}})</script>
</body>
</html>
  1. 使用 v-on:xxx@xxx 绑定事件, xxx为事件名
  2. 事件的回调需要配置在 methods 对象中,最终会在 vm
  3. methods 中配置的函数,都是被 Vue 所管理的函数,this 的指向是 vm 或组件实例对象
  4. @click="demo"@click="demo($event)" 效果一致,但后者可以传递参数
  5. 绑定事件时,xxx 可以写一些简单的语句,不过最好在 methods 中写函数封装。

事件修饰符

  1. prevent : 阻止默认事件(常用)

    <!DOCTYPE html>
    <html lang="en">
    <head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>事件修饰符/title><script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body><div id="root"><h1>{{name}}</h1><a href="https://www.baidu.com" @click="showInfo">点击</a></div><script type="text/javascript">const vm = new Vue({el:'#root',data:{name:'hh',},methods:{showInfo(event){alert('你好')},}})</script>
    </body>
    </html>
    

    可以发现,a 标签的默认行为不会被执行

  2. stop : 阻止事件冒泡(常用)

    <script type="text/javascript">const vm = new Vue({el:'#root',data:{name:'hh',},methods:{showInfo(t){console.log(t);},}})
    </script>
    

    未添加阻止冒泡时

    <div id="root"><h1>{{name}}</h1><div @click="showInfo(1)"><button @click="showInfo(2)">点击</button></div>
    </div>
    

    image-20220805093803034

    阻止冒泡后

    <div id="root"><h1>{{name}}</h1><div @click="showInfo(1)"><button @click.stop="showInfo(2)">点击</button></div>
    </div>
    

    image-20220805093939494

  3. once: 事件只触发一次(常用)

    <div id="root"><h1>{{name}}</h1><div><button @click.once="showInfo(2)">点击</button></div>
    </div>
    

    多次点击后,只会执行一次 showInfo(2)

  4. capture: 使用事件的捕获模式

  5. self : 只有 event.target 是当前操作的元素时才触发事件

  6. passive :事件的默认行为立即执行,无需等待事件回调执行完毕

键盘事件

Vue 常用按键别名

image-20220805094420703

触发条件: keydownkeyup

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>键盘事件</title><script type="text/javascript" src="../js/vue.js"></script>
</head>
<body><div id="root"><input type="text" @keydown.tab="showInfo"></div><script type="text/javascript">const vm = new Vue({el:'#root',data:{name:'hh',},methods:{showInfo(e){console.log(e.target.value);},}})</script>
</body>
</html>

补充

组合按键: <input type="text" @keydown.ctrl.y="showInfo">

修饰符组合:

<div id="root"><h1>{{name}}</h1><div @click="showInfo(1)"><a href="https://baidu.com" @click.stop.prevent="showInfo(2)">点击</button></div></div>

不会跳转

image-20220805102131673

1.7 计算属性

基本使用

  1. 定义:要用的属性不存在,要通过已有属性计算得来
  2. 原理:底层借助了 Object.defineproperty 方法提供的 gettersetter
  3. get 函数什么时候执行?
    • 初次读取时会执行一次
    • 当计算属性所依赖的数据发生改变时会被调用
  4. 优势:与 methods 实现对比,内部有缓存机制(可复用),效率更高,调试方便
  5. 备注:
    • 计算属性最终会出现在 vm 上,直接读取使用即可
    • 如果计算属性被修改,那必须写 set 函数去响应修改,且 set 中要引起计算时依赖的属性的数据发生改变
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>计算属性</title><script type="text/javascript" src="../js/vue.js"></script>
</head>
<body><div id="root"><input type="text" v-model="firstName"><br/><input type="text" v-model="lastName"><br/><div><h3>{{fullName}}</h3></div></div><script type="text/javascript">const vm = new Vue({el:'#root',data:{firstName:'张',lastName:'三',},computed:{fullName:{get(){console.log('调用get函数')return this.firstName + '-' + this.lastName},set(value){console.log('调用set函数')const arr = value.split('-')    this.firstName = arr[0]this.lastName = arr[1]}}}})</script>
</body>
</html>

修改姓

image-20220805111415798

image-20220805111432175

修改计算属性

image-20220805111508199

image-20220805111503343

简写

计算属性只考虑读取,不考虑修改时,才可以进行简写

computed:{fullName(){console.log('调用get函数')return this.firstName + '-' + this.lastName}
}

1.8 监视属性

  1. 当被监视的属性变化时,回调函数自动调用,进行相关操作
  2. 监视的属性必须存在,才能进行监视
  3. 监视的两种写法:
    • new Vue 时传入 watch 配置
    • 通过 vm.$watch 监视

基本使用

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>监视属性</title><script type="text/javascript" src="../js/vue.js"></script>
</head>
<body><div id="root"><div><h2>今天天气很{{info}}</h2><button @click="change">点击切换天气</button></div></div><script type="text/javascript">const vm = new Vue({el:'#root',data:{ishot:true,},methods: {change(){this.ishot = !this.ishot}},computed:{info(){return this.ishot ? '炎热' : '凉爽'}},// 第一种写法watch:{ishot:{immediate:true, // 初始化时会被调用一次handler(newValue, oldValue){ // 当 ishot 被修改时会被调用console.log('ishot被修改', newValue, oldValue);}}}})// 第二种写法vm.$watch('ishot', {immediate:true,handler(newValue, oldValue){console.log('ishot被修改', newValue, oldValue);}})</script>
</body>
</html>

深度监视

  1. Vue 中的 watch 默认不监测对象内部值的改变(一层)
  2. 配置 deep:true 可以监测对象内部值改变(多层)

备注:

  1. Vue 自身可以监测到对象内部值的改变,但 Vue 提供的 watch 默认不可以
  2. 使用 watch 时根据数据的具体结构,决定是否采用深度监视
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>监视属性</title><script type="text/javascript" src="../js/vue.js"></script>
</head>
<body><div id="root"><div><h2 @click="number.a++">{{number.a}}</h2><h2 @click="number.b++">{{number.b}}</h2></div></div><script type="text/javascript">const vm = new Vue({el:'#root',data:{number:{a:1,b:1}},watch:{// 多级结构时写字符串形式'number.a':{handler(){console.log('a变化');}}}})</script>
</body>
</html>

此时点击 a 会输出 a变化

watch:{number:{deep:true, // 深度监视配置deep属性handler(){console.log('number变化');}}
}

简写

wathch 配置项只有 handler 时可以简写

vm.$watch('ishot',function(newValue, oldValue){console.log('ishot被修改', newValue, oldValue)
})
watch:{ishot(newValue, oldValue){console.log('ishot被修改', newValue, oldValue);}
}

Watch vs Computed

二者区别:

  1. computed 能完成的功能,watch 都能完成
  2. watch 能完成的功能,computed 不一定能完成,例如:watch 可以进行异步操作

两个重要的小原则:

  1. Vue 管理的函数,最好写成普通函数,这样 this 的指向才是 vm 或组件实例对象
  2. 所有不被 Vue 管理的函数(定时器的回调函数、ajax的回调函数、promise的回调函数等),最好写成箭头函数,这样 this 的指向才是 vm 或 组件实例对象

1.9 绑定class和style

class

基本写法

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>绑定样式</title><script type="text/javascript" src="../js/vue.js"></script><style>.happy{background-color: red;}.sad{background-color: blue;}.normal{background-color: wheat;}.basic{height: 100px;width: 200px;border: solid red 1px;}</style>
</head>
<body><div id="root"><div class="basic" :class="css" @click="change"></div></div><script type="text/javascript">const vm = new Vue({el:'#root',data:{css:'normal'},methods: {change(){styles = ['normal', 'sad', 'happy']this.css = styles[Math.floor(Math.random()*3)]}},})</script>
</body>
</html>

以上示例可以通过点击实现样式随机切换

和绑定属性值类似

:class="xxx"

xxx 可填变量,数组或对象

数组:

<body><div id="root"><div class="basic" :class="arr"></div></div><script type="text/javascript">const vm = new Vue({el:'#root',data:{css:'normal',arr:['normal', 'sad', 'happy'],},methods: {},})</script>
</body>

对象:

<body><div id="root"><div class="basic" :class="cssObj"></div></div><script type="text/javascript">const vm = new Vue({el:'#root',data:{cssObj:{'normal':true, // 使用 normal样式'sad':false,'happy':false,}},})</script>
</body>

style

原始写法

<div class="basic" style="font-size: 50px;">你好</div>

绑定后

<div class="basic" :style="{fontSize: size + 'px'}">你好</div>

image-20220806103853268

image-20220806103912733

对象写法

data:{styleObj:{fontSize: '60px',color: 'green',backgroundColor: 'yellow'}
},

前面的 key 不能乱写,一个单词正常写,两个单词用 - 连接的需要将第二个单词首字母大写,然后去掉 -

image-20220806104143764

style中也可以写 数组,但不常用

1.10 条件渲染

  1. v-if
    • 写法:
      1. v-if="表达式"
      2. v-else-if="表达式"
      3. v-else="表达式"
    • 适用于:切换频率较低的场景
    • 特点:不展示的 DOM 元素直接被移除
    • 注意:v-if 可以和 v-else-ifv-else 一起使用,但要求结构不能被打断
  2. v-show
    • 写法:v-show="表达式"
    • 适用于:切换频率较高的场景
    • 特点:不展示的 DOM 元素未被移出,仅仅是使用样式隐藏掉
  3. 备注:使用 v-if 时,元素可能无法获取到,而使用 v-show 时一定可以获取到
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>条件渲染</title><script type="text/javascript" src="../js/vue.js"></script>
</head>
<body><div id="root"><h1 v-show="0">你好</h1><h1 v-if="1 === 3">hello</h1></div><script type="text/javascript">const vm = new Vue({el:'#root',data:{},})</script>
</body>
</html>

image-20220806110424753

1.11 列表渲染

v-for 指令

  1. 用于展示列表数据
  2. 语法:v-for="(item, index) in xxx" :key="yyy"
  3. 可遍历:数组、对象、字符串(使用较少)、指定次数(使用较少)
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>列表渲染</title><script type="text/javascript" src="../js/vue.js"></script>
</head>
<body><div id="root"><ul><li v-for="(val, k) in persons" :key="k">{{val.name}}--{{val.age}}</li></ul></div><script type="text/javascript">const vm = new Vue({el:'#root',data:{persons:[{'name':'wy', 'age':20},    {'name':'wm', 'age':16},{'name':'xx', 'age':10},]}})</script>
</body>
</html>

Key作用

image-20220806123457645

列表过滤

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>列表过滤</title><script type="text/javascript" src="../js/vue.js"></script>
</head>
<body><div id="root"><input type="text" v-model="keyword"><ul><li v-for="(val, k) in persons_fill" :key="k">{{val.name}}--{{val.age}}</li></ul></div><script type="text/javascript">// const vm = new Vue({//     el:'#root',//     data:{//         keyword:'',//         persons:[//             {'name':'wyy', 'age':20},    //             {'name':'wmx', 'age':16},//             {'name':'xxw', 'age':10},//             {'name':'adsf', 'age':20},    //             {'name':'vcx', 'age':16},//             {'name':'xwe', 'age':10},//             {'name':'wyy', 'age':20},    //             {'name':'wmx', 'age':16},//             {'name':'xxw', 'age':10},//             {'name':'adsf', 'age':20},    //             {'name':'vcx', 'age':16},//             {'name':'xwe', 'age':10},//         ],//         persons_fill:[//         ]//     },//     watch:{//         keyword:{//             immediate:true,//             handler(val){//                 this.persons_fill = this.persons.filter((p)=>{//                     return p.name.indexOf(val) !== -1//                 })//             }//         }//     }// })const vm = new Vue({el:'#root',data:{keyword:'',persons:[{'name':'wyy', 'age':20},    {'name':'wmx', 'age':16},{'name':'xxw', 'age':10},{'name':'adsf', 'age':20},    {'name':'vcx', 'age':16},{'name':'xwe', 'age':10},{'name':'wyy', 'age':20},    {'name':'wmx', 'age':16},{'name':'xxw', 'age':10},{'name':'adsf', 'age':20},    {'name':'vcx', 'age':16},{'name':'xwe', 'age':10},],},computed:{persons_fill(){return this.persons.filter((p)=>{return p.name.indexOf(this.keyword) !== -1})}}})</script>
</body>
</html>

测试结果:

image-20220806131131980

列表排序

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>列表排序</title><script type="text/javascript" src="../js/vue.js"></script>
</head>
<body><div id="root"><h1>人员列表</h1><input type="text" v-model="keyword"><button @click="sortType = 1">升序</button><button @click="sortType = 2">降序</button><button @click="sortType = 0">原序</button><ul><li v-for="(val, k) in persons_fill" :key="k">{{val.name}}--{{val.age}}</li></ul></div><script type="text/javascript">const vm = new Vue({el:'#root',data:{keyword:'',sortType:0,persons:[{'name':'wyy', 'age':20},    {'name':'wmx', 'age':16},{'name':'xxw', 'age':10},{'name':'adsf', 'age':20},    {'name':'vcx', 'age':16},{'name':'xwe', 'age':10},{'name':'wyy', 'age':20},    {'name':'wmx', 'age':16},{'name':'xxw', 'age':10},{'name':'adsf', 'age':20},    {'name':'vcx', 'age':16},{'name':'xwe', 'age':10},],},computed:{persons_fill(){const a = this.persons.filter((p)=>{return p.name.indexOf(this.keyword) !== -1})if (this.sortType){a.sort((a, b)=>{return this.sortType === 1 ? a.age - b.age : b.age - a.age;})}return a;}}})</script>
</body>
</html>

测试结果:

image-20220807093103341

升序和降序

image-20220807093203721

image-20220807093210080

模拟Vue进行数据监测(对象)

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>模拟数据监测</title><script type="text/javascript" src="../js/vue.js"></script>
</head>
<body><div id="root"></div><script type="text/javascript">let data = {name:'wy',age:23,}// 创建一个监视的实例对象,用于监视data中属性的变化const obs = new Observer(data)let vm = {}vm._data = data = obsfunction Observer(obj) {const keys = Object.keys(obj)// 汇总对象中所有属性形成一个数组keys.forEach((k)=>{Object.defineProperty(this, k, {get(){return obj[k]},set(val){obj[k] = val}})})}</script>
</body>
</html>

测试结果

image-20220807101633970

Vue.set使用

Vue 中添加属性

注意:tartget 不能为 vm 本身或者 vm._data

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Vue.set使用</title><script type="text/javascript" src="../js/vue.js"></script>
</head>
<body><div id="root"><h1>name: {{name}}</h1><h1>age: {{age}}</h1><h2>school</h2><h3>name: {{school.name}}</h3><h3 v-if="school.loc">loc: {{school.loc}}</h3></div><script type="text/javascript">const vm = new Vue({el:'#root',data:{name:'wy',age:18,school:{name:'zzu',}}})</script>
</body>
</html>

方式一:

Vue.set(vm.school, 'loc', 'zz')

方式二:

vm.$set(vm.school, 'loc', 'zz')

执行结果:

image-20220807103941825

Vue监测数组

image-20220807114034420

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>模拟数据监测数组</title><script type="text/javascript" src="../js/vue.js"></script>
</head>
<body><div id="root"><h1>爱好</h1><ul><li v-for="(val, k) in hobby" :key="k">{{val}}</li></ul></div><script type="text/javascript">const vm = new Vue({el:'#root',data:{hobby:['听音乐', '打游戏', '唱歌', '跑步']}})</script>
</body>
</html>

数组中的元素没有 gettersetter 方法

image-20220807113100914

直接使用数组下标对其修改在页面上不会体现效果

vm._data.hobby[0] = '睡觉'

Vue 将被侦听的数组的变更方法进行了包裹,所以它们也将会触发视图更新。这些被包裹过的方法包括:

  • push()

  • pop()

  • shift()

  • unshift()

  • splice()

    vm.hobby.splice(0, 1, '吃饭')
    
  • sort()

  • reverse()

1.12 收集表单数据

image-20220807115903853

实例

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>收集表单数据</title><script type="text/javascript" src="../js/vue.js"></script>
</head>
<body><div id="root" @submit.prevent="submit"><form><div>账户: <input type="text" v-model.trim="userinfo.username"></div><div>密码: <input type="password" v-model="userinfo.password"></div><div>性别: 男<input type="radio" name="sex" v-model="userinfo.sex" value="male"><input type="radio" name="sex" v-model="userinfo.sex" value="female"></div><div>年龄: <input type="number" v-model.number="userinfo.age"></div><div>爱好:<input type="checkbox" v-model="userinfo.hobby" value="eat">吃饭<input type="checkbox" v-model="userinfo.hobby" value="sleep">睡觉<input type="checkbox" v-model="userinfo.hobby" value="drink">喝酒<input type="checkbox" v-model="userinfo.hobby" value="gameing">打游戏</div><div>其他: <textarea name="" id="" cols="30" rows="10" v-model.lazy="userinfo.other"></textarea></div><button>提交</button></form></div><script type="text/javascript">const vm = new Vue({el:'#root',data:{userinfo:{username:'',password:'',sex:'',age:'',hobby:[],other:'',}},methods: {submit(){console.log(JSON.stringify(this.userinfo));}},})</script>
</body>
</html>

1.13 过滤器

**定义:**对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理)

语法:

  1. 注册过滤器:Vue.filter(name, callback) 或 new Vue{filters:{}}
  2. 使用过滤器:{{ xxx | 过滤器名 }} 或 v-bind:属性 = "xxx | 过滤器名"

备注:

  1. 过滤器也可以接收额外参数、多个过滤器也可以串联
  2. 并没有改变原本的数据,是产生新的对应数据

实例:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>过滤器</title><script type="text/javascript" src="../js/vue.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/dayjs/1.11.4/dayjs.min.js"></script>
</head>
<body><div id="root"><h1>显示当前日期和时间</h1><h2>{{ time | getTime }}</h2><h1>显示时间</h1><h2>{{ time | getTime('HH:mm:ss') }}</h2><h1>属性绑定</h1><h2 :x="time | getTime">你好</h2><h1>截取前4位</h1><h2>{{ time | getTime | slice(0, 4) }}</h2></div><script type="text/javascript">const vm = new Vue({el:'#root',data:{time:1659925371764},methods:{},filters:{getTime(value, str='YYYY年MM月DD日 HH:mm:ss'){return dayjs(value).format(str)},slice(str, st=0, ed=0) {return str.slice(st, ed)}}})</script>
</body>
</html>

全局注册

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>过滤器</title><script type="text/javascript" src="../js/vue.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/dayjs/1.11.4/dayjs.min.js"></script>
</head>
<body><div id="root"><h1>显示当前日期和时间</h1><h2>{{ time | getTime | slice(0, 4) }}</h2><h1>显示时间</h1><h2>{{ time | getTime('HH:mm:ss') }}</h2><h1>属性绑定</h1><h2 :x="time | getTime">你好</h2><h1>截取前4位</h1><h2>{{ time | getTime | slice(0, 4) }}</h2></div><script type="text/javascript">Vue.filter('getTime', function(value, str='YYYY年MM月DD日 HH:mm:ss'){return dayjs(value).format(str)})Vue.filter('slice', function(str, st=0, ed=0){return str.slice(st, ed)})const vm = new Vue({el:'#root',data:{time:1659925371764},methods:{},})</script>
</body>
</html>

image-20220808103707923

1.14 内置指令

v-text

  1. 作用:向其所在节点中渲染文本内容
  2. 与插值语法的区别:v-text 会替换掉节点的内容,{{xx}} 不会

v-html

  1. 作用:向指定节点中渲染包含html结构的内容
  2. 与插值语法的区别:
    1. v-html 会替换掉节点中所有内容,{{xxx}} 不会
    2. v-html 可以识别为html结构
  3. 严重注意:v-html 有安全性问题
    1. 在网站上动态渲染任意 html 是非常危险的,容易导致 XSS 攻击
    2. 一定在可信的内容上使用 v-html ,永远不要用在用户提交的内容上

v-cloak

  1. 本质是一个特殊的属性,Vue实例创建完毕并接管容器后,会删掉 v-cloak 属性
  2. 使用 css 配合 v-cloak 可以解决网速慢时页面展示出 {{xxx}} 的问题

实例

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>v-cloak</title><script type="text/javascript" src="../js/vue.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/dayjs/1.11.4/dayjs.min.js"></script><style>[v-cloak]{display: none;}</style>
</head>
<body><div id="root"><h1 v-cloak>{{name}}</h1></div><script type="text/javascript">Vue.filter('getTime', function(value, str='YYYY年MM月DD日 HH:mm:ss'){return dayjs(value).format(str)})Vue.filter('slice', function(str, st=0, ed=0){return str.slice(st, ed)})const vm = new Vue({el:'#root',data:{name:'张三'}})</script>
</body>
</html>

v-once

  1. v-once 所在节点在初次动态渲染后,就视为静态内容了
  2. 以后数据的改变不会引起 v-once 所在结构的更新,可以用于优化性能

v-pre

  1. 跳过其所在节点的编译过程
  2. 可利用它跳过节点:没有使用指令语法、没有使用插值语法的节点,加快编译
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>v-cloak</title><script type="text/javascript" src="../js/vue.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/dayjs/1.11.4/dayjs.min.js"></script></head>
<body><div id="root"><h1 v-pre @click="name += '1'">{{name}}</h1></div><script type="text/javascript">Vue.filter('getTime', function(value, str='YYYY年MM月DD日 HH:mm:ss'){return dayjs(value).format(str)})Vue.filter('slice', function(str, st=0, ed=0){return str.slice(st, ed)})const vm = new Vue({el:'#root',data:{name:'张三'}})</script>
</body>
</html>

1.15 自定义指令

image-20220808125006778

注意自定义命令中的 this 是 Windows

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>自定义指令</title><script type="text/javascript" src="../js/vue.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/dayjs/1.11.4/dayjs.min.js"></script></head>
<body><div id="root"><h1>{{n}}</h1><button @click="n++">点击</button><input type="nubmer" v-fbind="n"></div><script type="text/javascript">Vue.filter('getTime', function(value, str='YYYY年MM月DD日 HH:mm:ss'){return dayjs(value).format(str)})Vue.filter('slice', function(str, st=0, ed=0){return str.slice(st, ed)})const vm = new Vue({el:'#root',data:{n:1,},directives:{// fbind(element, binding){//     console.log(element, binding);//     element.value = binding.value;//     element.focus() // 在第一次绑定时,还没有将所在元素插入页面中,因此不会生效// }fbind:{bind(elem, binding){console.log('bind');elem.value = binding.value},inserted(elem, binding){console.log('inserted');elem.focus()},update(elem, binding){console.log('update');elem.value = binding.value}}}})</script>
</body>
</html>

1.16 生命周期

  1. 又名:生命周期回调函数、生命周期函数,生命周期钩子
  2. 是什么:Vue 在关键时期帮我们调用的一些特殊函数
  3. 生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的
  4. 生命周期函数中的 this 指向的是 vm 或组件实例对象
生命周期
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>生命周期</title><script type="text/javascript" src="../js/vue.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/dayjs/1.11.4/dayjs.min.js"></script></head>
<body><div id="root"><h1 :style="{opacity}">Hello, World!</h1></div><script type="text/javascript">const vm = new Vue({el:'#root',data:{opacity:1},mounted() {setInterval(()=>{this.opacity -= 0.01if (this.opacity <= 0) this.opacity = 1}, 16)},})</script>
</body>
</html>

常用的生命周期钩子:

  1. mounted: 发送 ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】
  2. beforeDestroy: 清除定时器、解绑自定义事件取消订阅消息等【收尾工作】

关于销毁 Vue 实例

  1. 销毁后借助 Vue 开发工具看不到任何信息
  2. 销毁后自定义事件会失败,但原生DOM事件依然有效
  3. 一般不会在 beforedestroy操作数据,因为即便操作数据,也不会触发更新流程了
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>生命周期</title><script type="text/javascript" src="../js/vue.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/dayjs/1.11.4/dayjs.min.js"></script></head>
<body><div id="root"><h1 :style="{opacity}">Hello, World!</h1><button @click="hack">点击销毁vm实例</button></div><script type="text/javascript">const vm = new Vue({el:'#root',data:{opacity:1},methods: {hack(){this.$destroy()}},beforeCreate() {console.log('beforeCreate');},created() {console.log('created');},beforeMount() {console.log('beforeMount');},mounted() {console.log('mounted');setInterval(()=>{this.opacity -= 0.01if (this.opacity <= 0) this.opacity = 1}, 16)},beforeUpdate() {console.log('beforeUpdate')},updated() {console.log('updated');            },beforeDestroy() {console.log('beforeDestroy');},destroyed() {console.log('destroyed');},})</script>
</body>
</html>

参考资料

尚硅谷Vue2.0+Vue3.0全套教程丨vuejs从入门到精通
https://www.bilibili.com/video/BV1Zy4y1K7SH?p=15&share_source=copy_web&vd_source=d3c9ceb0642f45fbe95f795c0d074040

Vue 官方文档

https://cn.vuejs.org/v2/guide/

Vue api 文档

https://cn.vuejs.org/v2/api/


http://chatgpt.dhexx.cn/article/LPWtdJEb.shtml

相关文章

JavaScript总结(二:基础知识)

HTML中如何使用JavaScript&#xff1f; HTML要想使用JavaScript&#xff0c;首先自己要拥有它&#xff0c;有了才可以用&#xff0c;就好像我们学习一样&#xff0c;先要认&#xff0c;后才知&#xff0c;好了废话不多说了&#xff0c;下面进入这个问题的解答过程。 JavaScript…

android.database.sqlite.SQLiteException: no such column:xxxxx

今天在使用sql语句删除数据时报了android.database.sqlite.SQLiteException: no such column:xxxxx&#xff0c;令人奇怪的是删除的数据是int类型的却没报错&#xff0c;代码如下 if ((list.get(j)).equals(list_delete.get(i))) {db.execSQL("delete from TotalData whe…

(AD FS 配置完全说明)图文说明 SharePoint 2013 配置AD FS

图文说明 SharePoint 2013 配置AD FS 前提是已经安装成功AD FS服务&#xff0c;下面开始配置&#xff1a; 为信赖方配置 AD FS 使用有管理员权限的帐号。 在 AD FS 服务器上&#xff0c;打开 Active Directory 联合身份验证服务 (AD FS) 管理控制台。 在导航窗格中展开“信任…

在Azure中部署AD FS

AD FS提供简化安全的身份联合验证和Web SSO。 ADFS和Azure AD O365联合起来的话&#xff0c;用户就可以拿本地的凭据来访问云上的所有资源。所以&#xff0c;ADFS就将本地资源和云上资源整合起来&#xff0c;至关重要。 ADFS部署在Azure上有以下有点&#xff1a; 高可用&…

Python中的Unicode编码和UTF-8编码

下午看廖雪峰的Python2.7教程&#xff0c;看到 字符串和编码 一节&#xff0c;有一点感受&#xff0c;结合 崔庆才的Python博客 &#xff0c;把这种感受记录下来&#xff1a; ASCII码&#xff1a;是用一个字节&#xff08;8bit&#xff0c; 0-255&#xff09;中的127个字母表示…

01、ADS新建工程后初始设置

为了避免版图报错&#xff0c;需要在ADS新建工程之后进行一些初始设置 Option→Technology→Technology Setup... 此时可以看到已经不报错了

Windows Server 2012 AD域控搭建-系统安装及环境配置

一、安装系统 首先https://msdn.itellyou.cn&#xff0c;去下载系统。 刻录到U盘省略&#xff0c;创建虚拟机步骤省略&#xff0c;直接进入安装步骤&#xff1a; 选择带标准版&#xff0c;带GUI的服务器安装 后面选择硬盘即可 等等等&#xff0c;完成后设置密码&#xff0c;一…

论文阅读ICLR2020《ADAPTIVE STRUCTURAL FINGERPRINTS FOR GRAPH ATTENTION NETWORKS》

论文阅读ICLR2020《ADAPTIVE STRUCTURAL FINGERPRINTS FOR GRAPH ATTENTION NETWORKS》 摘要确定节点相似性时图的结构Adaptive Structural Fingprients&#xff08;ADSF&#xff09;模型介绍结果分析原作CONCLUSION AND FUTURE WORK论文 摘要 观点&#xff1a;如何利用注意力…

MDC300的ADSFI框架介绍

文章目录 什么是ADSFI框架&#xff1f;ADSFI应用框架图MDC300上有哪些ADSFI框架&#xff1f;各个ADSFI框架的联系单个ADSFI框架的构成单个ADSFI框架中的yaml文件 什么是ADSFI框架&#xff1f; ADSFI&#xff08;Autonomous Driving Service Framework Initiative&#xff09; …

论文阅读笔记(4-2)---吴恩达DNN算法分析和仿真实现

算法开发 该深度卷积神经网络以原始心电图数据&#xff08;以200Hz或每秒200个样本为样本&#xff09;作为输入&#xff0c;并且每256个样本&#xff08;或每1.28秒&#xff09;生成一个预测&#xff0c;我们称之为输出间隔。网络仅以原始心电图样本为输入&#xff0c;网络架构…

LightGBM的基本原理以及使用

LightGBM的基本原理以及使用 LightGBM的基本原理 LightGBM是一款常用的GBDT工具包&#xff0c;由微软亚研院开发&#xff0c;速度比XGBoost快&#xff0c;精度稍低 。他的设计理念是&#xff1a;1.单个机器在不牺牲速度的情况下&#xff0c;尽可能使用上更多的数据。2.多机并…

从心电信号分类过渡到心音信号分类

首先刚接手这种关于信号的分类问题&#xff0c;以下可能会有不对的地方&#xff0c;接下去通过学习会对不正确的地方进行更正或者补充。 心电信号分类参考文献&#xff1a;Cardiologist-LevelArrhythmiaDetectionwithConvolutionalNeuralNetworks目标&#xff1a;对传感器采集…

LightGBM调参

GBDT模型的另一个进化版本&#xff1a;LightGBM。LigthGBM是boosting集合模型中的新进成员&#xff0c;由微软提供&#xff0c;它和XGBoost一样是对GBDT的高效实现&#xff0c;原理上它和GBDT及XGBoost类似&#xff0c;都采用损失函数的负梯度作为当前决策树的残差近似值&#…

XGBoost调参步骤及常见问题

XGBoost xgboost中的基学习器除了可以是CART&#xff08;gbtree&#xff09;也可以是线性分类器&#xff08;gblinear&#xff09; xgboost在目标函数中显示的加上了正则化项&#xff0c;基学习为CART时&#xff0c;正则化项与树的叶子节点的数量T和叶子节点的值有关。 正则项…

LightGBM原理介绍

简介 是GBDT模型的一个进化版本&#xff0c;其主要思想是利用弱分类器&#xff08;决策树&#xff09;迭代训练以得到最优模型&#xff0c;该模型具有训练效果好、不易过拟合等优点&#xff08;备注&#xff1a;容易出现过拟合的风险&#xff0c;需要限制树的最大深度来防止过…

lightbgm参数_参数调优LightGBM-商品分类-代码

1.直接调用LightGBM内嵌的cv寻找最佳的参数n_estimators(弱分类器数目) Otto商品分类数据 导入必要模型import lightgbm as lgbm import pandas as pd import numpy as np from sklearn.model_selection import GridSearchCV from sklearn.model_selection import StratifiedKF…

Xgboost回归四种调参方法及Python简单实现

前言 Xgboost对特征工程和数据处理比较友好&#xff0c;相比之下调参成为用好Xgboost重要的一环&#xff0c;本文分别从参数、调参方法、Python实现的维度进行梳理&#xff0c;作为调参思路的记录。 本文将关注以下几个问题&#xff1a; 1.Xgboost哪些参数需要调参&#xff…

Python机器学习10——梯度提升

本系列所有的代码和数据都可以从陈强老师的个人主页上下载&#xff1a;Python数据程序 参考书目&#xff1a;陈强.机器学习及Python应用. 北京&#xff1a;高等教育出版社, 2021. 本系列基本不讲数学原理&#xff0c;只从代码角度去让读者们利用最简洁的Python代码实现机器学…

【机器学习】集成学习代码练习

课程完整代码&#xff1a;https://github.com/fengdu78/WZU-machine-learning-course 代码修改并注释&#xff1a;黄海广&#xff0c;haiguang2000wzu.edu.cn import warnings warnings.filterwarnings("ignore") import pandas as pd from sklearn.model_selection …

Keras 1.0 与 2.0 中 Convolution1D 的区别(其实是tf1.0 2.0 区别)

1.0 Convolution1D: 一维卷积层 nb_filter: 卷积核的个数 filter_length: 每个卷积核的长度 init: 权重初始化函数名称 weights: 权重初始化 border_mode: valid, same or full 如果是‘valid ’ 进行有效的卷积&#xff0c;对边界数据不处理&#xff0c;‘same表示保留…