Vue基础

由于windows命令行比较原始不好用,可下载git命令行代替cmd命令行,并且安装nodejs环境

安装完nodejs环境后npm就安装成功了,这样才能使用npm命令。

以上是前提。

搭建项目过程:(创建好项目目录后,在该目录中执行命令)

 //npm会访问到国外的东西,速度慢,可用淘宝的npm镜像,也就是cnpm,先输入npm install -g cnpm --registry=https://registry.npm.taobao.org,在这之后就可以使用cnpm来执行npm的命令。速度更快。

#全局安装vue-cli:

  npm install --global vue-cli  或者  cnpm install --global vue-cli 

#创建一个基于webpack模板的新项目:

  vue init webpack my-project  //下划线部分为创建的文件名

#安装依赖包

  cd my-project  //进入目录

  npm install 或者 cnpm install

  npm run dev  //运行项目


 在项目文件中,代码中的@符号表示src目录。

 创建页面可在src目录中创建新的目录,并在新建的目录中创建目录以及文件即可。

  运行自己写的文件需要在router目录下导入,添加import component名 from '@/路径'。

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Demo2 from '@/pages/demo2/index.vue'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/', //代表域名后面的路径
      name: 'HelloWorld',
      component: HelloWorld   //新版本引入方式
    //component: require("@/pages/demo2/index.vue") 旧版本引入方式,有的版本不支持,建议使用上一种。 }, { path:
'/demo2', name: 'demo2', component: Demo2 } ] })

选项数据:

  • data
  • computed
  • methods
<template>
    <div>
        <div>选项数据</div>
        <div>-----------------------------</div>
        <div>{{msg}}</div><!--这里用{{}}包裹data中定义的数据来调用。-->
        <div>-----------------------------</div>
        <div>computed: {{numDouble}}</div>
        <div>-----------------------------</div>
        <div @click="say('hi')">点击我</div>
    </div>
</template>
<script>
    export default {
        data() { //全局组件的变量的定义,这是一个函数
            return {  //这里的return{}一定要写否则会报错。
                msg: 'hello 前端',  //数据绑定并自动显示到页面中
                num: 2
            }
        },

        computed: { //这是一个对象,在这里面定义各种函数。
            numDouble() {
                return this.num * 2;
            }
        },

        methods: { //里面主要写给事件用的函数
            say(h) {
                alert(h);
            }
        }
    }
</script>

模板语法:

  • data
  • 模板中直接嵌入代码
  • 指令 v-html、 v-on、v-bind等
  • 计算属性
  • 过滤器
<template>
    <div>
        <div>模板语法</div>
        <hr/>
        <div>
            data: {{msg}}
        </div>
        <div>----------------------------</div>

        <div>{{ num + 2 }}</div><!--模板当中可直接嵌入js代码-->
        <div>-----------------------------------</div>

        <div v-html="rawHtml"></div> <!--将HTML片段用这种方式放入div中,称为它的子元素-->
        <div>-----------------------------------</div>

        <div v-bind:class="red"></div><!--动态改变所取属性的值-->

        <div v-on:click="say('hi')">点击我</div><!--绑定事件-->
        <div>-------------------------------------------</div>
        <div @click="change()">修改颜色</div><!--绑定事件,这是v-on的简写方式-->

        <div>-------------------------------</div>
        <div>computed: {{ name }}</div>        <!--计算属性-->

        <div>----------------------------------</div>
        <div>{{ message | capitalize }}</div>  <!--过滤器,左边为原始值,右边为一个函数,可返回设置的值-->

    </div>
</template>

<script>
    export default {
        data() {
            return {
                msg: '你好啊前端',
                num: 3,
                rawHtml: '<span>666</span>',
                red: 'blue active',
                message: 'message'
            }
        },

        methods: {
            change() {
                this.red = 'blue';
                console.log(this);
            },
            say(h) {
                alert(h);
            }
        },

        computed: { //计算属性
            name() {
                return '计算属性';
            }
        },

        filters: { //专门给过滤器使用的对象
            capitalize() {
                return 123;
            }
        }
    }
</script>

计算属性:

  • 在模板中放入太多的逻辑会让模板过重且难以维护。
  • 计算属性下所有函数可以放到computed中。
<template>
    <div>
        <div>计算属性</div>
        <div>------------------------------</div>

        <div>msg: {{ reverseC }}</div> <!--在模板中调用函数只能写函数名,不能带有括号-->
    </div>
</template>

<script>
    export default {
        data() {
            return {
                msg: '你好前端'
            }
        },

        computed: {
            reverseC() {
                console.log(this.msg);//这里的this代表data()里定义的变量。
                
                // console.log(str);
                // console.log(typeof this.msg)
                // console.log(msg);  //这样会报错,未定义
                return this.msg.split('').reverse().join('');
            }
        }
    }
</script>

Class与Style绑定:

  v-bind指令:

  • 动态绑定一个或多个特性
  • 缩写 ‘ : ’
  • 原始写法   v-bind:class            缩写写法  :class

  Class绑定:

  1. 绑定1:{ 'active': isActive, 'text-danger': hasError }
  2. 绑定2:classObject
  3. 绑定3:[activeClass, errorClass]

  Style绑定:

  1. 绑定1:{ color: activeColor, fontSize: '16px' }
  2. 绑定2:StyleObject
  3. 绑定3:[baseStyles, overridingStyles]
<template>
    <div>
        <div>Class与Style绑定</div>
        <div>------------------------------</div>

        <!-- 第一种绑定方式 -->
        <div v-bind:class="{ 'active': isActive, 'text-danger': hasError }" v-bind:style="style">class</div>
        <!--上面其实是等于设置了一个class="active",{}内单引号的为类名-->

        <!-- 第二种绑定方式 -->
        <div :class="classObject">class2</div>
        <!-- 相当于传入一个变量,在data中设置 -->

        <!-- 第三种绑定方式 -->
        <div v-bind:class="[ activeClass, errorClass ]">class3</div>

        <!--其实以上三种方式大同小异,1,对象方式.2变量方式。3,数组方式
        <div :class="{ 'active': true, 'text-danger': false }"></div>
        <div :class="[{ 'active': true}, {'text-danger': false }]"></div>
        -->

        <div>---------------------------------------------</div>

        <div v-bind:style="{ 'color': activeColor, 'fontSize': fontSize + 'px' }">html</div>
        <div v-bind:style="StyleObject">css</div>
        <div :style="[ baseStyles, overridingStyle ]">JavaScript</div>

        <!--实际上都是一样的写法:
            <div v-bind:style="{ 'color': 'red', 'fontSize': '16px' }"></div>

            <div v-bind:style="[{ 'color': 'red' },{ 'fontSize': '30px' }]"></div>
        -->


    </div>
</template>

<script>
    export default {
        data() {
            return {
                isActive: true, //为ture的时候存在,这两个值不一定要这两个名字
                hasError: false,  //为false的时候消失
                style: 'color: red',

                classObject: {
                    'active': false,
                    'text-danger': true
                },

                activeClass: 'active',
                errorClass: 'text-danger',


                activeColor: 'yellow',
                fontSize: 16,

                StyleObject: {
                    fontSize: '20px',
                    fontWeight: 'bold'
                },

                baseStyles: {'color': 'pink'},
                overridingStyle: {'fontFamily': '微软雅黑'}
            }
        }


    }
</script>

条件渲染:

  • v-if 指令
  • v-if  v-else
  • v-if  v-else-if  v-else
  • v-show
<template>
    <div>
        <div>条件渲染</div>
        <div>----------------------------------</div>

        <h1 v-if="hehe">v-if值为true</h1>
        <!--v-if值为true,则该标签输出,false,该标签消失-->

        <div v-if="type === 'a'">a</div>
        <div v-else-if="type === 'b'">b</div>
        <div v-else-if="type === 'c'">c</div>
        <div v-else>d</div>
        <!--等同于js语法
            if ( type === 'a' ) {
                
            } else if ( type === 'b' ) {
    
            } else if ( type === 'c' ) {
    
            } else {
    
            }
        -->

        <div>-------------------------------------</div>
        <div v-show="Show">v-show效果类似v-if</div>
    </div>
</template>

<script>
    export default {
        data() {
            return {
                hehe: true,
                type: 'f',
                // Show: true
            }
        },
        methods: {
            Show() {
                return '666'; //会自动进行boolean类型转换
            }
        }
    }
</script>

列表渲染:

  • v-for指令:对模板进行for循环
  • 用法1:v-for="item in items" 数组
  • 用法2:v-for="(item, index) in items" 数组
  • 用法3:v-for="(value, key) in object" 对象
<template>
    <div>
        <div>列表渲染</div>
        <div>-----------------------------</div>
        <!-- 第一个种写法 -->
        <ul id="exp">
            <li v-for="item in items">
                {{ item }}
            </li>
        </ul><!--类似for-in遍历数组,生成多个li标签,注意这种写法只能是数组-->

        <div>-----------------------------------</div>

        <!-- 第二种写法 -->
        <ul id="exp">
            <li v-for="(item, index) in items">
                {{ index }} - {{ item }}
            </li>
        </ul><!--index代表下标,0开始-->

        <div>-------------------------------------</div>

        <!-- 第三种写法 -->
        <ul id="exp">
            <li v-for="( value, key ) in obj">
                {{ key }}: {{ value }}
            </li>
        </ul><!--这里类似用for-in遍历对象-->

    </div>
</template>

<script>
    
    export default {
        data() {
            return {
                items: [
                    '123',
                    456,
                    { message: '666' },
                    { message: 'bar' }
                ],
                obj: {
                    name: 'xiaoming',
                    age: 18
                }
            }
        }
    }

</script>

事件处理器:

  • v-on指令
  • 缩写@
  • 原始写法  v-on:click         缩写  @click
  • 事件修饰符
<template>
    <div>
        <div>事件处理器</div>
        <div>---------------------------------</div>
        <div>
            <button v-on:click="count++">增加1</button>
            <p>这个按钮被点击了{{ count }}次。</p>
            <!--这里是直接写js运算-->
        </div>

        <div>-----------------------------------</div>
        <div>
            <button @click="add()">增加1</button>
            <!--这里的add是一个方法名,事件中的方法名可以加括号,也可以不加-->
        </div>

        <div>-----------------------------------</div>
        <div>
            <button v-on:click="say('hi')">打招呼</button>
        </div>    

        <div>------------------------------------</div>
        <div @click="doThis2()">
            <button v-on:click="doThis">不会冒泡哦</button><!--添加事件修饰符.stop阻止事件冒泡-->
            <span @click="alert('???')">hahahahah</span>
            <!--此写法会报错,不支持window所带的方法-->
        </div>


    </div>
</template>

<script>
    
    export default {
        data() {
            return {
                count: 0
            }
        },
        methods: {
            add() {
                alert('略略略');
                console.log(this.count);
                this.count = this.count * 2;
            },
            say(h) {
                alert(h);
            },
            doThis() {
                alert('doThis');
            },
            doThis2() {
                alert('doThis2');
            }
        }
    }

</script>

表单控件绑定:

  • v-model指令在表单控件元素上创建双向数据绑定
  • 复选框
  • 多个勾选框
  • 选择列表
<template>
    <div>
        <div>表单控件绑定</div>
        <div>--------------------------------------</div>

        <input v-model="message">
        <p>Message is: {{ message }}</p> <!--两者绑定,同时变化,双向绑定-->

        <div>--------------------------------------</div>
        
        <!-- 多选框 -->
        <input type="checkbox" value="js" v-model="checkedNames">
        <label for="js">js</label>
        <!-- 1,选中。
        2,checkedNames = [];
        3, checkedNames = [value]; -->
        <input type="checkbox" value="html" v-model="checkedNames">
        <label for="html">html</label>
        <input type="checkbox" value="css" v-model="checkedNames">
        <label for="css">css</label>
        
        <br>
        <span>Checked names: {{ checkedNames }}</span>

        <div>----------------------------------------</div>

        <!-- 下拉菜单 -->
        <div>
            <select v-model="selected">
                <option value="" disabled>请选择</option>
                <option value="a">A</option>
                <option value="b">B</option>
                <option>C</option>
                <!--option如果有value,会选value值,没有的话将会把文本节点传入-->
            </select>
            <p>被选项为:{{ selected }}</p>
        </div>

    </div>
</template>

<script>
    
    export default {
        data() {
            return {
                message: 3,
                checkedNames: [],
                selected: []
            }
        }
    }

</script>

vue中表单控件+下拉列表的绑定,需要在selected上通过v-model去绑定,也要在data中的return去为这个变量赋值,而且html中也要去接收这个变量。 

自定义组件:

  • 组件写到components文件夹下
  • 自定义一个倒计时组件
  • 组件基本要素:props、$emit等
  • 通过import导入自定义组件,在需要导入的页面中导入,而不是在路由中导入。
<template>
    <div>
        <div>自定义组件</div>

        <div>----------------------------------</div>

        <realCountDown col="blue" @end="ending"></realCountDown>
      //在这里可以使用组件名作为元素名,并且还可进行属性的添加
    </div>
</template>

<script>
    import realCountDown from '@/components/countDown.vue'
  //这里需要导入组件
export default { data() { return { } }, components: { //这里需要注册组件 realCountDown // 'realCountDown': hahaha }, methods: { ending() { alert('时间到!'); } } } </script>

以下是组件代码:

<template>
    <p :style="{ 'color': col }">{{ time }}</p>  
</template>

<script>
    
    export default {
        data() {
            return {
                time: 10
            }
        },
        mounted() {
            let vm = this;
            let t = setInterval(() => {
                vm.time--;
                if ( vm.time == 0 ) {
                    clearInterval(t);
                    vm.$emit("end");  //在页面中需要做事情的元素中添加@end="函数名"属性,这里是一个自定义end事件,emit是触发的意思。
                }
            }, 1000);
        },
        props: {  //组件中接收页面传过来的属性之后
            col: {
                type: String,  //设置值的类型为字符串
                default: 'black'  //默认值为黑色
            }
        }
    }

</script>

Vue中的DOM操作:

  • Vue中操作DOM
  • this.$refs
<template>
    <div>

        <div>Vue操作dom</div>
        <div>---------------------------------</div>
        <!--Vue主流不建议使用dom操作,但提供了这种操作,因为难免在开发中需要用到--->

        <div ref="head" id="head"></div>

    </div>
</template>

<script>
    
    export default {
        data() {
            return {

            }
        },
        mounted() {  //只有在该生命周期下才能进行dom操作,在该部分下的dom都为真实dom,其他部分下的dom都是虚拟dom。
        //可在该部分进行原生js,JQ,zepto等库的操作。

            // document.getElementById('head');//js方式。
            
            this.$refs.head.innerHTML = '这是用this.$refs获得的dom';//该方式为vue操作dom的方式。

            // $('#head').html();//JQ方式

        },
    }

</script>

过渡效果:

  • 过渡transition
  • 通过样式方式写过渡
<template>
    <div>
        
        <div>过渡效果</div>
        <div>---------------------------------</div>

        <div>
            <button @click="show = !show">toggle</button><!--点击将!show赋值给show,也就是true和false之间的互换-->

            <!-- vue中的过渡标签,name属性可根据自己的喜好 -->
            <transition name="fade">
                <p v-if="show">hello</p>
            </transition>

            <!-- 1,由显示到隐藏,leave,整个leave有三个状态
            leave,leave-active,leave-to

            2,由隐藏到显示,enter
            enter,enter-active,enter-to -->

        </div>

    </div>
</template>

<script>
    
    export default {
        data() {
            return {
                show: true
            }
        }
    }

</script>

<style>

    .fade-enter-active, .fade-leave-active {
        transition: opacity 1s;
    }
    .fade-enter, .fade-leave-to {
        opacity: 0;
    }
    /* 以下两个部分为默认设置,可以省略 */
    /* .fade-enter-to {
        opacity: 1;
    } */
    /* .fade-leave {
        opacity: 1;
    } */


</style>

路由vue-router:

  • npm install引入vue-router包//新建项目时已经安装好了
  • 页面跳转功能
  • 用法1:<router-link to="/demo1">demo1</router-link>
  • 用法2:to="{ name: 'demo9', params: { { path: '/demo1' } } }"
  • 用法3:this.$router.push( { path: '/demo1' } )
  • 用法4:this.$router.push( { name: 'demo1', params: { userld: 123 } } )
<template>
    <div>
        
        <div>vue-router</div>
        <div>-----------------------------</div>
        <!--关于vue路由  https://router.vuejs.org/zh-cn/-->

        <!-- 第一种写法 -->
        <router-link to="/countDown">倒计时组件</router-link>
        <div>--------------------------------</div>

        <!-- 第二种写法,在跳转的时候带参数传过去 -->
        <router-link :to="{ name: 'v-model', params: { userId: 133 } }">v-model</router-link>
        <!--这里的name是路由中设置的name,也可以写path-->
        <!-- http://localhost:8080/#/v-model/133?plan=private -->
        <div>----------------------------------</div>

        <!-- 第三种写法,在第二种的基础上,可以在跳转后的页面的url后面通过query对象添加后缀 -->
        <router-link v-bind:to="{ name: 'v-model', params: { userId: 666 }, query: { plan: 'private' } }">query</router-link>
        <!-- http://localhost:8080/#/v-model/666?plan=private -->
        <!-- 可以在跳转后的页面中通过this.$route.params等方式获取其所对应的值 -->
        <div>-----------------------------------</div>

        <!-- 第四种写法,通过js进行跳转 -->
        <button @click="toUrl">transition页面</button>

        <!-- 总结:跳转页面可以总分为2种方法:
        1,引入router-link标签,在其添加属性。
        2,通过js方式,通过this.$router.push({})该方法跳转。
        注意:在传入参数的时候,需要在路由中设置path的尾部添加":参数",冒号表示通配符 -->
    </div>
</template>


<script>
    
    export default {
        data() {
            return {

            }
        },
        methods: {
            toUrl() {
                // this.$router.push( { path: '/transition' } );//注意这里的$router有r

                // this.$router.push( { name: 'v-model', params: { userId: 666 } } );
            }
        }
    }

</script>

状态管理vuex:

  • npm install引入vuex包    命令:npm install vuex --save
  • 全局状态管理,所有页面共享数据
  • 设置数据:this.$store.dispatch('increment', 100000); ////这句话调用的是index.js中的actions对象中的函数
  • 获取数据:this.$store.state.num; 

  首先引入vuex包;然后在src文件夹中创建store文件夹,在里面创建index.js文件;

接着在main.js文件中导入store文件夹;之后就可以在页面中通过this.$store进行数据管理。

index.js代码如下:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
    state: {
        count: 0,
        num: 1
    },
    mutations: {
        increment( state, num ) {
            state.count++;
            state.num = num;
        }
    },
    actions: {  //这里的方法调用了mutations对象里的方法
        inc({ commit }, obj) {
            commit('increment', obj)
        }
    }
})
<template>
    <div>
        
        <div>状态管理</div>
        <div>------------------------------</div>
        <!-- vuex官网:https://vuex.vuejs.org/zh -->

        <div>{{ msg }}</div>
        <button @click="change">阿牛</button>

    </div>
</template>


<script>
    
    export default {
        data() {
            return {
                msg: '123'
            }
        },
        methods: {
            change() {
                //vuex取数据
                this.msg = this.$store.state.count;

                //vuex修改数据
                this.$store.dispatch('inc', 100000);

                alert(this.$store.state.num);
                alert(this.$store.state.count);

            }
        }
    }

</script>



vue中的状态管理vuex,可以通过vuex去获取并修改公共数据,使用vuex,需要在src中创建store文件,然后在main.js中去将store文件引入进来。

具体可查阅vuex官网:https://vuex.vuejs.org/zh

slot插槽:

  • 常用于组件的调用

首先在components文件夹中创建slot.vue文件,里面写上模板;接着在页面中导入该文件;在模板内使用该组件名作为标签名来使用slot插槽。在该标签内书写的内容将会被放入插槽组件中的slot标签中。若是组件中没有slot标签,那么页面中写在组件名作为标签名的那个标签内的内容将不会被显示。

//主页面
<
template> <div> <div>slot插槽</div> <div>--------------------------------</div> <slots> <p>13412341234</p> <div slot="bottom">09870987097</div> </slots> </div> </template> <script> import slots from '@/components/slot.vue'; export default { data() { return { } }, components: { slots } } </script>
//组件内部
<
template> <div> <h1>插槽测试</h1> <slot></slot> <p>我是最底部</p> <slot name="bottom"></slot> </div> </template>

vue-resource请求:(类似JQ中的ajax请求)

  • npm install引入vue-resource    命令:npm install vue-resource --save
  • this.$http.get('/someUrl')
  • this.$http.post('/someUrl', { foo: 'bar' })

在main.js中加入以下两句话:

import VueResource from 'vue-resource'

Vue.use(VueResource);

<template>
    <div>
        
        <div>vue-resource请求</div>
        <div>---------------------------------</div>
        <!--vue-resource官网:https://github.com/pagekit/vue-resource -->

    </div>
</template>

<script>
    export default {
        data() {
            return {

            }
        },
        mounted() {  //对接后台数据
            this.$http.get('/someUrl').then(response => {
                console.log(response.body);
            }, response => {
                //error callback
            });

            this.$http.post('/someUrl', { foo: 'bar' }).then(response => {
                console.log(response.body);
            }, response => {
                //error callback
            });

            this.$http.get('/someUrl', { params: { foo: 'bar' }, header: { 'X-Custom': '...' } }).then(response => {
                // console.log(response.body);
                //success callback
            }, response => {
                //error callback
            });
        }
    }

</script>

移动组件库Mint UI:

  • 官网:http://mint-ui.github.io/docs/#/zh-cn
原文地址:https://www.cnblogs.com/zhonghonglin1997/p/10189861.html