赞
踩
作用:动态绑定一个或多个属性,属性值是一个动态的【值是依赖于data中的数据源】
使用方式:
<!-- v-bind绑定href属性值 -->
<a v-bind:href='url'>跳转</a>
<!-- v-bind绑定href属性值(简写形式) -->
<a :href='url'>跳转</a>
绑定
1.对象绑定
– html代码
<ul class='app' :class="{'Fone':isOne, 'Ftwo':isTwo}"></ul>
– js代码
var vue = new Vue({
el:'.app',
data:{
isOne:true,
isTwo:true
}
})
最终渲染为
<ul class='app Fone Ftwo' ></ul>
当data里的 isOne 或 isTwo 变化时,class列表会相应更新
以上代码等价于
// html代码
<ul class='app' :class="classObject"></ul>
// js代码
var vue = new Vue({
el:'.app',
data:{
classObject:{
'Fone':true,
'Ftwo':true
}
}
})
2.数组语法
— html代码
<ul class="box" :class="[classA, classB]"></ul>
— js代码
var vm= new Vue({
el:'.box',
data:{
classA:'Fone',
classB:'Ftwo'
}
})
补充
可以使用三目运算符
— html代码
<ul class="box" :class="[isA ? classA:'', classB]"></ul>
— js代码
var vm= new Vue({
el:'.box',
data:{
classA:'Fone',
classB:'Ftwo'
isA:false
}
})
:属性=“data中的属性数据/methods/props/computed”
:属性=“js表达式环境,认为它就是可以直接写js了,字符串相关就要用引号”
— html代码
<a :href="`http://www.baidu.com?id=${id}`">百度一下</a>
<hr>
<a :href="`http://www.baidu.com?id=`+id">百度一下</a>
— js代码
const app = new Vue({
el: '#app',
data: {
url: 'http://img.1314000.cn/face.png',
id: 100
},
})
— html代码
<div id="box" :style="{color:activeColor, fontSize:size, textShadow:shadow}">社恐泡面</div>
— js代码
var vm= new Vue({
el:'#box',
data:{
activeColor:'#f00',
size:'30px',
shadow:'5px 2px 6px #000'
}
})
或者
— html代码
<div id="box" :style="styleObject">社恐泡面</div>
— js代码
var vm= new Vue({
el:'#box',
data:{
styleObject:{
color:'red',
fontSize:'30px'
}
}
})
2.数组语法
举个栗子
— html代码
<div id="app">
<!-- 样式class它也是属性,动态属性 :class="对象|数组" -->
<h3 class="title" :class="activeObj">我是一个标题</h3>
<!-- 数组 -->
<!--
如果新增样式,则默认情况下,对象无法直接生效,而数组可以生效
如果对已有的样式,进行开关操作,建议用对象
-->
<!-- <h3 :class="activeArr">我是一个标题</h3> -->
<button @click="setActive">让标题高亮</button>
</div>
— js代码
const app = new Vue({ el: '#app', data: { // 对象的方式,key,定义的的style中的样式名称 activeObj: { active: true, font: true }, // 数组中的元素就是样式名 activeArr: [] }, methods: { setActive() { // Object.defineProperty // this.activeObj.active = true // this.activeObj.font = true // this.activeObj = { active: false, font: true } // this.activeObj = { ...this.activeObj, font: true } // Object方法完成对象的合并,返回一个新对象,引用地址不同 // this.activeObj = Object.assign({},this.activeObj,{font: true}) // vue2中为了解决Object.defineProperty动态添加属性无法监听问题,提供一个成员方法 $set // 参数1:对象是谁 // 参数2:属性名称 // 参数3:值 // 推荐 // this.$set(this.activeObj, 'font', true) // 触发视图更新 // this.$delete(this.activeObj, 'font') // this.activeArr.length == 0 ? this.activeArr.push('active') : this.activeArr.pop() // this.activeArr.push('font') } } })
设置内联样式
— html代码
<div id="app">
<!-- 内联样式,它的优先级更高,一般用于已有样式的覆盖 -->
<div :style="styleObj">我是style样式 -- 对象</div>
<hr>
<div :style="styleArr">我是style样式 -- 数组</div>
</div>
— js代码
const app = new Vue({
el: '#app',
data: {
// styleObj: { color: 'red', fontSize: '50px' }
styleObj: { color: 'red', 'font-size': '50px' },
styleArr: [{ color: 'blue' }, { fontSize: '30px' }]
}
})
— html代码
<img :src="getImg()" alt="">
— js代码
const app = new Vue({
el: '#app',
data: {
url: 'http://img.1314000.cn/face.png',
id: 100
},
methods: {
getImg() {
return 'http://img.1314000.cn/face.png'
}
}
})
注意: 有()
用于循环取出列数中的数据
语法:v-for="(item,index) in/of 数组"
语法:v-for="(item,key,index) in/of 对象"
注:
v-for中建议在迭代时,最好是给第个迭代的元素添加一个唯一不重复的key值,以达到提升性能
key值尽量不要用index索引导它的key值,index索引,如果目标增加或删除,则会触发index值的变化,这样达不到性能优化,index塌陷
今后在和后端合作,通过请求接口拿数据时,一定要确保拿过来数据中一定要有id值
如果你指定了key,新key在的节点中找不到,则创建,旧的key如果在新的节点中找不到,删除
使用:
— html代码
<div id="app">
<ul>
<!-- <li v-for="item,index of users" :key="index"> -->
<li v-for="item,index of users" :key="item">
<span>{{index}}</span>
<span>{{item}}</span>
</li>
</ul>
<hr>
<!-- 迭代对象方案,在工作中很少有,了解就可以,如果用到知道它可以就可以 -->
<div v-for="item,key,index in info">
{{key}} -- {{index}} -- {{item}}
</div>
</div>
— js代码
const app = new Vue({
el: '#app',
data: {
users: [
// {id:1,name:'张三'}
'张三',
'李四',
'王五'
],
info: { id: 1, name: '赵六', age: 100 }
}
})
事件绑定:v-on:事件名="绑定的方法" : vue中的绑定的方法可以加小括号也可以不加括号
绑定的方法定义的位置:data/methods,推荐写在methods
因为事件绑定在工作中经常用,简单 @事件名="方法" 【h函数中 onClick】
如果你的绑定的方法,需要传实现的参数,则写小括号,如果还用到事件对象,则手动传一下,一般我们手动传的事件对象,都写在第1个形参
试一试
— html代码
<div id="app">
<h3>{{num}}</h3>
<!-- <button v-on:click="addNum">++++</button> -->
<!-- <button @click="addNum">++++</button> -->
<!-- <button @click="addNum($event,2)">++++</button> -->
<button @click="addNum(2)">++++</button>
<hr>
<input type="text" @keyup="onEnter">
</div>
— js代码
const app = new Vue({ el: '#app', data: { num: 100 }, methods: { // addNum(evt, n) { // console.log(evt); // this.num += n // } addNum(n) { this.num += n }, onEnter(evt) { // console.log(evt) // 如果我是回车,则获取数据 if ('Enter' === evt.key) { console.log(evt.target.value) evt.target.value = '' } } } })
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xtn3gZvZ-1668606202270)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\1668568835001.png)]
— html代码
<div id="app">
<div @click="click">
<!-- 阻止冒泡 stop -->
<div @click.stop="click">我是一个点击事件</div>
</div>
<!-- 绑定keyup的额组合按键 ctrl+enter -->
<input type="text" @keyup.ctrl.enter="onEnter">
<hr>
<!-- 阻止默认行为 prevent -->
<a href="http://www.baidu.com" @click.prevent="gourl">百度</a>
</div>
— js代码
const app = new Vue({ el: '#app', data: { }, methods: { onEnter(evt) { console.log(evt.target.value) }, click() { console.log('click'); }, gourl() { console.log('百度一下'); } } })
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dyrLOp7z-1668606202272)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\1668605424230.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sgEtdXfG-1668606202273)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\1668605439477.png)]
vue中一个语法糖:快捷方式
v-model: 绑值 事件 ==> 双向数据绑定
text/radio/checkbox ==> value/input checked/change
title它是在data中定义的数据
受控组件
<input type="text" :value="title" @input="onInput">
<input type="text" v-model="title">
举个栗子
— html代码
<div id="app"> <input type="text" v-model="title"> <hr> <!-- 多行文本 --> <textarea v-model="intro"></textarea> <hr> <!-- 单个复选框 全选 、记住登录、声明确认 -- 状态只有两个 true/false --> <!-- false则不选中,为true选中 事件和状态修改 --> <input type="checkbox" v-model="checked" @change="changeHandle"> <hr> <ul> <li v-for="item of targetCourse"> <label> <input type="checkbox" :value="item.id" v-model="course" @change="changeOneHandle"> {{item.title}} </label> </li> </ul> <hr> <div> <input type="radio" value="1" v-model="sex">先生 <input type="radio" value="2" v-model="sex">女士 </div> <hr> <select v-model="city" @change="aa"> <option value="0">请选择所在城市</option> <option value="1">芜湖</option> <option value="2">杭州</option> <option value="3">南京</option> </select> <select v-model="region"> <option value="10">镜湖区</option> <option value="11">鸠江区</option> </select> <button @click="login">提交信息</button> </div>
— js代码
const app = new Vue({ el: '#app', data: { title: 'aa', intro: 'bb', // 单个复选框,用boolean checked: false, // 多个复选框,array,数组中的元素值,和value值相同时,则界面中选中 course: [], targetCourse: [ { id: 1, title: '浠浠呀小白入门' }, { id: 2, title: '浠浠呀你不知道的js' }, { id: 3, title: 'kerwin老师精品大师' }, ], sex: '2', city: '1', region: '' }, methods: { login() { console.log({ ...this.$data }); }, changeHandle() { let course = [] if (this.checked) { course = this.targetCourse.map(({ id }) => id) } this.course = course }, changeOneHandle(){ this.checked = this.course.length==this.targetCourse.length ? true : false; }, aa() { console.log(this.city); } } })
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fCmofASN-1668606202273)(C:\Users\dell\AppData\Roaming\Typora\typora-user-images\1668605832908.png)]
— html代码
<div id="app"> <!-- v-model修饰符 .number把表单项中的字符串转为数字, 如果你的字符是以数字开头,则转为数字,如果不能转为数字,则不转 --> <input type="text" v-model.number="n1"> + <input type="number" v-model.number="n2"> <button @click="onCalc">结果</button> {{sum}} <hr> <!-- 去除两边空格 --> <input type="text" v-model.trim="title"> <!-- 延时更新,优化用 --> <input type="text" v-model.trim.lazy="title"> </div>
— js代码
const app = new Vue({ el: '#app', data: { n1: 1, n2: 2, sum: 3, title: '' }, methods: { onCalc() { // this.sum = +this.n1++this.n2 // this.sum = Number(this.n1) + Number(this.n2) this.sum = this.n1 + this.n2 } } })
除了用内置的指令完成vue工作需要后,还可以根据vue提供的方案完成自定义指令 自定义指令:操作dom dom对象.style.color='red' 自定义指令它提供了5个钩子函数,它可以帮我们实现所需要的各种业务场景 el 当前绑定到指令元素的dom对象,bindings 修饰符和传入的值 bind 第一次绑定到元素时调用 inserted 被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中) update 数据更新时调用 componentUpdated 指令所在组件的 VNode 及其子 VNode 全部更新后调用。 unbind 只调用一次,指令与元素解绑时调用。 // 定义自定义指令有两种方案 // 1.全局 --- 本项目中所有的组件都能使用 // 2.局部 --- 当前组件可以用 注:自定义指令中不能使用 this来获取 new Vue组件中的data和方法
举个栗子–定义主题颜色
— html代码
<div id="app">
<div v-red v-if="show">
<span>我是标题</span>
<div>
<input type="text" v-model="title">
</div>
<button v-red>蓝色</button>
</div>
</div>
<div id="app2">
<div v-red>我是一个标题App2</div>
</div>
— js代码
// 1.定义全局指令 -- 定义一次,全局可用 // 参数1:指定指令的名称,不要v-开头 // 参数2:对象[定义这5个钩子函数实现] | 回调函数[它是bind/update简写] Vue.directive('red', { bind(el) { el.style.cssText = `color:red; font-size: 30px;` } }) const app = new Vue({ el: '#app', data: { title: '', show: true } }) const app2 = new Vue({ el: '#app2', data: { title: '', show: true } })
举个栗子-- 表单验证
— html代码
<div id="app">
<div>
<div>
<!-- 用户名必须是以a开头 -->
<input type="text" v-model="username" v-username>
</div>
<div>
<input type="text" v-model="password" v-password>
</div>
</div>
</div>
— js代码
// Vue.directive('username', { // bind(el) { // // 用户名必须是以a开头 // if (el.value.startsWith('a')) { // // el.style.color = 'red' // el.style.cssText = `border: 1px solid red;outline:none;` // } else { // // el.style.color = 'black' // el.style.cssText = `border: 1px solid black;` // } // }, // update(el) { // // 用户名必须是以a开头 // // console.log(el.value); // // console.log(el.value.startsWith('a')) // // 输出的账号中不能有a字母 // // console.log(el.value.includes('a')) // // 用户名必须是以a开头 // if (el.value.startsWith('a')) { // // el.style.color = 'red' // el.style.cssText = `border: 1px solid red;outline:none;` // } else { // // el.style.color = 'black' // el.style.cssText = `border: 1px solid black;` // } // } // }) // 简写,它相当于 bind/update合集 Vue.directive('username', el => { // 用户名必须是以a开头 if (el.value.startsWith('a')) { el.style.cssText = `border: 1px solid red;outline:none;` // 当前我没有兄弟,创建 if (!el.nextSibling) { const spanDom = document.createElement('span') spanDom.innerHTML = '账号不能以a字母开头' el.parentNode.appendChild(spanDom) } } else { el.style.cssText = `border: 1px solid black;` // el?.nextSibling?.remove() el && el.nextSibling && el.nextSibling.remove() } }) Vue.directive('password', el => { }) const app = new Vue({ el: '#app', data: { username: '', password: '' } }) => { // 用户名必须是以a开头 if (el.value.startsWith('a')) { el.style.cssText = `border: 1px solid red;outline:none;` // 当前我没有兄弟,创建 if (!el.nextSibling) { const spanDom = document.createElement('span') spanDom.innerHTML = '账号不能以a字母开头' el.parentNode.appendChild(spanDom) } } else { el.style.cssText = `border: 1px solid black;` // el?.nextSibling?.remove() el && el.nextSibling && el.nextSibling.remove() } }) Vue.directive('password', el => { }) const app = new Vue({ el: '#app', data: { username: '', password: '' } })
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。