【Vue】(1)基础知识 | MVVM | 基础指令 | v-model | v-for | v-if | v-show | 实例

VueJS 基础

首先,你可以在这里下载本文使用到的vue.js文件,使用的是v2.6.10开发版本。

MVC与MVVM

Vue只关注视图层,是一套构建用户界面的框架。

  • app.js :项目的入口模块,一切的请求,都要先进入这里进行处理。(注意:app.js并没有路由分发功能,需要调用router.js模块进行路由的分发处理)
  • router.js:这是路由分发处理模块:为了保证路由模型的只能单一,router.js只负责分发路由,不负责具体业务逻辑的处理(如果涉及到业务逻辑处理操作,router.js就无能为力了,只能调用controller模块进行业务逻辑处理)
  • Controller:这是业务逻辑处理层,在这个模块中,封装了一些具体业务逻辑处理的逻辑代码,但是,也是为了保证职能单一,此模块只负责处理业务,不负责处理数据的CRUD,如果涉及到了数据的CRUD,需要调用Model层
  • Model层:职能单一,只负责操作数据库,执行对应的Sql语句,进行数据的CRUD。
  • View视图层:每当用户操作了界面,如果需要业务的处理,都会通过网络请求,去请求后端服务,此时,这个请求就会被后端的app.js监听到
    • MVVM:是前端视图层的分层开发思想,主要把每个页面分成了M、V和VM。其中,VM是MVVM的思想核心,因为VM是M和V之间的调度者。
    • M:保存每个页面中单独的数据;(如:ajax请求返回的数据)
    • VM:它是一个调度者,分割了M和V。(每当M要想V渲染,或V改动后要同步到M时,VM负责这部分中间的处理工作。)
    • V:视图,每个页面中的html代码;(M中的数据渲染到V中)

前端页面使用MVVM的思想,主要是为了让我们开发更方便,因为MVVM提供了数据的双向绑定。(注意:数据的双向绑定是由VM提供的。

【Vue】(1)基础知识 | MVVM | 基础指令 | v-model | v-for | v-if | v-show | 实例_第1张图片

Vue基础代码

  • 基础代码

    
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Documenttitle>
        <script src="./lib/vue.js">script>
    head>
    <body>
        
         
        <div id="app">
            <p>{{msg}}p>
        div>
        <script>
            //创建一个Vue实例
            //当导入vue.js的包之后,在浏览器的内存中,就多了一个Vue构造函数
            //注意:我们new 出来的这个vm对象,就是我们MVVM中的VM调度者
            var vm = new Vue({
                el: '#app',  //表示当前我们new的这个vue实例,要控制页面上的哪个区域
                //这里的data就是MVVM中的M,专门用来保存每个页面的数据
                data: { //data属性中,存放的是el中要用到的数据
                    msg: '欢迎学习Vue' //通过vue提供的指令,很方便的把数据渲染到页面上,程序员不再手动操作DOM元素了
                }
            })    
        script>
    body>
    html>
    

    基础指令

  • v-cloak:解决插值表达式闪烁问题

  • v-text:解析文本

  • v-html:解析html

  • v-bind:提供属性绑定机制,缩写是 “:”

  • v-on:绑定事件,绑定浏览器常见事件,缩写是 “@”

  • 示例代码:

    
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Documenttitle>
        <style>
            [v-cloak]{display: none;}
        style>
    head>
    <body>
        <div id="app">
            
            
            
            <p v-cloak>{{msg}}p>
            <h4 v-text="msg">h4>
            
            
            <div v-html="msg2">div>
            
             
             
            <input type="button" value="按钮" v-bind:title="mytitle + '123'"> 
            <input type="button" value="按钮" :title="mytitle + '567'">
    
            
            <input type="button" value="按钮" :title="mytitle" v-on:click="hello">
            <input type="button" value="按钮" :title="mytitle" @mouseover="hello">
    
        div>
        <script src="./lib/vue.js">script>
        <script>
            var vm = new Vue({
                el: '#app',
                data: {
                    msg: '123',
                    msg2: '

    我是H1

    '
    , mytitle: '这个一个自定义的title' }, methods: { // methods属性中定义了当前Vue实例中所有可能的方法 hello: function() { alert('hello'); } } })
    script> body> html>

实例:跑马灯


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Documenttitle>
head>
<body>
    <div id="app">
        <input type="button" value="浪起来" @click="lang">
        <input type="button" value="别浪" @click="dontLang">
        <h4>{{ msg }}h4>
    div>
    <script src="./lib/vue.js">script>
    <script>
        //注意:在vm实例中,如果想要获取data上的数据,或者想要调用methods中方法,必须通过t his.数据属性名 或 this.方法名 来进行访问,就表示我们 new 出来的vm实例对象
        var vm = new Vue({
            el: '#app',
            data: {
                msg: '猥琐发育,别浪!',
                timer: null, //在data上定义定时器ID
            },
            methods: {
                lang() {
                    if(this.timer === null) {
                        this.timer = setInterval(()=>{
                        var start = this.msg.substring(0,1);//获取第一个字符串
                        var end = this.msg.substring(1);//获取到第一个字符后面的所有字符
                        this.msg = end + start;//重新凭借得到新的字符串,并赋值给 this.msg
                        //注意: VM实例,会自动监听data中所有数据的改变,只要数据发送变化,就会把最新的数据,从data同步到页面中去。【好处:程序员只需要关系操作数据,不需要考虑如何重新渲染到页面】
                        },300);
                    }else {
                        return;
                    }
                    
                },
                dontLang() {
                    clearInterval(this.timer);
                    //每当清除了定时器后,重新把timer置为null
                    this.timer = null;
                }
            }
        })

        //分析:
        //1.给 【浪起来】按钮,绑定一个点击事件 v-on 或 @
        //2. 在按钮的事件处理函数中,写相关的业务逻辑代码:拿到msg字符串,然后调用字符串的substring方法,来进行字符串截取操作,把第一个字符串截取出来,
        //放到最后一个位置,即可。
        //3.为了实现点击下按钮,自动截取的功能,需要把2步骤的代码,放到一个定时器中
    script>
body>
html>

事件修饰符

  • .stop 阻止冒泡
  • .prevent阻止默认事件
  • .capture添加事件侦听器时使用事件捕获模式
  • .self只当事件在该元素本身(比如:不是子元素)触发时触发回调
  • .once事件只触发一次

.self.stop的区别:

  • .self只阻止自身元素上的其他默认行为,不会阻止其他元素的默认冒泡行为
  • .stop阻止包含自身以及其他元素的默认冒泡行为

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Documenttitle>
    <script src="./lib/vue.js">script>
    <style>
        .inner {
            height: 100px;
            background-color: darkcyan;
        }
        .outer{
            padding: 10px;
            background-color: green;
        }
    style>
head>
<body>
    <div id="app">
        
        

        
        

        
        

        
        

        
        

        
        
        
        
    div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                
            },
            methods: {
                divHandler() {
                    console.log('inner div click event')
                },
                btnHandler() {
                    console.log('button click event')
                },
                linkHandler() {
                    console.log('a link click event')
                },
                divSelfHandler() {
                    console.log('inner self click event')
                },
                divouterHandler() {
                    console.log('outer click event')
                }
            }
        })    
    script>
body>
html>

v-model :唯一一个实现双向数据绑定的指令


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Documenttitle>
    <script src="./lib/vue.js">script>
head>
<body>
    <div id="app">
       <h4>{{ msg }}h4>
       
       

       
       
       
       <input type="text" v-model="msg">
    div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                msg: 'HELLO world'
            },
            methods: {
                
            }
        })    
    script>
body>
html>

简易计算器


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Documenttitle>
    <script src="./lib/vue.js">script>
head>
<body>
    <div id="app">
        <input type="text" name="" v-model="n1">
        <select v-model="opt">
            <option value="+">+option>
            <option value="-">-option>
            <option value="*">*option>
            <option value="/">/option>
        select>
        <input type="text" v-model="n2">
        <input type="button" value="=" @click="calc">
        <input type="text" v-model="result">
    div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                n1: 0,
                n2: 0,
                result: 0,
                opt: '+'
            },
            methods: {
                calc() {
                //不推荐该方式,开发中最好不用
                    let codeStr = `parseInt(this.n1)${this.opt}parseInt(this.n2)`;
                    this.result = eval(codeStr);
                }
            }
        })    
    script>
body>
html>

在Vue 中使用样式

使用class样式 :class

  • 数组方式

    <h1 :class="['red','thin']">啧啧啧啧啧啧h1>
    
  • 数组中使用三元表达式(要在data中添加isactive)

    <h1 :class="['red','thin',isactive?'active':'']">h1>
    
  • 数组中嵌套对象

    <h1 :class="['red','thin',{'active':isactive}]">啧啧啧啧啧啧h1>
    
  • 直接使用对象

    <h1 :class="{red:true,'thin':true,italic:true,active:true}">啧啧啧啧啧啧h1>
    
    
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Documenttitle>
        <script src="./lib/vue.js">script>
        <style>
            .red {
                color: red;
            }
            .thin {
                font-weight: 200;
            }
            .italic {
                font-style: italic;
            }
            .active {
                letter-spacing: 0.5em;
            }
        style>
    head>
    <body>
        <div id="app">
            
            
    
            
            
    
            
            
    
            
            <h1 :class="classObj">啧啧啧啧啧啧h1>
        div>
        <script>
            var vm = new Vue({
                el: '#app',
                data: {
                    classObj: {red:true,'thin':true,italic:true,active:false}
                },
                methods: {
                }
            })    
        script>
    body>
    html>
    

使用内联样式 :style


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Documenttitle>
    <script src="./lib/vue.js">script>
head>
<body>
    <div id="app">
        
        <h1 :style="styleObj1">啧啧啧啧啧啧h1>

        
        <h1 :style="[styleObj1,styleObj2]">啧啧啧啧啧啧h1>

    div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                styleObj1: {color: 'red','font-weight': 400},
                styleObj2: {'font-style':'italic','letter-spacing':'0.5em'}
            },
            methods: {
            }
        })    
    script>
body>
html>

v-for 循环

循环普通数组


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Documenttitle>
    <script src="./lib/vue.js">script>
head>
<body>
    <div id="app">
        <ul>
            <li v-for="(item,i) in list">第{{i+1}}项:{{item}}li>
        ul>
    div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
               list: [1,2,3,4,5,6]
            },
            methods: {
            }
        })    
    script>
body>
html>

循环对象数组


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Documenttitle>
    <script src="./lib/vue.js">script>
head>
<body>
    <div id="app">
        <ul>
            <li v-for="(item,i) in list">id:{{item.id}}---{{item.name}}li>
        ul>
    div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
               list: [
                {id:1,name:'zzz1'},
                {id:2,name:'zzz2'},
                {id:3,name:'zzz3'},
                {id:4,name:'zzz4'},
                {id:5,name:'zzz5'},
               ]
            },
            methods: {
            }
        })    
    script>
body>
html>

循环对象


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Documenttitle>
    <script src="./lib/vue.js">script>
head>
<body>
    <div id="app">
        
        <p v-for="(val,key,i) in user">{{ key }} --- {{ val }} --- 索引:{{i}}p>
    div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
               user: {
                   id: 1,
                   name: 'zzzz',
                   gender: '男'
               }
            },
            methods: {
            }
        })    
    script>
body>
html>

迭代数字


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Documenttitle>
    <script src="./lib/vue.js">script>
head>
<body>
    <div id="app">
        
        
        <p v-for="count in 10">第{{count}}次循环p>
    div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
            },
            methods: {
            }
        })    
    script>
body>
html>

v-for中key属性的使用注意事项

v2.2.0+的版本里,每次for循环时,通过key属性标识当前循环的唯一身份。

  • 注意: v-for循环的时候,key属性只能使用number获取string

  • 注意: key 在使用的时候,必须使用v-bind 属性绑定的形式,指定key的值

  • 在组件中,使用v-for循环的时候,或者在一些特殊情况中,如果v-for有问题,必须在使用v-for的同时指定唯一的字符串/数字类型的:key值

    
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Documenttitle>
        <script src="./lib/vue.js">script>
    head>
    <body>
        <div id="app">
            <div>
                <label>
                    ID: <input type="text" v-model="id">
                label>
                <label>
                    name: <input type="text" v-model="name">
                label>
                <input type="button" value="添加" @click="add">
            div>
            
            
          
            <p v-for="item in list" :key="item.id">
                <input type="checkbox">
                {{item.id}}---
                {{item.name}}
            p>
        div>
        <script>
            var vm = new Vue({
                el: '#app',
                data: {
                    id: '',
                    name: '',
                    list: [
                        {id:1,name: 'xxx'},
                        {id:2,name: 'yyy'},
                        {id:3,name: 'zzz'},
                        {id:4,name: 'www'}
                    ]
                },
                methods: {
                    add() {
                        this.list.unshift({id: this.id,name:this.name});
                    }
                }
            })    
        script>
    body>
    html>
    

v-if 和 v-show

  • v-if:每次都会重新删除或创建DOM(v-if会消耗较高的切换性能 ,如果该DOM涉及到频繁的切换,最好不要用到v-if,这时推荐使用v-show

  • v-show:每次不会重新进行DOM的删除或创建操作,只是切换了DOM的display:none样式。(如果这个DOM从来不会被进行显示,那么v-show有较高的初始渲染消耗,这时推荐使用v-if

    
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Documenttitle>
        <script src="./lib/vue.js">script>
    head>
    <body>
        <div id="app">
            <input type="button" value="toggle" @click="flag=!flag">
            
            <h3 v-if="flag">v-if控制的DOMh3>
            
            <h3 v-show="flag">v-show控制的DOMh3>
        div>
        <script>
            var vm = new Vue({
                el: '#app',
                data: {
                    flag: true
                },
                methods: {
                }
            })    
        script>
    body>
    html>
    

实例-商品列表


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Documenttitle>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet">
    <script src="../lib/vue.js">script>
head>
<body>
    <div id="app">
        <div class="panel panel-primary">
            <div class="panel-heading">
                <h3 class="panel-title">添加品牌h3>
            div>
            <div class="panel-body form-inline">
                <label for="">
                    id: <input type="text" class="form-control" v-model="id">
                label>
                <label for="">
                    name: <input type="text" class="form-control" v-model="name">
                label>
                
                <input type="button" value="添加" class="btn btn-primary" @click="add">
                <label for="">
                    搜索关键字: <input type="text" value="搜索" v-model="keywords">
                label>
            div>
        div>
        <table class="table table-bordered table-hover table-striped">
            <thead>
                <tr>
                    <th>idth><th>Nameth><th>Ctimeth><th>Operationth>
                tr>
            thead>
            <tbody>
                
                
                
                <tr v-for="item in search(keywords)" :key="item.id">
                    <td v-text="item.id">td>
                    <td v-text="item.name">td>
                    <td v-text="item.ctime">td>
                    <td>
                        <input type="button" value="删除" @click.prevent="del(item.id)">
                    td>
                tr>
            tbody>
        table>
    div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                id: '',
                name: '',
                keywords: '',
                list: [
                    {id:1,name:'科比',ctime: new Date()},
                    {id:2,name:'詹姆斯',ctime: new Date()}
                ]
            },
            methods: {
                add() {
                    //分析:
                    //1.获取到id和name,直接从data上获取
                    //2.组织处一个对象
                    //3.把这个对象,调用数组的相关方法,添加到当前data上的list中
                    //4.注意:在Vue中,已经实现数据的双向绑定,每当我们修改了data中的数据,Vue会默认监听到数据的改动,自动把最新的数据,应用到页面上
                    let data = {id:this.id,name:this.name,ctime:new Date};
                    this.list.push(data)
                    this.id = this.name = '';//清空
                },
                del(id) {
                    // this.list.some((item,i)=>{
                    //     if(item.id === id) {
                    //         this.list.splice(i,1);
                    //         return true;
                    //     }
                    // })
                   let index = this.list.findIndex(item => {
                        if(item.id === id) {
                            return true;
                        }
                    });
                    this.list.splice(index,1);
                },
                search(keywords) {//根据关键字进行数据的搜索
                    // let newList = [];
                    // this.list.forEach(item=>{
                    //     if(item.name.indexOf(keywords) !== -1) {
                    //         newList.push(item);
                    //     }
                    // })
                    // if(keywords.trim() === '') {
                    //     return this.list;
                    // }else {
                    //     return newList;
                    // }
                    return this.list.filter(item => {
                        return item.name.includes(keywords) === true ? item : false;
                    })
                }
            }
        })    
    script>
body>
html>

你可能感兴趣的:(MVVM)