vue2.0基础知识,及webpack中vue的使用

## 基础指令 ##

    [v-cloak]{
        Display:none;
    }
    <p v-cloak>xx{{msg}}xx</p> //解决闪烁问题,xx显示
    <p v-text='msg'>xxxx</p> //引入数据,默认没有闪烁问题,xxxx不显示
    <p v-html='msg2'>xxxx</p> //引入html
    <p v-for='(item,i) in user'>{{item}}</p> //v-for遍历数组
    <p v-for='count in 10'>{{ count }}</p> //v-for遍历数字,执行10次
    <p v-for='(val,key,i) in user' :key="item.id">{{item}}</p> 
    //v-for遍历数对象,i为索引,:key为唯一性关联
    <input type="button" v-bind:title="mytitle">  //绑定属性的指令,v-bind:可简写为:
    <input type="button" v-on:click="show">  //绑定事件方法,v-on: 可简写为@
    
    <p v-if='flag'>xxxx</p> //dom添加删除元素
    <p v-show='flag'>xxxx</p> //通过display隐藏元素

    var vm= new Vue({
        el:"#app",
        data:{
            msg:"123",
            msg2:"<h2>title</h2>",
            mytitle:"这是title",
            user:[1,2,3,4]
        },
        methods:{ //绑定事件的方法
            show:function(){****
                this.msg="改变" 
                //在方法中改变数据,页面中数据会同步改变,用this引用数据源
            }
        },
        watch:{  //监听data中数据的改变
            'mytitle':function(newVal,oldVal){ //oldVal为老的值
                Console.log(newVal)  //新的值
            }
        },
        computed:{ //设置数据的计算属性,相当于新增数据,有关数据变化,该值也变
            'fullMsg':function(){
                return this.msg+this.msg2
            }
        }
    })
    <p v-cloak>xx{{ fullMsg}}</p>  //直接调用计算属性的数据
    //{{msg}}双花括号数据显示,其实是省略了该vue对象的this指向,直接调用对象的方法,也可以直接调用类似$route.query等内置的属性和值{{$route.query }}

## 事件修饰符 ##

    <input type="button" @click.stop="show">  //阻止事件冒泡
    <a href="www.baidu.com" @click.prevent.once="show"></a>  //阻止默认行为


## 表单元素中的双向数据绑定v-model ##

    <input type="text" v-model="msg">  //input中输入数据,实时更新Vue中data

## 添加样式 ##

### 类名样式 ###

    <h1 :class="['thin','italic',flag?'active':'']">xxx</h1>
    <h1 :class="['thin','italic',{'active':flag}]">xxx</h1>  //两种写法
    <h1 :class="{red:true,thin:true}">xxx</h1> //可写对象,key为类名
    //其中thin,italic,active都是有样式的类名,flag是Vue中data中设置的数据

### stlye样式 ###

    <h1 :style="{color:'red','font-weight':200}">xxx</h1>
    <h1 :style="[styleObj1,styleObj2]">xxx</h1>

## 安装Vue调试工具 ##

Vue-devtools chrome插件

## Vue过滤器filer ##

    <p>{{ msg | msgFormat }}</p> //过滤显示数据
    Vue.filter(‘msgFormat’,function(){  //全局过滤器
        return msg.replace(‘a’,’b’);
    })
    var vm= new Vue({
        el:”#app”,
        filters:{  //写在实例化Vue对象中filters中的为私有过滤器
              fileName:function(data){  //定义过滤器名称
            }
        }
    })

## 按键修饰符 ##

    <input type=”text” @keyup.enter=”show”>  //enter为按键修饰符,监听回车

//如果不为上述按键可以使用键盘码:@keyup.112=”show”
Vue.config.keyCodes.f2=113;  //自定义键盘修饰符

## 自定义指令v-focus ##

    Vue.directive(‘focus’,{  //全局设置eyup.112=”show” 
        bind:function(el,binding){},  //当指令绑定到元素上时,执行,样式相关
        inserted:function(el){},  //当元素插入DOM中后执行,js行为相关
        updated:function(el){},  //当Vnode更新时执行,可能触发多次
    })
    var vm= new Vue({  //局部设置
        el:”#app”,
        directives:{  //自定义私有指令
            ‘fontWeight’:{
                bind:function(el,binding){}
            },
            ‘fontsize’:function(el,binding){
                 //直接写等同于写入bind和    update中
            },
        }
    })

### 钩函数中,传递的参数意义 ###


## 生命周期 ##


## vue-resource插件发送ajax ##

### 引入插件 ###

    Vue.http.options.root=”http://vue.study.rgo”;//全局设置resourse配置项
    Vue.http.options.emulateJSON=true
    new vue({  //局部配置
        http:{
            root:’/root’,
            headers:{
                Authorization:’xxxx’
            }
        }
    })
    var vm= new Vue({  //局部设置
        el:”#app”,
        methods:{  //自定义私有指令
             postInfo(){
                this.$http.post(url,{params},{options}).then(success,error)
            }
        }
    })

## vue中的动画效果 ##

### 自定义类动画 ###

    .name-enter,name-leave-to{ //时间点,动画进入之前/动画离开之后
        opacity:0;
        transform:translateY(100px);
    }
    .name-enter-active,name-leave-active{ //入场/离场动画时间段
        opacity:0;
        transform:translateY(100px);
    }
    <transition name=”name” mode=”out-in”> //mode设置动画切换模式
        <h3 v-if=”flag”>这是动画</h3>
    </transition>

### 引入第三方css动画,如animate.css ###

    <transition enter-active-class=”bounceIn” leave-active-class=” bounceOut” :duration=”{enter:200}”>
        <h3 v-if=”flag” class=”animated”>这是动画</h3> 
        //加入animated类名动画才生效,也可将类名加在transition标签上
    </transition>

### 使用动画钩函数(只演示进场动画) ###

    <transition @before-enter=”beforEnter” @ enter=”enter” @after-enter=”afterEnter”>
        <h3 v-if=”flag”>这是动画</h3>
    </transition>
    var vm= new Vue({  
                el:”#app”,
                methods:{  
                    beforeEnter(el){
                        el.style.transform=”translate(0,0)”
                    },
                    enter(el,done){
                        el.offsetWidth //需要操作offset动画才生效
                        el.style.transform=”translate(150px,450px)”;
                        el.style.transition=”all 1s ease”;
                        done(); //done等同于调用了afterEnter,建议调用
                        },
                    afterEnter(el){  
                        this.flag=!this.flag
                    }
                }    
        })

### v-for创建的标签使用<transition-group>包裹才能实现动画 ###

    <transition-group appear tag=”ul”>
        //appear属性使整个标签实现渐入效果,tag属性指定transition-group为ul标签,默认为span
        <li v-for=”item in list” :key=”item.id”>  //如果要为每一个元素设置动画需要key属性
            {{item.id}} --- {{item.name}}
        </li>
    </transition-group>

### 移除动画设置: ###

    .v-move{
        transition:all 0.6s ease;
    }
    .v-leave’-active{
        position:absolute;
    }

## vue中的组件(组件template属性必须用唯一根元素) ##

### 全局组件 ###

    var com1=Vue.extend({
            template:’<h3>这是组件名称</h3>’;
            //使用template定义组件需要的html
        })
    Vue.component(‘myCom1’,com1) //驼峰命名,标签要变-连接
    可合写为:
    Vue.component(‘myCom1’, Vue.extend({
        template:’<h3>这是组件名称</h3>’;
    })) 
    <div id=”app”>
        <my-com1></my-com1>
    </div>    

### 组件的其他写法 ###

        一、
            Vue.component(‘myCom1’, {
                template:’<h3>这是组件名称</h3>’;
            }) 
        二、
            <div id=”app”></div>
                <template id=”tmp1”>  //写在app外面
                    <h3>这是组件</h3>
                </template>
            Vue.component(‘myCom1’, {
                template:’#tmp1’;
            }) 

### 定义私有组 ###

    var vm2= new Vue({  
                el:”#app2”,
                components:{  
                    tmp1:{
                        template:’<h3>私有组件tmp1</h3>’;
                    }
                }
            })

### 组件中的数据和方法 ###

    Vue.component(‘myCom1’, {
            template:’#tmp1’;
            data:function(){  //data必须为返回一个对象的函数
                return:{count:0}
            },
            methods:{
                increment(){
                    this.count++
                }
            }
    }) 

### 组件切换 ###

    <div id=”app”>
        <a @click.prevent=”comName=’login’”>登录</a>
        <a @click.prevent=”comName=’register’”>注册</a>
        <component :is=”comName”></component>
        //vue中定义用于组件占位的标签
    </div>

### 组件动画 ###

    <transition mode=”out-in”> //mode设置动画切换模式
        <component :is=”comName”></component>
    </transition>

### 父子组件之间数据/方法传递 ###

    <div id=”app”>
        //在子组件绑定一个私有属性,通过这个属性传递数据
        <comp1 v-bind:parentmsg=”msg” v-on:func=”show”></comp1>
    </div>
    var vm2= new Vue({  
                el:"#app",
                data:{
                    msg:"123 父组件数据"
                },
                methods:{
                    show(data1,data2){
                        console.log(‘调用了父组件方法’)
                    }
                },
                components:{  
                    comp1:{
                        template:’<h3 @click=”myclick”>私有组件{{ parentmsg }}</h3>’,
                        data(){ //子组件私有的数据,可读可写
                            return {title:”123”,content:”xxx”}
                        },
                        props:[‘parentmsg’], //在props中引入父组件传入的数据,只读
                        methods:{
                            myclick(){
                                this.$emit(‘func’,112,333) //调用父组件方法,112,333为传入参数
                            }
                        }
                    }
                }
            })

## 通过ref属性获取dom和子组件的数据/方法 ##

    <h2 ref=”myh2”>这是h2标签</h2> //这是dom
    <login ref=”mylogin”></login> //这是组件
    var login={
            template:’<h1>登录组件</h1>’,
            data:function(){  //data必须为返回一个对象的函数
                return:{msg:”这是登录信息”}
            },
            methods:{
                show(){
                    console.log(‘show’)
                }
            }
        }
    var vm2= new Vue({  
            el:”#app”,
            data:{
                msg:”123 父组件数据”
            },
            methods:{
                getElement(){
                    this.$refs.myh2  //获取dom
                    this.$refs.login.msg  //获取子组件的data
                    this.$refs.show()  //获取子组件的方法
                }
            },
            components:{  
                login
            }
        })

## vue中的路由vue-router ##

    1. 前端路由原理

    hash的使用:
    http://www.baidu.com#/login    //网页url中#后面的部分称为hash,当页面hash发生改变时,页面不会向后端发送http请求,页面也不会跳转,但是页面本身会发生部分显示改变,例如使用锚点展示显示内容,这样可以使用hash来完成单页面的应用

    2.vue-router的安装

    在模块化工程(webpack)中必须使用Vue.use()明确安装路由功能
    import Vue from ‘vue’
    import VueRouter from ‘vue-router’
    Vue.use(VueRouter) //给vue注册router功能

    3.vue-router的基本使用方法

    <div id=”app”>
        //使用a标签点击跳转路由
        <a href=”#/login?id=10&name=jim”>登录</a>  //直接在url中传递参数
        <a href=”#/register/10/jack”>注册</a> //url传递参数的第二种方式,传入设置规则的参数
        //使用router-link标签点击跳转路由,特殊标签,默认渲染为a标签
        <router-link to=”/login”>登录</router-link>
        <router-link to=”/ register” tag=”span”>注册</router-link> //渲染为span
        <router-view></ router-view > //特殊标签,相当于路由的占位符
        //可使用动画标签设置路由动画切换
        <transition name=”name” mode=”out-in”> //mode设置动画切换模式
            <router-view></ router-view > //此处路由会动画切入
        </transition>
    </div>
    //url第一种传参解析
    var login={
            template:’<h1>登录组件----{{$route.query.id}}---{{$route.query.name}}</h1>’,
            data(){
                return {msg:’123’}
            },
            created(){ //组件生命周期创建之初后,
                Console.log(this.$route.query.id) //获取路由url中传递的参数
            }
        }
    //url第二种传参解析
    var register={
            template:’<h1>注册组件----{{$route. params.id}}---{{$route. params.name}}</h1>’,
            data(){
                return {msg:’123’}
            },
            created(){ //组件生命周期创建之初后,
                console.log(this.$route.params.id) //获取路由url中传递的参数
            }
        }
    var routerObj=new VueRouter({ //创建路由对象
            routes:[
                    {path:’/’,redirect: login }, //重定向
                    {path:’/login’,comppnent: login },
                    {path:’/register/:id/:name’,comppnent: register }, //设置路由参数
            ],
            //被激活的类名为router-link-active,可设置当前选中路径标签的样式,也可如下操作
            linkActiveClass:’myactive’ //设置选中高亮的标签的样式类名
        })
    var vm=new Vue({
            el:”#app”,
            data:{},
            methods:{},
            router: routerObj, //引入路由对象
            watch:{  //通过$route.path监听路由的改变
                ‘$route.path’:function(newVal, oldVal){
                    console.log(oldVal)
                }
            }
        })

    4.设置子路由

    <div id=”app”>
        <router-link to=”/account”>Account</router-link>
        <router-view></ router-view > 
    </div>
    <template id=tmp1>
        <div>
            <h2>这是Account组件</h2>
        <router-link to=”/account/login”>登录</router-link>
        <router-link to=” /account/ register” tag=”span”>注册</router-link>
        <router-view></ router-view > 
        </div>
    </template>
    var account={
        template:’#tmp1’,
    }
    var login={
        template:’<h1>登录组件</h1>’,
    }
    var register={
        template:’<h1>注册组件</h1>’,
    }
    var routerObj=new VueRouter({ //创建路由对象
        routes:[
            {
                path:’/account’,
                component: account,
                children:[ //设置子路由                    {path:’login’,component:login}, //路径不要写斜线,不然认为到根路径
                    {path:’register’,component: register },
                ]
            }, 
        ],
    })

    5.设置多个路由

    <div id=”app”>
        <router-view></ router-view > 
        <router-view name=”left”></ router-view >
        <router-view name=”right”></ router-view >
    </div>
    var routerObj=new VueRouter({ //创建路由对象
        routes:[
            {
                path:’/account’,
                components: { //显示多个路由使用conponents复数,key为router-view中的name
                    ‘default’:header, //第一个可以用默认组件name:default,不写name
                    ‘left’:leftBox,
                    ‘main’:mainBox
                },
            }, 
        ],
    })

## json格式文件中不能写注释 ##

## vue中的render方法替换组件 ##

    <div id="app">
        <login></login>
    </div>
    var login={
        template:"<h1>这是登录组件</h1>"
    }
    var vm=new Vue({
        el:'#app'
        data:{},
        methods:{},
        render:function(createElements){  //传递的参数是一个方法,能够将指定的模板组件渲染为html
            return createElements(login) //这类的return结合会替换vue中el指定的那个容器,本案例中替换id="app"容器
        }            
    })

## 在webpack中使用vue ##

    import Vue from 'vue' //引入vue,其实默认引入的是vue.runtime版本在webpack中使用的,在网页中使用的话需要引入vue.js
    引入规则:
    1. 查找项目中的node_modules文件夹
    2. 在node_modules文件夹下找到对应的vue文件夹
    3. 在vue文件夹中,找到package.json包的配置文件
    4. 在package.json中,查找main属性,里面写入了包的入口路径
    修改路径:
    //在webpack.config.js文件中添加规则即可
    resolve:{
        alias:{ //修改vue导入的路径
            "vue$":"vue/dist/vue.js"
        }
    }
    //也可直接引入
    import Vue from '../node_modules/vue/dist/vue.js'

### 创建.vue文件使用webpack中默认的vue.runtime来构建组件 ###

1. 安装loader:vue-loader vue-template-compiler
2. webpack.config中配置loader:{test:/\.vue$/,use:'vue-loader'}
3. 创建包含template script style的xxxx.vue文件

        <template>
            <h1>这是登录组件</h1>
        </template>
        <script></script>
        <style></style>

4. 在需要渲染组件的页面使用render引入组件

        import xxxx from './xxxx.vue'
        var vm=new Vue({
            el:'#app'
            data:{},
            methods:{},
            render:function(createElements){  
                return createElements(xxxx) 
            }            
        })

## 在webpack中使用vue-router ##

新建route.js文件并设置路由
    import VueRouter from 'vue-router' //导入路由包
    Vue.ues(VueRouter)  //安装vueRouter

    //导入组件
    import account from './main/Acount.vue'
    import goodsList from './main/GoodsList.vue'
    import login from './main/login.vue'
    import register from './main/register.vue'

    var router = new VueRouter({  //创建路由对象
        routes:[
            {
                path:'/account',
                component:account,
                children:[ //设置子组件
                    {path:'login',component:login},
                    {path:'register',component:register}
                ]
            },
            {path:'/GoodsList',component:goodsList,name:'goodsList'}
        ]
    })
    export default router //暴露路由对象
在main.js:
    
    import Vue from 'vue'
    import app from './App.vue'
    import router from './route.js'
    var vm=new Vue({
        el:'#app',
        render:c=>c(app),
        router    
    })


在App.vue文件中:

    <template>
        <div>
            <h1>这是App组件</h1>
            <router-link to="/account">Account</router-link>
            <router-link to="/account">Account</router-link>
            <rounter-view></router-view>
        </div>
    </template>

在Account.vue中:

    <template>
        <div>
            <h1>这是Account组件</h1>
            <router-link to="/account/login">登录</router-link>
            <router-link to="/account/register">注册</router-link>
            <rounter-view></router-view>    
        </div>
    </template>
    <style lang="scss" scoped> //lang属性指定使用语言,此处使用scss,scoped属性表明样式只对当前组件生效,原理是自动加上一个属性选择器
        body{
            div{
                color:"red"
            }
        }
    </style>
在GoodsList.vue中:

    <template>
        <div>
            <h1>这是GoodsList组件</h1>
        </div>
    </template>
在index.html中:

    <body>
        <div id="app"></div>
    </body>

如果使用编程式导航(window.location.href)跳转则可通过控制$router.push

    this.$router.push("/home/goodsList"+id)
    //或者
    this.$router.push({path:"/home/goodsList"+id}})
    //或者使用路由的name
    this.$router.push({name:"goodsList",params:{id}})

## 在父组件中引用子组件 ##

    <template>
        <comment-box :id="this.id"></comment-box> //父组件向子组件传值
    </template>
    <script>
        //引入子组件页面
        import comment from "../subcomponent/comment.vue";
        export default{
            components:{
                "comment-box":comment //设置子组件标签名
            }
        }
    </script>
    //在comment.vue中接收父组件传递过来的值
    props:['id','max']
    //也可写成可以设置值类型的形式
    props:{
        id:Number,
        // 多种类型
        propB:[String, Number],
        // 必传且是字符串
        propC:{
          type:String,
          required:true
        },
        // 数字,有默认值
        propD:{
          type: Number,
          default: 100
        },
    }
    //可以通过watch监听props中值的变化
    watch:{
        max:function(newVal,oldVal){ //监听父组件max的值
            
        }
    }

## vuex的使用 ##

vuex是Vue配套的组件公共数据管理工具,可以将组件的一些共享数据保存到vuex中,方便整个程序中的任意组件直接获取或修改公共组件

    import Vuex from 'vuex'
    Vue.use(Vuex)
    //创造一个公共
    var store=new Vuex.Store({
        state:{ //公共数据集,类似vue中的data
            count:0
        },
        mutations:{ //对公共数据的操作方法,;类似vue中的methods
            increment(state,params){ //方法中只能传递两个参数,第一个为公共数据集,第二个为向该方法传递的参数
                state.count++;
            },
            subtract(state,params){ 
                state.count-=(params.a+params.b);
            }
        },
        getters:{ //可以对数据进行获取并包装再返回
            optCount:function(state){
                return '当前最新的count值是:'+state.count
            }
        }
    })

    //挂载公共数据集的数据
    const vm = new Vue({
        el:'#app',
        render:c=>c(App),
        store
    })
    //获取store数据集中的数据
    <input type="text" v-model="$store.state.count">
    //获取getters中的数据
    <h3>{{$store.getters.optCount}}</h3>
    //调用公共集中的方法并操作公共集中的数据
    methods:{
        remove(){
            this.$store.commit('substract',{a:2,b:4})
        }
    }

## es6 export语法使用 ##

在test.js文件定义:

    var info={
        name:"tabb",
        age:18    
    }
    export default info //export default只能出现一次
    //暴露多个对象
    export var title="这是title"
    export var content="这是content"

在另一个test2.js文件中接收test.js中的信息

    import test123,{title,content as content123} from './test.js'
    {title,content} //这种方式称为按需导出
    console.log(tset123) //为export default中的内容
    console.log(title) //为额外暴露的内容
    console.log(content123) //可以使用as给content起别名

## 使用es6 Promise 处理回调嵌套(回调地狱)##

1. Promise是一个构造函数
2. Promise上有两个回调函数:resolve(成功之后的回调函数),reject(失败之后的回调函数)
3. 在Promise构造函数的Prototype属性上,有一个then()方法
4. Promise表示一个异步操作,每当new 一个Promise时,就表示一个具体的异步操作
5. 由于Promise创建的实例是一个异步操作,这个异步操作的结果只有两种状态:成功(resolve);失败(reject)
6. 可以在new出来的Promise实例上,调用then()方法,为这个Promise异步操作,指定成功(resolve)和失败(reject)回调函数

### 以读取文件为例的Promise异步操作示例 ###

    const fs = require('fs') //引入文件处理模块
    //封装一个读取文件的promise函数
    function getFileByPath(fpath){
        //此处resolve和reject为成功、失败的形参函数,直接返回promise对象
        return new Promise(function(resolve,reject){
            fs.readFile(fpath,'utf-8',(err,dataStr)=>{
                if(err) return reject(err)
                resolve(dataStr)    
            })
        })
        
    }
    //promise中then的使用,传入两个函数,第一个监听resolve执行,第二个监听reject执行
    getFileByPath('./files/1.text').then(function(data){
        console.log(data)
    },function(err){
        console.log(err)
    })
    //使用promise的then解决回调地狱,同时使用catch捕获reject的执行
    //只执行成功回调的异步操作,如果某次执行失败进入reject,操作终止
    getFileByPath('./files/1.text')
    .then(function(data){
        console.log(data)
        return getFileByPath('./files/2.txt') //将新生成的promise对象返回,可以直接在调用新对象的then
    })
    .then(function(data){
        console.log(data)
        return getFileByPath('./files/3.txt') 
    })
    .catch(function(err){ //捕获上述方法中的任意执行失败事件
        console.log(err)
    })

## 如果出现引用第三方callee等报错,修改babel的配置可去除webpack的严格模式 ##

babel-plugin-transform-remove-strict-mode 

posted @ 2018-06-28 17:13  Tabb.Coding  阅读(508)  评论(0编辑  收藏  举报