• Vue基础学习


    1.vue基础

    1.1 Vue下载安装

    1.1.1js文件安装

    下载:学习--教程--左侧的安装---下载开发版,点击进入,复制---到项目中创建vue.js文件,将内容复制即可,用script引入 
    <script type="text/javascript" src="Vue/vue.js" ></script>
    3.或者可以直接引入
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>

    1.1.2 win下安装node.js

    • 下载安装:
    • 测试:
      • 打开cmd,输入node进入,然后就可以测试了
      • 退出:两次Ctrl+c
    • 查看版本号: npm -v
    若是没有版本号,需要修改环境变量:
    在用户变量的path中加上:C:UsersjsyAppDataRoaming pm


    1.1.3安装命令行工具MobaXterm 

    打开即可使用;
    配置:打开Settings 

    • 安装cnpm
      • 方法1:
    npm install -g cnpm --registry=https://registry.npm.taobao.org
    //但是这样版本可能会不一致
      • 方法2:
    或者你直接通过添加 npm 参数 alias 一个新命令:
    alias cnpm="npm --registry=https://registry.npm.taobao.org 
    --cache=$HOME/.npm/.cache/cnpm 
    --disturl=https://npm.taobao.org/dist 
    --userconfig=$HOME/.cnpmrc"



    1.1.3vue-cli下载和安装

    使用node.js(MobaXterm )安装vue-cli

    • 安装vue-cli:     cnpm install vue-cli -g
    • 初始化项目:        vue init webpack my-project
    • 安装项目依赖         cnpm install
    • 在locallot启动测试服务器 :       npm run dev
    • 生成上线日录(部署) :        npm run build

    • 具体使用
    vue版本2.9.6,输入  vue --help    有一下内容

    • 查看版本
    • vue -V

    • 查看官方提供的模板
    • vue list    //速度回有点慢

    • 使用webpack搭建项目
    vue init webpack my-project    //搭建项目
        接下来是配置:
            项目名
            描述
            作者
            安装vue-router   y
            代码校验ESLint   n
            测试工具tests  看个人需要 n
            e2s tests 测试工具    n
      生成项目;
    启动项目:
        1.安装依赖:
            进入项目文件夹my-project
            cnpm install    //安装依赖  node_modules
            npm run dev    //启动项目
    生成部署用的文件:
        npm run build     //运行之后,会有一个dist目录

    1.1.4 sublime text 添加vue高亮

    1.准备语法高亮插件vue-syntax-highlight。
    下载zip并解压;
    2.进入sublime,首选项--浏览插件目录,在打开的文件夹中创建“Vue”文件夹。
    3.在Vue文件夹中,将vue-syntax-highlight-master压缩包解压后的所有文件考入
    4.按下快捷键“ctrl+shift+p”,在打开的packages输入框中输入vue,选择“Set Syntax:Vue Component”进行加载。
    加载后重启sublime,重新打开.vue文件,即能看到语法高亮

    1.1.5 安装vuex

    在项目中安装
    cnpm install vuex --save
    //若是重启了工具,要重新把上面的npm转cnpm的代码运行一下,
    安装完之后,重新运行项目
        npm run dev

    1.1.6 安装vue-resource

    cnpm install vue-resource

    1.1.7 json-server 虚拟的后端(只能get)

    cnpm install json-server --save
    打开项目,进入build 打开dev-server.js文件,
    在第四行express下:
        var jsonServer=require('json-server')
    在第16行var app = express()之下写
        var jsonServer=new jsonServer()
    在最底下module.exports之前设置:
    
    
    var jsonServer=require('json-server')
    var apiserver=jsonServer.create()
    var apirouter=jsonServer.router('db.json')//此目录是项目的目录,放置此文件到项目文件夹中
    var middlewares=jsonServer.defaults()
    apiserver.use(middlewares)
    apiserver.use('/api',apirouter)
    apiserver.listen(3000,function () {//监听的接口,
      console.log('JSON Server is running')
    })
    

    配置后端接口路径

    打开config中的index.js文件,其中配置的就是后端

    1.1.8虚拟后端接口

    var apiServer = express()
    var bodyParser = require('body-parser')
    apiServer.use(bodyParser.urlencoded({ extended: true }))
    apiServer.use(bodyParser.json())
    var apiRouter = express.Router()
    var fs = require('fs')
    apiRouter.route('/:apiName')//动态设置路由接口
    .all(function (req, res) {
      fs.readFile('./db.json', 'utf8', function (err, data) {
        if (err) throw err
        var data = JSON.parse(data)
        if (data[req.params.apiName]) {//判断是否有这个接口
          res.json(data[req.params.apiName])//设置返回值
        }
        else {
          res.send('no such api name')
        }
    
      })
    })
    
    
    apiServer.use('/api', apiRouter);
    apiServer.listen(port + 1, function (err) {
      if (err) {
        console.log(err)
        return
      }
      console.log('Listening at http://localhost:' + (port + 1) + '
    ')
    })







    1.2 vue概述

    生命周期


    1.2.1 挂载点、模板、实例的关系

    挂载点:就是页面的标签,vue只会处理挂载点下面的内容
    <div id="root"></div>
    模板:挂载点内部的内容,都是模板内容,可以写在挂载点(标签中),也可以写在template中.
    显示的时候,显示的是template中定义的内容,页面本身的内容会去掉
        <body>
            <div id="root">{{msg}}</div><!--显示msg中内容-->
        </body>
        <script>
        /*创建一个vue实例,让这个实例接管页面上的id为root的标签*/
            new Vue({
                el:"#root", /*绑定:id为root的*/
                template:'<h1>你好,{{msg}}</h1>',/*在root内部设置内容*/
                data:{
                    msg:"hello world"
                }
            })
        </script>
    实例在vue实例中的data中,可以设置任意的名字,只要用{{ }}就可以显示

    1.2.1 vue实例显示方法(html,text)

    1.用{{ }}显示
    {{msg}}
    2.在标签上使用v-text显示:(若是HTML格式的内容,会直接将标签显示)
    <h1 v-text='msg'></h1>
    3.在标签上使用v-html显示:(会将标签转义,显示处理后的页面样式)
    <h1 v-html='msg'></h1>

    1.2.2 vue点击事件

    点击标题,将标题的内容改为123
    • 点击标题时,调用root的vue中的handleClick方法,将vue的data中的msg改为123;

    绑定点击事件的方法: 

    1.使用 v-on:click='handleClick' 
    2.使用 @click='handleClick'
    注意:写方法的时候,方法要写在vue的methods中
    <body>
        <div id="root">
            <h1 v-on:click='handleClick'>{{msg}}</h1>
            <!--设置点击方法-->
        </div>
        <!--显示msg中内容-->
    </body>
    <script>
        new Vue({
            el : "#root"/*绑定:id为root的*/
            data : {
                msg "hello world"
            },
            methods : {
                handleClick : function() {
                    his.msg "123"
                }
            }
        })
    </script>

    1.2.3 Vue中的属性绑定

    (1)属性绑定

    使用:
    (1)v-bind:
    (2):
    <!--使用v-bind对title中的内容绑定,绑定为data中title中的内容-->
    <div v-bind:title="title">hello world</div><!--v-bind可以省略-->
    -------------
    new Vue({
        el:"#root", /*绑定:id为root的*/
        data:{
            title:"this is hello world",
        }
    })


    <div v-bind:title="'123 '+title">hello world</div>
    则页面上提示内容为:123 this is hello world 
    简化:
    <div :title="title">hello world</div>

    (2):绑定class

    这种class绑定不会冲突,页面上回自动整合未一个class的两个样式
    <div :class="link" class="aaa"></div>
    在data中:
        link:'class1'

    • 绑定多个class(class对象)
            link:{
                'class1':true,
                'class2':false
            }//true的class会在页面显示
    • 数组形式class
    link:['class1','class2']
    或者:
    <div :class="[classA,classB]" class="aaa"></div>
    ----------------------
    classA:'cla1',
    classB:'cla2',
    • 混合使用:
    <div :class="[classA,{'classB':iferror}]" class="aaa"></div>
    ******************
    classA:'cla1',
    classB:'cla2',
    iferror:true

    1.2.4 双向数据绑定 v-model

    v-model双向绑定,当INPUT中的内容变的时候,下面div中的内容也会变
    <input v-model="content"/>    
    <!--v-model双向绑定,当INPUT中的内容变的时候,下面div中的内容也会变-->        
    <div>{{content}}</div>    



    (1)绑定表达式

    • 支持三元表达式
    {{content?content:"你好"}}
    当content有值的时候显示值,没有的时候显示"你好"

    (2)lazy修改器:延迟修改

    只有当修改完之后,点击了enter或者失去焦点的时候,才会修改,input必须定义type为text
    <input type="text" v-model.lazy="myVlaue" /><!--延迟-->
    {{myVlaue}}

    (3)number数字转为number格式

    <input type="text" v-model.number="myVlaue" /><!--延迟-->
    {{typeof myVlaue}}     输出的是类型

    注意:是数字格式的会转化为number,但是字符串的不会影响

    (4)trim去掉前后空格

    <input type="text" v-model.trim="myVlaue" /><!--延迟-->
    {{myVlaue}}

    1.2.5 Vue中的计算属性(多个属性)

    姓:<input v-model="firstName"/>
    名:<input v-model="lastName"/>
    <div>{{firstName}}{{lastName}}</div>


    整合之后:
    姓:<input v-model="firstName"/>
    名:<input v-model="lastName"/>
    <div>{{fullName}}</div>    
    --------------
    new Vue({
        el:"#root", /*绑定:id为root的*/
        data:{
            firstName:"",
            lastName:""
        },
        computed:{/*计算属性,表示一个属性通过另一个属性计算而来*/
            fullName:function(){
                return this.firstName+' '+this.lastName;
            }
        }
    })



    (1)案例:获取输入中的数据,将数字清掉,只显示其他部分

    • 方法1:使用计算属性
    <input type="text" v-model.trim="myVlaue" /><!--延迟-->
    {{myVlaueNoNumber}}
        computed:{
            myVlaueNoNumber:function (){
                return this.myVlaue.replace(/d/g,'')
            }
    • 方法2:添加事件:
    定义方法:
    getValue:function(){
        return this.myVlaue.replace(/d/g,'')
    }
    调用:
    {{getValue()}}
    显示:

    • 区别:
      • 计算属性只会根据其中调用的值改变(只有这个值改变的时候,他才会变);
      • 方法只要调用就会进行数据处理

    1.2.6 Vue中的侦听器,监听: watch

    watch监听的属性的方法可以有两个值,一个新值,一个旧值
    	watch:{
    		myVlaue:function(val,oldVal){}
    	}
    ()
    当姓或名做了改变的时候,count+1,使用watch监听器

    姓:<input v-model="firstName"/>    
    <!--v-model双向绑定,当INPUT中的内容变的时候,下面div中的内容也会变-->        
    名:<input v-model="lastName"/>
    <div>{{fullName}}</div>            
    <div>{{count}}</div>
    -------------
    new Vue({
        el:"#root", /*绑定:id为root的*/
        data:{
            firstName:"",
            lastName:"",
            count:0
        },
        computed:{/*计算属性*/
            fullName:function(){
                return this.firstName+' '+this.lastName;
            }
        },
        watch:{
            /*监听firstName*/
            firstName:function () {
                this.count++;
            },
            lastName:function () {
                this.count++;
            }
        }
    })

    此处监听的是firstName和lastName,也可以监听fullName,只要fullName改变,就count++

    1.2.7 v-if, v-show与v-for指令

    (1)案例:点击按钮,标签显示、隐藏

    • v-if
    <div id="root">
        <!--只有show是true的时候,标签才会存在-->
        <div v-if='show'>hello world</div>
        <button @click='handleClick'>toggle</button>
    </div>
    --------------
    new Vue({
        el:"#root",
        data:{
            show:true,
        },
        methods:{
            handleClick:function(){
                this.show=!this.show;//将show的值取反
            }
        }
    })

    • v-show
    上述代码,直接将v-if换为v-show即可,使用时,结果相同 
    • v-else
    <v-if="isshow">456</a>
    <v-else>123</a>

    (2)v-for 案例:将list中的内容,循环展示出来

    遍历的时候,item of list ,用in或of都可以
        <ul>
            <!--遍历list中的内容,定义Wieitem,将他显示-->
            <li v-for="item of list":key="item">{{item}}</li>
        </ul>
    -------------
    data:{
            show:true,
            list:[1,2,3]
    },


    注意:,使用了key,要求item中的内容不能相同,(list中的内容不能相同)
    若是list中有相同的内容,使用index:
    <!--item放的是内容,index放的是下标,用index作为key值,就不会重复了-->
    <li v-for="(item,index) of list":key="index">{{item}}</li>

    • 对象列表

          
            list:[
            {
                name:'apple',
                price:323
            },{
                name:'aaa',
                price:1123
            }
            ]
    <div v-for="(item,index) in list":key="index">{{item.name}}---{{item.price}}--{{index}}</div>
    也可以直接在标签中引用:
    <div v-for="(item,index) in list":key="index"
       v-text="item.name+'---'+item.price+'---'+index"></div>

    • 遍历对象
    <div v-for="(value,key) in objlist" >{{value}}---{{key}}</div>
    	objlist:{
    			name:'app',
    			price:123,
    			color:'red'
    		}

    (3)v-if, v-show区别

    v-if:当为false的时候,会之间将代码移除; 
    v-show:当为false的时候,会display为隐藏none;
    当需要频繁的显示隐藏的时候,v-show更好,它不需要重新创建,性能更高; 
    只需要一次的话,v-if更好;

    (4)v-for 操作class

    <div v-for="(item,index) in list" :class="{odd:index%2}">{{index}}</div>
    当index%2有余数的时候odd显示

    (5)案例:当点击提交的时候,input的内容显示在list中,在页面显示(同步更新)

    <!--当点击提交的时候,input的内容显示在list中,在页面显示-->        
    <div id="root">
        <div>
            <input v-model="inputValue"/>
            <button @click="handleSubmit">提交</button>
        </div>
        <ul>
            <li v-for="(item,index) of list":key="index">{{item}}</li>
        </ul>
    </div>
        </body>
        <script>
    new Vue({
        el:"#root",
        data:{
              inputValue:'',
            list:[]
        },
        methods:{
            handleSubmit:function(){
                //点击提交的时候,将input的值放到list中
                this.list.push(this.inputValue)
                this.inputValue=''//将inputValue设置W为空,这样输入框就会自动为空了
            }
        }
    })
        </script>

    (5)数据列表修改数据

    为列表中某一项修改数据
    • 直接修改----不会自动更新
    • 使用vue的setfnagfa
    <button @click="changelist">changelist</button>
    -----------------
    methods:{
    		changelist:function (){
    			Vue.set(this.list,1,123)
    		}
    	}

    1.2.8 组件

    组件:指页面的某些部分

    (1)全局组件

    //将页面显示的ul部分作为一个组件,
    //Vue.component创建的是全局组件
    Vue.component('todo-item',{
        template:'<li>item</li>'  //模板(其中的HTML代码)
    })
    -----------调用:
    <ul>
        <!--使用组件-->
        <todo-item></todo-item>
    </ul>

    (2)局部组件

    • 局部组件声明
    var TodoIrem={
        template:'<li>item</li>' 
    }
    由于是局部的,需要在要使用的实例哪里声明
    new Vue({
        el:"#root",
        components:{        //做组件声明
            'todo-item':TodoItem
    //若是左右相同,可以只写一边的  TodoItem  
        },
    • 组件使用:
      • 方法1:
    <todo-item></todo-item> <!--一样-->
      • 方法2:使用is引入
    <p is='todo-irem'></p>
    方法2优势,可以动态的使用组件,使用:is 的时候,可以引用变量
    动态引入:
    <p :is='getTodo'></p>
    data中:   getTodo:'todo-irem'

    (3)子组件多级调用

    var my2={
        template:'<div>123456</div>',
    }
    //创建一个子组件
    var my1={
        template:'<div><my2></my2></div>',//多级调用,要在这里
        components:{
            //my1
            'my2':my2
        }
    }
    new Vue({//根组件
        el: '#app',
        data: {
            content: 'Hello'
        },
        components:{
            'my':my1
        }
    })

    (4)子组件data赋值

    子组件要避免引用赋值,
    //创建一个子组件
    var my1={
        template:'<div>{{f}}<my2></my2></div>',
        components:{
            //my1
            'my2':my2
        },
        data :function(){//也可以使用    data (){
            return{
                f:2
            }
        }
    }


    (3)组件与实例的关系

    每一个组件,就是一个实例,每一个组件上都可以定制方法等内容

    (4)父组件向子组件传递数据组件通信

    • 父组件向子组件传递数据,属性:
      • 父组件调用的时候,设置:key=value,(key是父组件的数据的key)
      • 子组件接收参数:使用props接收参数,就可以正常调用了
      • 子组件方法中可以用this.xxx调用数据
      • 注意,key值设置的时候大小写不敏感,要使用-,props中也是,当时子组件调用的时候,使用的是驼峰的样式.

    • 使用全局组件完成input提交显示,
     <!--使用组件-->
    <todo-item v-for="(item,index) of list" 
        :key="index" 
        :content="item"
    >  <!--设置key值,1.传参-->
    </todo-item>
    设置全局组件,接收参数,显示内容
    Vue.component('todo-item',{
        props:['content'],//2.接收参数content
        template:'<li>{{content}}</li>'  //3.设置显示模板(其中的HTML代码)也可以在页面中调用
    })

    (5)props接收参数

    接收参数可以是list格式,也可以是对象格式:
     props:['aaa','bbb']
    对象格式:
        props:{
            'aaa':[Number,String,Object]//指定参数运行的格式
        }

    (6)子组件向父组件传递事件

    1.子组件的模板中添加时间(vue事件);
    2.在事件中,通过  this.$emit('delete-a',this.index)  创建自定义的事件,并传递参数,自定义的事件不支持驼峰形式.
    3.在父组件中调用子组件的时候,在标签中用@...调用这个事件,@...='父组件中的方法名',
    4.在父组件中编写方法,
    5.调用子组件的事件的时候,调用的就会是父组件的方法了.
    • 案例:下方的删除功能

    (7)插槽:子组件显示父组件定义的标签

    在父组件中调用子组件,再向子组件的标签中添加内容的时候,不会显示,只会显示子组件本身的内容
    <todo-irem><!--调用子组件,子组件中有内容<li>i123131132tem</li>-->
    	<p>123</p>
    </todo-irem>
    只会显示:子组件本身定义的内容
    想要这部分内容显示,可以在子组件的模板中使用标签
    template:'<div><li>i123131132tem</li><slot></slot></div>' 
    在子组件中加上这个标签,就会把父组件调用的时候添加的内容显示
    注意:子组件必须在一个大标签之下,

    • 插槽设置默认内容
    当插槽没有设置的时候,默认显示内容
    template:'<div><li>i123131132tem</li><slot>没有内容</slot></div>' ,

    • 插槽设置名字
    <todo-irem><!--调用子组件,子组件中有内容<li>i123131132tem</li>-->
    <slot='header'>header插的内容 </p>
    <!--<p slot='footer'> footer插的内容</p>-->
    </todo-irem>
    template:'<div><li>i123131132tem</li><slot name="header">header没有内容</slot><slot name="footer">footer没有内容</slot></div>',

    (8)动态组件is

    在父组件中声明子组件之后,在页面中:
    <:is='getTodo'></p>
    这样就可以动态设置了,getTodo是data中的属性,通过改变它的值改变绑定的子组件
    getTodo:'todo-irem'

    (9)组件缓存:<keep-alive>

    <keep-alive>
        <:is='getTodo'></p>
    </keep-alive>
    当组件从a切换到b,的时候,a就会缓存起来,从b切换回a的时候,直接读缓存

    1.2.9案例: 删除功能(子组件向父组件传递事件)

    • 已有功能:
    点击提交,会将input中的内容保存到list,子组件会遍历list,设置为item,以content传递到props,在template中显示.
    • 需要实现:
    要想删除子组件,在每一条上加上click方法,删除的时候,要删除的是父组件list中的内容. 
    调用的是子组件的方法,删除父组件的数据,需要两个组件之间进行通信(此时需要子组件中,这一条的下标,来和父组件中对应).

    • 传递顺序:
    1.点击子组件(显示的内容中)的方法handleClick(click方法),调用方法, this.$emit创建在父组件中显示的名(@...自定义事件)和参数,在父组件中调用@...(<xxx调用子组件)之后的方法
    注意,自定义事件不支持驼峰形式

        <body>
    <!--当点击提交的时候,input的内容显示在list中,在页面显示-->        
    <div id="root">
        <div>
            <input v-model="inputValue"/>
            <button @click="handleSubmit">提交</button>
        </div>
        <ul>
            <!--在父组件中调用子组件----使用组件-->
            <todo-item v-for="(item,index) of list" 
                :key="index" 
                :content="item"
                :index="index"
                @delete-a="handleDelete"
                >  <!--设置key值,1.传参,下标,-->
                <!--监听子组件的delete事件,当子组件触发了delete事件的时候,调用方法handleDelete(父组件的方法)-->
            </todo-item>
        </ul>
    </div>
        </body>
        <script>
    //将页面显示的ul部分作为一个组件,
    //Vue.component创建的是全局组件
    Vue.component('todo-item',{
        props:['content',"index"],//2.接收参数content
        template:'<li @click="handleClick">{{content}}</li>'//3.设置显示模板(其中的HTML代码)
        methods:{
            handleClick:function(){
                //调用$emit,调用自定义的事件,传入接收的下标值
                this.$emit('delete-a',this.index)
            }
        }
    })
    //局部组件
    //var TodoItem={
    //    template:'<li>item</li>' 
    //}
    new Vue({
        el:"#root",
    //    components:{//做组件声明
    //        'todo-item':TodoItem
    //    },
        data:{
              inputValue:'',
            list:[]
        },
        methods:{
            handleSubmit:function(){
                //点击提交的时候,将input的值放到list中
                this.list.push(this.inputValue)
                this.inputValue=''//将inputValue设置W为空,这样输入框就会自动为空了
            },
            handleDelete:function (index) {
                //删除list中对应下标的内容,即可删除页面中的数据
                //从下标位置,删除一项
                this.list.splice(index,1)
            }
        }
    })
        </script>
    </html>

    1.3vue事件和表单

    1.3.1全局api

    实例对象创建完之后,还可以进行操作
    实例对象有一个对象名root
    var root=new Vue({
    	el: '#app',
    	data: {
    		content: 'Hello'
    	}
    })
    root.$data 
    可以获取data数据
    root.$on('emit',function () {})  
    可以绑定方法

    1.3.1事件绑定

    除了click之外,还常用的方法是keydown方法,一般监听的键盘是enter
    当按键为回车的时候,进行的操作:
    <input @keydown.enter="tokeydown" />
    也可以指定其他的按键,比如:
    @keydown.13

    1.3.2多选框/单选框,数据绑定

    将多选框中的数据绑定到数组中

    (1)单选框数据绑定

    <input v-model="myBox" type="radio" value="111" />
    <input v-model="myBox" type="radio" value="222" />
    <input v-model="myBox" type="radio" value="333" />
    {{myBox}}
    --------------
    myBox:[]

    (2)多选框数据绑定

    <input v-model="myBox" type="checkbox" value="111" />
    <input v-model="myBox" type="checkbox" value="222" />
    <input v-model="myBox" type="checkbox" value="333" />

    (3)select下拉框绑定

    <select v-model="sel">
    	<option value="1">11</option>
    	<option value="2">22</option>
    	<option value="3">33</option>
    </select>
    {{sel}}
    ------------
    sel:null

    (4)v-for 遍历下拉绑定

    <select v-model="sel">
    	<option v-for="item in seloption" :value="item.value">{{item.text}}</option>
    </select>
    {{sel}}
    ------------
    sel:null,
    seloption:[
        {text:'app1',value:1},
        {text:'app2',value:2},
        {text:'app3',value:3},
    ]
    一般情况,这种下拉会创建一个组件,直接调用组件:
    <vSelect @onSelect='' :list="seloption"></vSelect>

    1.4 vue高级功能

    1.4.1过渡(动画效果)

    要与v-show,v-if 动态组件结合
    1.给需要过渡的元素外层加transition ,并用name命名
    show:true,
    ---------------------
    <button @click="show=!show">button</button>
    <transition name='fade'>
        <v-show="show">456</p>
    </transition>

    (1)css过渡


    • 淡入淡出 
    show:true,
    ---------------------
    <button @click="show=!show">button</button>
    <transition name='fade'>
        <v-show="show">456</p>
    </transition>
    --------------------
    在style中定义样式
    <style>
    .fade-enter-active,.fade-leave-active{
        transition:/*opacity*/ all .5;/*属性,时长,还可以加上ease-out,代表变化的曲线*/
        /*指定当前样式有过渡效果,opacity代表透明度*/
    }
    .fade-enter,.fade-leave-active{
        opacity:0;
        /*进入和出去的时候透明度是0*/
    }
    </style>

    • 上下左右滑入滑出
    /*激活阶段,动画控制,*/
    .my-trans-enter-active,.my-trans-leave-active{
        transition: all .5s ease-out;/*属性,时长,还可以加上,代表变化的曲线*/
        
    }
    /*控制动画具体怎么变*/
    /*进入动画控制*/
    .my-trans-enter{
        /*进入从上方滑入*/
        transform: translateY(-500px);
        opacity: 0;
    }
    .my-trans-leave-active{
        /*出去,向下滑出*/
        transform: translateY(500px);
        opacity:0;
        /*进入和出去的时候透明度是0*/
        /*指定当前样式有过渡效果,opacity代表透明度*/
    }

    组件设置过渡

    <transition name='my-trans'>
    	<div :is='getTodo'></div>
    </transition>
    <button @click="getTodoFun">button</button>
    ---------------
    getTodo:'todo-irem'
    ------------
    getTodoFun:function(){
        if(this.getTodo==='todo-irem'){
            this.getTodo='todo-irem2'
        }else{
            this.getTodo='todo-irem'
        }
    }

    多元素过渡

    多个元素切换,是将新的在下方显示,在将旧的隐藏,有同时出现的机会,默认是in-out
    使用out-in,会先将就的去掉,再显示新的
    <transition name='my-trans' mode='out-in'>  
        <v-show="show">456</p>
    </transition>

    注意,多个元素的时候,过渡动画会消失,需要定义key区分每一个元素
    <button @click="show=!show">button</button>
    <transition name='fade' mode='out-in'>
        <v-if="show" key='1'>456</p>
        <v-else key='2'>11178911</p>
    </transition>

    (2)JS过渡

    • js控制动画,是通过v-on事件控制的.
    • 使用js过渡的时候,要在transition中绑定  v-bind:css='false' 防止css样式的影响

     <!--进入前,进入过程中,离开-->
     <transition 
        @before-enter='beforeEnter'
        @enter='enter'  
        @leave='leave'   
        :css='false'>
        <class='js-class' v-show="show" >456</p>
    </transition>
    .js-class{
        position: absolute;
        top: 50px;
        left: 50px;
        color: red;
    }

    使用js操作动画:
            beforeEnter:function(el){
                $(el).css({
                    left:'-500px',
                    opacity:0
                })
            },
            enter:function(el,done){
                $(el).animate({
                    left:'50px',/*进入的时候,跑到left到50位置*/
                    opacity:1
                },{
                    duration:1500,/*执行的ms数*/
                    complete:done /*完成的之后*/
                });
            },
            leave:function(el,done){
                $(el).animate({
                    left:'500px',/*离开的时候,向右移动500px后消失*/
                    opacity:0
                },{
                    duration:1500,/*离开时间*/
                    complete:done
                })
            }
    动画会在左右动作,没有定义的top不会有影响


    1.4.2 自定义指令

    使用的v-if等是内置的指令,

    (1)局部自定义指令

    在一个组件中定义的,只能在这一个组件中使用
    定义自定义指令,使用
        directives:{
            //自定义指令color,binding是传入的值
            color:function(el,binding){
                el.style.color=binding.value
            }
        }
    使用自定义指令:
    <v-color="'red'">hello123</p>
    传入的值使用"' '"包裹着

    (2)全局自定义指令

    只需要把自定义的指令放到根节点的组件中定义即可

    (3)更细致定义

    一个自定义对象可以定义几个钩子函数,
    没有声明的时候,默认是bind和update
    bind:
    只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
    inserted
    被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
    update
    所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
    componentUpdated
    指令所在组件的 VNode 及其子 VNode 全部更新后调用
    unbind
    只调用一次,指令与元素解绑时调用。

            //自定义指令color
            color:{
                bind:function(el,binding){
                    el.style.color=binding.value
                },
                inserted:function(el){
                    
                }
            }

    (4)案例:input获取光标

    focus:{
        inserted:function(el,binding){
            el.focus()
        }
    }
    <input type="text" v-focus />

    1.4.3插件

    在vue项目的package.json文件中,就可以看到项目的依赖
    • 安装插件
      • 使用node.js,进入项目包,输入:  cnpm install vue-router --save
      • 再次打开package.json可以看到这插件
    • 引用插件
      • 在要调用的vue文件中进行引用,若是所有的页面都会用到的,可以在main.js中引用
      • import VueRouter from 'VueRouter '        
      • 也可以 import VueRouter from ' vue-router'   
      • 也可以 var VueRouter =require( ' vue-router' )

    • 注册使用
      • Vue.use(VueRouter )
    • 正式引入
      • 方法1:    
        • 定义:   let router=new VueRouter ()
        • 在组建中引入router,
      • 方法2:  若是已经引入了vueresource,可以直接在组建中定义
        • this.$http.get('')






    2.vue-cli

    2.1vue-cli概述

    Vue-cli-vue 官方提供的脚手架工具
    • 作用:初始化一个Vue项目
    • 优势:
      • 成熟的vue项目架构设计
      • 本地测试服务器
      • 集成打包上线方案
    • 要求:
      • Node.js(>=4.x)
      • Git
      • 一个能使用node的命令行终端



    启动项目:
    npm run start
    一个template中只能有一个根元素, 
    定义参数data要用function 

    style可以加上scoped使样式局部

    2.1.1es6语法


    • 导出:
      • Hello.vue导出
      • 方法1:
      • 方法2:

    • 导入:

    • 声明变量
      • 在当前作用域下:let
      •  本文件都可以取到var
      • 常量:const router=new VueRouter

    • 引入数据
    在组建中使用data,要使用return的方式
    <script>
    export default {
      name'HelloWorld',
      data () {
        return {
          msg'Welcome to Your Vue.js App'
        }
      }
    }
    </script>

    2.1.2 vue-rouer 路由

    (1)安装/配置:

    进入项目目录:(在搭建项目的时候安装了)
      cnpm install vue-router --save
    
    项目中载入,一般在main.js中载入:
        import VueRouter from 'vue-router'
        Vue.use(VueRouter)
        let router = new VueRouter({})    //其中配置路径和地址
    在Vue中引入:
        new Vue({
          el: '#app',
          router,
          template: '<APP/>',
          components: { APP }
        })

    (2)基础案例:路径访问(映射表)

    路径:http://localhost:8080/apple/    ,访问一个页面
    • 定义一个vue页面Apple:
    <template>
        <div class="apple">213124</div>
    </template>
    <script>
    export default {
      name'Apple'
    }
    </script>
    <style scoped>
    </style>

    • new VueRouter({})所在页面引入:
    import Apple from '@/components/Apple'

    • 在new VueRouter({}) 中引入:
      routes: [
           mode:'history',
        {
            path:'/apple',
            component:Apple
        },
         {
            path:'/apple2',
            component:Apple2
        }
        
      ]

    • APP.vue中引入(会在这里显示)
    <router-view></router-view>

    (3)页面内跳转

    要在   mode:'history',    之下
        <router-link :to="{path:'apple'}">to apple</router-link>
         <router-link :to="{path:'apple2'}">to apple2</router-link>

    (4)路由参数

    路由参数在映射表中进行
    设置参数:
        path:'/apple/:color',
    页面:
        http://localhost:8080/apple/red
    获取参数:
        在Apple.vue获取:
            <div >{{$route.params}}</div>    { "color": "red" }
    		<div >{{$route.params.color}}</div>    red
        在Apple.vue方法中获取:this.$route.params
    点击按钮,显示参数:{ "color": "red" }
    这种情况下,路径上若是没有参数,将会不能进入这个页面

    多个参数:
      path:'/apple/:color/deee/:aa',
    其中:color和:aa是用户可以自定义的参数,可以是任何内容;
    deee是路径,不能修改
    可以的访问路径为:http://localhost:8080/apple/red/deee/asas
    只有带:  的参数才会在$route.params中

    (5)路由嵌套(子路由)

        {
            path:'/apple',
            component:Apple,
            childdren:[
                {
                    path:'/childapple/',
                    component:ChildApple
                }
            ]
        },
    在这个页面import引入

    内容要在Apple.vue中添加
    <router-view></router-view>
    页面跳转:

    (6)router-link,页面内跳转,声明试导航

    普通页面跳转
    <router-link :to="{path:'apple'}">to apple</router-link>
    基于当前路径跳转
        <router-link :to="'apple'">to apple</router-link>
    根目录:
        <router-link :to="'/apple'">to apple</router-link>
    动态设置:
        <router-link :to="apple">to apple</router-link>
        在data中:
          data(){
          	reurn{
          		apple:'apple'
          	}
          }
    传递参数:
        <router-link :to="{path:'apple',param:{color:'red'}}">to apple</router-link>
        可以访问 apple/red(参数)
    改变router-link显示样式:
        <router-link :to="'apple'" tag="li">to apple</router-link>

    (7)js中定义导航,跳转

    router.push('apple') //或 {path:'apple'}
    或
    this.$router.push('/login');

    (8)路由命名

        {
        	path:'/apple',
        	component:Apple,
        	name:'applePage'
        	
        }
    访问:
        <router-link :to="{name:'applePage'}">to apple</router-link>

    • 命名路由视图
    在router-view 上添加name
    <router-view name='viewA  '></router-view>
    路由表中可以根据name定义页面
        {
        	path:'/apple',
        	component:{
        		viewA:Apple,
        		viewB:OtherApple,
        	},
        	name:'applePage'
        }

    (9)路由重定向

    比如默认页面是具体的某一个页面,比如访问根目录,会自动跳转到Apple.vue目录
      {
          path:"/",
          redirect:'/apple'
      },

    (10)页面跳转--过渡

        <transition name='fff'>
        	<keep-alive><!--缓存-->
        		<router-view></router-view>
        	</keep-alive>
        </transition>

    2.2vuex 状态管理

    2.2.1引入

    import  Vuex from  'vuex' /*引入*/
    Vue.use(Vuex) /*使用*/
    let store=new Vuex.Store({ /*调用*/
    state:{/*数据中心的数据*/
    totalPrice:0
    },
    mutations: {/*动作*/
    increment(state, price) {/*增加*/
    state.totalPrice += price
    },
    decrement(state, price) {/**/
    state.totalPrice -= price
    }
    }
    })
    在全局中引用:(在main.js中的vue中引用)
    new Vue({
    el: '#app',
    router,
    store ,
    components: { App },
    template: '<App/>'
    })
    其他文件调用:
    在上面引用之后,每个组件都可以使用:
    this.$store.state.totalPrice

    (1)案例:全局加减

    创建Apple和Banana两个vue文件,在APP.vue中引入
    方法1:
    <template>
    <div id="app">
    <img src="./assets/1ogo.png">
    {{ totalprice }}
    <apple></apple>
    <banana></banana>
    </div>
    </template>
    <script>
    import Apple from'./components/apple'
    import Banana from './components/banana'
    export default {
    components: {Apple, Banana},
    computed:{/*计算属性*/
    totalPrice(){
    return this.$store.state.totalPrice
    }
    }
    }
    </script>
    每一个vue组件都有一个+1和-1的按钮
    <template>
    <div>
    <h1>{{msg}}</h1>
    <button @click="addOne">addOne</button>
    <button @click="minusOne">minusOne</button>
    </div>
    </template>

    <script>
    export default {
    name: "Apple",
    data(){
    return{
    msg:'i am apple',
    price:5 /*香蕉是15*/
    }
    },
    methods:{
    addOne(){
    this.$store.commit('increment',this.price)
    },
    minusOne(){
    this.$store.commit('decrement',this.price)
    }
    }
    }
    </script>

    方法2:
    let store=new Vuex.Store({  /*调用*/
    state:{/*数据中心的数据*/
    totalPrice:0
    },
    mutations: {/*动作,只能同步操作*/
    increment(state, price) {/*增加*/
    state.totalPrice += price
    },
    decrement(state, price) {/**/
    state.totalPrice -= price
    }
    },
    actions:{/*mutations之前的动作,可以先异步操作,再调用mutations中的方法*/
    increase(context,price){
    context.commit('increment',price)
    }
    }
    })
    addOne(){
    this.$store.dispatch('increase',this.price)
    },



    • 在Store中还可以设置getters获取数据
    getters:{/*获取数据*/
    getTotal(){
    return state.totalPrice
    //APP.vue中方法获取totalPrice,可以直接用
    // this.$store.getters.getTotal获取
    }
    },

    可以定义多个状态集,最后汇总

    2.3 vue-resource:整合ajax

    在main.js中
    import VueResource from 'vue-resource'
    Vue.use(VueResource)
    每一个页面都可以使用this.$http  

    2.3.1 ajax案例

    • get:
        /*ajax请求 */
        this.$http.get('api/getNewsList')
        .then((res) => {/*成功回调*/
          this.newsList = res.data //赋值
        }, (err) => {/*失败回调*/
          console.log(err)
        })
    • post
    this.$http.post(this.GLOBAL.urlHead+'manager/login',{managerUserName:this.ruleForm.username,managerPass:this.ruleForm.password},{emulateJSON:true})
                    .then((res) => {/*成功回调*/
                      if (res.data.state==1) {
                        alert(res.data.msg)
     localStorage.setItem('managerName',res.data.data.managerName);//ms_username
     localStorage.setItem('managerId',res.data.data.managerId);//ms_username
                        this.$router.push('/index');
                      }else {
                        alert(res.data.msg)
                      }
                    }, (err) => {/*失败回调*/
                      console.log(err)
                      alert("登录失败!")
                    });

    2.3.2 页面加载

      /*在组建创建完之后加载:页面加载*/
      created: function () {
        /*ajax请求 */
        this.$http.get('api/getNewsList')
        //post参数:.post('api/getNewsList',{userId:123,aa:44})
        .then((res) => {/*成功回调*/
          this.newsList = res.data //赋值
        }, (err) => {/*失败回调*/
          console.log(err)
        })
      },

    2.3.3页面初次加载判断

    使用一个没有定义的参数进行判断,默认为false,只需要判断完设置为true即可
          if (!this.userFlag) {
            errorText = ''
            this.userFlag = true
          }


    2.4 vue的UI组件

    2.3.3 轮播图组件


    2.3.4显示项目图片

    使用js设置的图片
    数据:src: require('../assets/slideShow/pic1.jpg')
    

    3.vue具体组件

    使用vue搭建项目的时候,一般的目结构为:

    3.1 侧边栏

    <template>
      <div class="left-nav">
        <ul>
            <li>
                <i class="icon iconfont icon-wodezichan"></i>
                <div>收银</div>
            </li>
    
            <li>
                <i class="icon iconfont icon-dianpu"></i>
                <div>店铺</div>
            </li>
    
            <li>
                <i class="icon iconfont icon-hanbao"></i>
                <div>商品</div>
            </li>
    
             <li>
                <i class="icon iconfont icon-huiyuanqia"></i>
                <div>会员</div>
            </li>
    
             <li>
                <i class="icon iconfont icon-shijian"></i>
                <div>抢购</div>
            </li>
    
            <li>
                <i class="icon iconfont icon-tongji"></i>
                <div>统计</div>
            </li>
    
    ·
        </ul>
      </div>
    </template>
    
    <script>
    export default {
      name: 'Main',
      data () {
        return {
          
        }
      }
    }
    </script>
    
    <!-- Add "scoped" attribute to limit CSS to this component only -->
    <style>
        .left-nav{
           color:#fff;
           font-size:10px;
           height:100%;
           background-color: #1D8ce0;
           float:left;
           5%;
        }
        .iconfont{/*设置图标大小*/
           font-size:24px;
        }
        .left-nav ul{
            padding:0px;
            margin: 0px;
        }
        .left-nav li{
            list-style: none;
            text-align: center;
            border-bottom:1px solid #20a0ff;
            padding:10px;
        }
    </style>
    • APP.vue中引用:
     <leftNav></leftNav>
    import leftNav from '@/components/common/leftNav'
    components:{
        leftNav
      }
    同时要调整APP的样式(比如#APP的margin-top)

    复制,赋值不绑定



    vue表单校验

    vue.js校验

    给定一个表单,包含三个字段,其中两个是必填项
    <form
      id="app"
      @submit="checkForm"
      action="https://vuejs.org/"
      method="post"
    >
    解释:
        id 确认vue的
        submit 处理函数
        action 跳转路径

    <form
      id="app"
      @submit="checkForm"
      action="https://vuejs.org/"
      method="post"
    >
    
      <p v-if="errors.length">
        <b>Please correct the following error(s):</b>
        <ul>
          <li v-for="error in errors">{{ error }}</li>
        </ul>
      </p>
    
      <p>
        <label for="name">Name</label>
        <input
          id="name"
          v-model="name"
          type="text"
          name="name"
        >
      </p>
    
      <p>
        <label for="age">Age</label>
        <input
          id="age"
          v-model="age"
          type="number"
          name="age"
          min="0">
      </p>
    
      <p>
        <label for="movie">Favorite Movie</label>
        <select
          id="movie"
          v-model="movie"
          name="movie"
        >
          <option>Star Wars</option>
          <option>Vanilla Sky</option>
          <option>Atomic Blonde</option>
        </select>
      </p>
    
      <p>
        <input type="submit" value="Submit">
      </p>
    
    </form>

    const app = new Vue({
      el: '#app',
      data: {
        errors: [],
        name: null,
        age: null,
        movie: null
      },
      methods:{
        checkForm: function (e) {
          if (this.name && this.age) {
            return true;
          }
    
          this.errors = [];
    
          if (!this.name) {
            this.errors.push('Name required.');
          }
          if (!this.age) {
            this.errors.push('Age required.');
          }
    
          e.preventDefault();
        }
      }
    })

    vue.js自定义校验

    <form
      id="app"
      @submit="checkForm"
      action="https://vuejs.org/"
      method="post"
      novalidate="true"
    >
          
     <p>
        <label for="email">Email</label>
        <input
          id="email"
          v-model="email"
          type="email"
          name="email"
        >
      </p>     
          
          
    注意顶端的 novalidate="true"
    浏览器会尝试在 type="email" 的字端校验邮件地址
    const app = new Vue({
      el: '#app',
      data: {
        errors: [],
        name: null,
        email: null,
        movie: null
      },
      methods: {
        checkForm: function (e) {
          this.errors = [];
    
          if (!this.name) {
            this.errors.push("Name required.");
          }
          if (!this.email) {
            this.errors.push('Email required.');
          } else if (!this.validEmail(this.email)) {
            this.errors.push('Valid email required.');
          }
    
          if (!this.errors.length) {
            return true;
          }
    
          e.preventDefault();
        },
        validEmail: function (email) {//自定义校验规则
          var re = /^(([^<>()[]\.,;:s@"]+(.[^<>()[]\.,;:s@"]+)*)|(".+"))@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}])|(([a-zA-Z-0-9]+.)+[a-zA-Z]{2,}))$/;
          return re.test(email);
        }
      }
    })

    其他校验方法
















  • 相关阅读:
    dimensionality reduction动机---data compression(使算法提速)
    K-means:如何选择K(cluster的数目)
    python2和python3共存方法
    docker postgresql 数据库
    转:MySQL到底能支持多大的数据量?
    数据库jdbc链接:mysql, oracle, postgresql
    python获取参数列表
    转载:ubuntu系统启动顺序,常见系统服务说明
    使用postman开发testcases记录贴
    python gevent使用例子
  • 原文地址:https://www.cnblogs.com/ziyue7575/p/42e7ef2211f3ed5d53d796f879184064.html
Copyright © 2020-2023  润新知