Vue基本用法和指令
Vue是一个构建数据驱动的web界面的渐进式框架,目标是通过尽可能简单的API实现响应式的数据绑定和组合的视图组件,能够构建复杂的单页面应用。
vue的基本引入和创建
1.下载
- cdn方式下载
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
2.引包
<script src='./vue.js'></script>
3.实例化
new Vue({ el:'#app', //绑定那标签 data:{ //数据属性 msg:'黄瓜', person:{ name:'张三' }, msg2:'hello Vue' } });
Vue的模板语法
可以插入任何你想插入的内容,除了if-else if-else用三元运算符代替
<!--模板语法--> <h2>{{ msg }}</h2> <h3>{{ 'hhahda' }}</h3> <h3>{{ 1+1 }}</h3> <h4>{{ {'name':'alex'} }}</h4> <h5>{{ person.name }}</h5> <h2>{{ 1>2? '真的': '假的' }}</h2> <p>{{ msg2.split('').reverse().join('') }}</p>
Vue的指令系统
v-text和v-html
v-text相当于innerText
v-html相当于innerHTML
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <!--<div id="app">--> <!--{{ msg }}--> <!--</div>--> <div id="content"> {{ msg }} <div v-text="msg"></div> <div v-html="msg"></div> </div> <!--1.引包--> <script src='./vue.js'></script> <script> // new Vue({ // el:'#app', // }) new Vue({ el:'#content', data () { //data中是一个函数 函数中return一个对象,可以是空对象 但不能不return return { msg:"<h2>alex</h2>" } } }) </script> </body> </html>
v-if和v-show
v-show 相当于 style.display
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> .box { width: 200px; height: 200px; background-color: red; } .box2 { width: 200px; height: 200px; background-color: green; } </style> </head> <body> <div id="content"> {{ add(2,3) }} <button v-on:click='handlerClick'>隐藏</button> <div class="box" v-show='isShow'></div> <div class="box2" v-if="isShow"></div> <div v-if="Math.random() > 0.5"> 有了 </div> <div v-else> 没了 </div> </div> <!--1.引包--> <script src='./vue.js'></script> <script> //数据驱动视图 new Vue({ el: '#content', data() { //data中是一个函数 函数中return一个对象,可以是空对象 但不能不return return { msg: "<h2>alex</h2>", num: 1, isShow: true } }, methods: { add(x, y) { console.log(this.num); return x + y }, handlerClick() { //数据驱动 console.log(this); this.isShow = !this.isShow; } } }) </script> </body> </html>
v-if和v-show的区别
v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。 v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。 相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。 一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。
v-bind 和v-on
v-bind可以绑定标签中任何属性 ,v-on 可以监听 js中所有事件
简便写法:v-bind:src 等价于 :src , v-on:click 等价于 @click
l<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> .box { width: 200px; height: 200px; background-color: red; } .active{ background-color: green; } </style> </head> <body> <div id="app"> <!--<button v-on:click = 'handlerChange'>切换颜色</button>--> <!--v-bind 标签中所有的属性 img标签src alt,a标签的href title id class--> <!--<img v-bind:src="imgSrc" v-bind:alt="msg">--> <!--<div class="box" v-bind:class = '{active:isActive}'></div>--> <button @mouseenter = 'handlerChange' @mouseleave = 'handlerLeave'>切换颜色</button> <!--v-bind 标签中所有的属性 img标签src alt,a标签的href title id class--> <img :src="imgSrc" :alt="msg"> <div class="box" :class = '{active:isActive}'></div> </div> <!--1.引包--> <script src='./vue.js'></script> <script> //数据驱动视图 设计模式 MVVM Model View ViewModel //声明式的JavaScript框架 // v-bind和v-on的简便写法 : @ new Vue({ el: '#app', data() { //data中是一个函数 函数中return一个对象,可以是空对象 但不能不return return { imgSrc:'./1.jpg', msg:'美女', isActive:true } }, methods:{ handlerChange(){ // this.isActive = !this.isActive; this.isActive = false; }, handlerLeave(){ this.isActive = true; } } }) </script> </body> </html>
v-for
v-for可以遍历列表,也可以遍历对象,在使用vue的v-for指令的时候,一定要绑定key,避免vue帮咱们计算DOM
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> .box { width: 200px; height: 200px; background-color: red; } .active { background-color: green; } </style> </head> <body> <div id="app"> <ul v-if="data.status === 'ok'"> <!--v-for的优先级是最高的 diff算法--> <li v-for = '(item,index) in data.users' :key="item.id" > <h3>{{ item.id }} -- {{ item.name }} -- {{ item.age }}</h3> </li> </ul> <div v-for = '(value,key) in person'> {{ key }}-----{{ value }} </div> </div> <!--1.引包--> <script src='./vue.js'></script> <script> new Vue({ el: '#app', data() { return { data: { status: 'ok', users: [ {id: 1, name: 'alex', age: 18}, {id: 2, name: 'wusir', age: 30}, {id: 3, name: 'yuan', age: 48} ] }, person:{ name:'alex' } } }, methods: {} }) </script> </body> </html>
watch和computed
watch可以监听单个属性
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script src="../vue.js"></script> <div id="app"> {{ name }} -- {{ age }} <button @click="clickHandler">修改</button> </div> <script> new Vue({ el:'#app', data(){ return{ name:'cj', age:18 } }, methods:{ clickHandler(){ this.name='xushuo'; this.age=28 } }, //watch单个属性,如果想监听多个属性 声明多个属性的监听 watch: { // 监听nam属性,后面对应的是一个方法 'name':function (value) { console.log(value); this.name = '天秀' }, // 监听age属性,后面对应的是一个方法 'age'(aaa){ this.age = 66 } } }) </script> </body> </html>
computed (计算属性)
监听多个属性
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script src="../vue.js"></script> <div id="app"> {{ Myfun }} <button @click="clickHandler">修改</button> </div> <script> new Vue({ el:'#app', data(){ return{ name:'cj', age:18 } }, methods:{ clickHandler(){ this.name='xushuo'; this.age=28 } }, // 计算属性 computed:{ // Myfun 自定义的方法名 Myfun(){ this.name='天秀'; return `我的名字是${this.name},今年${this.age}岁了` } } }) </script> </body> </html>
V-model
数据双向绑定,只能用于input,select,textarea
// HTML页面 <div id="app"> <label> 男 <input type="checkbox" v-model="sex" value="male"> // <input type="radio" v-model="sex" value="male"> </label> <label> 女 <input type="checkbox" v-model="sex" value="female"> </label> {{sex}} </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="../js/main.js"></script> // main.js 页面 var app = new Vue({ el: '#app', data: { // sex: "male", sex: [], } }); v-model input
// HTML页面 <div id="app"> <!--<select v-model="from">--> <!--<option value="1">单选1</option>--> <!--<option value="2">单选2</option>--> <!--</select>--> <!--{{from}}--> <select v-model="where" multiple=""> <option value="1">多选1</option> <option value="2">多选2</option> <option value="3">多选3</option> </select> {{where}} </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="../js/main.js"></script> // main.js 页面 var app = new Vue({ el: '#app', data: { from: null, where: [], } }); v-model select
// HTML 页面 <div id="app"> <div> <texteare v-model="article"> </texteare> </div> </div> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <script src="../js/main.js"></script> // main.js 页面 var app = new Vue({ el: '#app', data: { // sex: "male", sex: [], article: "这是一段文本。。这是一段文本。。这是一段文本。。这是一段文本。。这是一段文本。。" } }); v-model textarea
修饰符
- .lazy 懒加载,只有用户按下回车键才会触发
- .number 希望用户输入纯数字使用它
- .trim 去掉用户输入中的两端空格,等价于python中的strip()
过滤器
-
全局过滤器:只要过滤器一创建,在任何组件中都能使用
-
声明 Vue.filter('过滤器的名字',function(val,a,b){})
-
使用 属性 | 过滤器的名字
-
-
局部过滤器:在当前组件内部使用过滤器
-
声明 filters:{过滤器名字:function(val){ } } //局部过滤器名字没有引号
-
使用 属性 | 过滤器名字
-
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <App></App> </div> <div></div> <script src="../vue.js"></script> <script src="../moment.js"></script> <script> // moment(new Date()).format('YYYY-MM-DD'); // moment('2020-01-01').fromNow(); Vue.filter('myTime',function (val,formatStr) { return moment(val).format(formatStr); }); let App = { data(){ return{ msg: 'hellp world', time:new Date() } }, template:` <div> <h1>{{ time | myTime("YYYY-MM-DD")}}</h1> </div> `, }; new Vue({ el: '#app', data() { return {} }, components:{ App } }) </script> </body> </html>
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div id="app"> <App></App> </div> <div></div> <script src="../vue.js"></script> <script src="../moment.js"></script> <script> // moment(new Date()).format('YYYY-MM-DD'); // moment('2020-01-01').fromNow(); let App = { data(){ return{ msg: 'hellp world', time:new Date() } }, template:` <div>我是App {{ msg | myFilter }} <h1>{{ time | myTime("YYYY-MM-DD")}}</h1> </div> `, filters:{ myFilter:function (val) { console.log(val); return val.split('').reverse().join('') }, myTime:function (val,formatStr) { return moment(val).format(formatStr); } } }; new Vue({ el: '#app', data() { return {} }, components:{ App } }) </script> </body> </html>
轮播图
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>轮播图</title> </head> <body> <div id="app"> <img :src="imgs[currentIndex].imgSrc" alt=""> <button @click="prevHandler">上一张</button> <button @click="nextHandler">下一张</button> </div> <script src="../vue.js"></script> <script> new Vue({ el: '#app', data() { return { imgs: [{'id': 1, 'imgSrc': './imgs/1.gif'}, {'id': 2, 'imgSrc': './imgs/2.jpg'}, {'id': 3, 'imgSrc': './imgs/3.gif'}, {'id': 4, 'imgSrc': './imgs/4.jpg'}], currentIndex: 0 } }, methods: { nextHandler() { this.currentIndex++; if (this.currentIndex > 3) { this.currentIndex = 0 } }, prevHandler() { this.currentIndex--; if (this.currentIndex < 0) { this.currentIndex = 3 } }, }, //组件创建完成后 created() created() { // 计时器方法setInterval setInterval(()=> { // 函数里面套函数,闭包,这里改变this指向问题,所以采用了箭头函数 this.currentIndex++; if (this.currentIndex > 3) { this.currentIndex = 0 } },2000) } }) </script> </body> </html>
vue中使用ajax
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> span.active{ color:red; } </style> </head> <body> <div id="app"> <div> <span @click = 'handlerClick(index,category.id)' v-for = '(category,index) in categoryList' :key = 'category.id' :class = '{active:currentIndex==index}'> {{category.name}} </span> <ul> <li></li> </ul> </div> </div> <script src="./vue.js"></script> <!--axios--> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> <script> let vm = new Vue({ el: '#app', data() { return { categoryList:[], currentIndex:0 } }, methods: { handlerClick(i,id){ this.currentIndex = i; //发起请求 $.ajax({ url:`https://www.luffycity.com/api/v1/courses/?sub_category=${id}`, type:'get', success:(data) => { var data = data.data; console.log(data); } }) } }, //组件创建完成, ajax vue的钩子函数 created() { //this指向问题 能用箭头函数 不要用匿名函数 $.ajax({ url:"https://www.luffycity.com/api/v1/course_sub/category/list/", type:"get", success: (data) => { console.log(data); if (data.error_no === 0){ var data = data.data; let obj = { id:0, name:'全部', category:0 } this.categoryList = data; this.categoryList.unshift(obj) } }, error:function (err) { console.log(err); } }) } }) </script> </body> </html>
音乐播放器
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> ul li.active{ background-color: darkcyan; } </style> </head> <body> <div id="music"> <!--@ended 播放完成 会自动调用该方法--> <audio :src="currentSong" controls autoplay @ended = 'nextHanlder'></audio> <ul> <li @click = 'songHandler(index)' v-for = '(item,index) in musicData' :key="item.id" :class = '{active:index===currentIndex}'> <h2>歌手:{{ item.author }}</h2> <p>歌名:{{ item.name }}</p> </li> </ul> </div> <script src="./vue.js"></script> <script> var musicData = [{ id: 1, name: '于荣光 - 少林英雄', author: '于荣光', songSrc: './static/于荣光 - 少林英雄.mp3' }, { id: 2, name: 'Joel Adams - Please Dont Go', author: 'Joel Adams', songSrc: './static/Joel Adams - Please Dont Go.mp3' }, { id: 3, name: 'MKJ - Time', author: 'MKJ', songSrc: './static/MKJ - Time.mp3' }, { id: 4, name: 'Russ - Psycho (Pt. 2)', author: 'Russ', songSrc: './static/Russ - Psycho (Pt. 2).mp3' } ]; new Vue({ el: '#music', data() { return { musicData:[], currentIndex:0 } }, computed:{ currentSong () { return this.musicData[this.currentIndex].songSrc } }, methods:{ songHandler(i){ this.currentIndex = i; }, nextHanlder(){ this.currentIndex++; } }, created(){ this.musicData = musicData } }) </script> </body> </html>
filters:{
幻想毫无价值,计划渺如尘埃,目标不可能达到。这一切的一切毫无意义——除非我们付诸行动。