Vue从入门到实践应用

Vue基本的语法

Vue的基本代码结构及插值表达式(Mustache)

<body>
    <!-- Vue 实例所控制的元素区域 -->
    <div id="app">
        {{ message }}
    </div>
    <script>
        //创建一个Vue的实例
        var vm = new Vue({
            el: '#app',// 表示当前new的这个Vue实例要控制页面上的哪个区域
            data: {
                message: 'Hello Vue!'
            }
        })
    </script>
</body>

Vue指令之v-textv-html

<body>
    <div id="app">
        <div>{{ msg }} - I'm coming</div>
        <div v-text='htmlText'>I'm coming</div>
        <div v-html="htmlText"></div>
    </div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                msg: 'Hello Vue',
                htmlText: '<h1>我是一个大标题</h1>'
            }
        })
    </script>
</body>

Vue指令之v-bind的三种用法

  1. 直接使用指令 v-bind

  2. 使用简化指令 :

  3. 在绑定的时候,拼接绑定内容::title="btnTitle + ', 这是追加的内容'"

<body>
    <div id="app">
        <div>{{ msg }} - I'm coming</div>
        <div v-text='htmlText'>I'm coming</div>
        <div v-html="htmlText"></div>
        <div v-html="htmlText" v-bind:title="msg"></div>
        <div v-html="htmlText" :title="msg"></div>
        <div v-html="htmlText" :title="msg+' I am coming'"></div>
    </div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                msg: 'Hello Vue',
                htmlText: '<h1>我是一个大标题</h1>'
            }
        })
    </script>
</body>

Vue指令之v-on跑马灯效果

<body>
    <div id="app">
        <h3>{{info}}</h3>
        <input type="button" value="开启" v-on:click="start">
        <input type="button" value="停止" @click="stop">
    </div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                info: '猥琐发育,别浪~!',
                intervalId: null
            },
            methods: {
                start() {
                    if (this.intervalId != null) { // 如果当前有定时器在运行,则直接return
                        return;
                    }
                    this.intervalId = setInterval(() => { // 开始定时器
                        this.info = this.info.substring(1) + this.info.substring(0, 1);
                    }, 200);
                },
                stop() {
                    clearInterval(this.intervalId);
                }
            }
        });
    </script>
</body>

Vue指令之事件修饰符

  • .stop 阻止冒泡

  • .prevent 阻止默认事件

  • .capture 添加事件侦听器时使用事件捕获模式

  • .self 只当事件在该元素本身(比如不是子元素)触发时触发回调

  • .once 事件只触发一次

<body>
    <style type="text/css">
        .inner {height: 150px;background-color: darkcyan;}
        .outer {padding: 40px;background-color: blue;}
    </style>
    <div id="app">
        <h4>正常事件</h4>
        <div class="inner" @click="div1Handler">
            <input type="button" value="戳他" @click="btnHandler">
        </div>
        <h4> 使用 .prevent 阻止默认行为</h4>
        <a href="http://www.baidu.com" @click.prevent="linkClick">有问题,先去百度</a>
        <h4> 使用 .capture 实现捕获触发事件的机制</h4>
        <div class="inner" @click.capture="div1Handler">
            <input type="button" value="戳他" @click="btnHandler">
        </div>
        <h4> 使用 .once 只触发一次事件处理函数 </h4>
        <a href="http://www.baidu.com" @click.prevent.once="linkClick">有问题,先去百度</a>
        <h4> 使用 .stop 阻止冒泡 </h4>
        <div class="outer" @click="div2Handler">
            <div class="inner" @click="div1Handler">
                <input type="button" value="戳他" @click.stop="btnHandler">
            </div>
        </div>
        <h4> 使用 .self 只会阻止自己身上冒泡行为的触发,并不会真正阻止冒泡的行为 </h4>
        <div class="outer" @click="div2Handler">
            <div class="inner" @click.self="div1Handler">
                <input type="button" value="戳他" @click="btnHandler">
            </div>
        </div>
    </div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {},
            methods: {
                div1Handler() {
                    console.log('这是触发了 inner div 的点击事件')
                },
                btnHandler() {
                    console.log('这是触发了 btn 按钮 的点击事件')
                },
                linkClick() {
                    console.log('触发了连接的点击事件')
                },
                div2Handler() {
                    console.log('这是触发了 outer div 的点击事件')
                }
            }
        });
    </script>
</body>

Vue指令之v-model双向数据绑定

<body>
    <div id="app">
        <h4 v-text="msg"></h4>
        <input type="text" v-model="msg">
    </div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                msg:"我是初始值"
            },
        });
    </script>
</body>

Vue指令之v-forkey属性

  1. 迭代数组
<ul>
  <li v-for="(item, i) in list">
  索引:{{i}} - 姓名:{{item.name}} - 年龄:{{item.age}}
  </li>
</ul>
  1. 迭代对象中的属性
<div v-for="(val, key, i) in user">{{val}}-{{key}}-{{i}}</div>
  1. 迭代数字
<p v-for="i in 10">这是第 {{i}} 个P标签</p>
  1. key与列表筛选

为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。

<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>
        <!-- search(name)  :key="item.id"-->
        <p v-for="item in list" >
            <input type="checkbox">{{item.id}} --- {{item.name}}
        </p>
    </div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                id: '',
                name: '',
                list: [
                    { id: 1, name: '盖伦' },
                    { id: 2, name: '寒冰' },
                    { id: 3, name: '瑞兹' },
                ]
            },
            methods: {
                add() { // 添加方法
                    this.list.unshift({ id: this.id, name: this.name })
                    this.id=this.name='';
                },
                search(name) {
                    return this.list.filter(x => {
                        return x.name.indexOf(name) != -1;
                    });
                }
            }
        });
    </script>
</body>

Vue指令之v-ifv-show

  • v-if:每次都会重新删除或创建元素 有较高的切换性能消耗
  • v-show: 每次不会重新进行DOM的删除和创建操作,只是切换了元素的 display:none 样式 有较高的初始渲染消耗
<body>
  <div id="app">
    <input type="button" value="toggle" @click="flag=!flag">
    <h3 v-if="flag">这是用v-if控制的元素</h3>
    <h3 v-show="flag">这是用v-show控制的元素</h3>
  </div>
  <script>
    // 创建 Vue 实例,得到 ViewModel
    var vm = new Vue({
      el: '#app',
      data: {
        flag: false
      },
    });
  </script>
</body>

一般来说,v-if 有更高的切换消耗而 v-show 有更高的初始渲染消耗。因此,如果需要频繁切换 v-show 较好,如果在运行时条件不大可能改变 v-if 较好。

使用内联样式

直接在元素上通过 :style 的形式,书写样式对象

<h1 :style="{color: 'red','font-size':'40px'}">这是一个H1</h1>

将样式对象,定义到 data 中,并直接引用到 :style

  • 在data上定义样式:
data: {
  h1StyleObj: { color: 'red', 'font-size': '40px' }
}
  • 在元素中,通过属性绑定的形式,将样式对象应用到元素中:
<h1 :style="h1StyleObj">这是一个H1</h1>

:style 中通过数组,引用多个 data 上的样式对象

  • 在data上定义样式:
data: {
  h1StyleObj: { color: 'red', 'font-size': '40px'},
  h1StyleObj2: { fontStyle: 'italic' }
}
  • 在元素中,通过属性绑定的形式,将样式对象应用到元素中:
<h1 :style="[h1StyleObj, h1StyleObj2]">这是一个H1</h1>

Vue自定义过滤器

Vue.js 允许你自定义过滤器,可被用作一些常见的文本格式化。过滤器可以用在两个地方:mustache 插值和 v-bind 表达式。过滤器应该被添加在 JavaScript 表达式的尾部,由“管道”符指示;

  1. 私有过滤器
<body>
    <div id="app">
        <select v-model="message">
            <option value="1">开心</option>
            <option value="2">失落</option>
            <option value="3">狂躁</option>
        </select>
        <p>选中值: {{message}}</p>
        <p :title="message | tran('我很')">翻译后: {{ message | tran('我很')}}</p>
    </div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                message: ''
            },
            filters: {
                tran(str, mood = "") {
                    switch (str) {
                        case "1": mood = mood + '开心';
                            break;
                        case "2": mood = mood + '失落';
                            break;
                        case "3": mood = mood + '狂躁';
                            break;
                        default: mood = "";
                    }
                    return mood;
                }
            }
        })
    </script>
</body>
  1. 全局过滤器
Vue.filter('tran', function (str, mood = "") {...})

注意:当有局部和全局两个名称相同的过滤器时候,会以就近原则进行调用,即:局部过滤器优先于全局过滤器被调用!

Vue自定义指令

详见官网api

Vue过渡动画

详见官网api

Vue生命周期函数

生命周期图示

new Vue({
  data: {
    a: 1
  },
  created: function () {
    // `this` 指向 vm 实例
    console.log('a is: ' + this.a)
  },
  ...
})

Vue组件

定义Vue组件

什么是组件: 组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功能模块,将来我们需要什么样的功能,就可以去调用对应的组件即可;
组件化和模块化的不同:

  • 模块化: 是从代码逻辑的角度进行划分的;方便代码分层开发,保证每个功能模块的职能单一;
  • 组件化: 是从UI界面的角度进行划分的;前端的组件化,方便UI组件的重用;

Vue组件的定义

全局定义的三种方式

  1. 使用 Vue.extend 配合 Vue.component 方法:
var login = Vue.extend({
  template: '<h1>登录</h1>'
});
Vue.component('login', login);
  1. 直接使用 Vue.component 方法:
Vue.component('register', {
  template: '<h1>注册</h1>'
});
  1. 将模板字符串,定义到script标签种:
<script id="tmpl" type="x-template">
  <div><a href="#">登录</a> | <a href="#">注册</a></div>
</script>
//同时,需要使用 Vue.component 来定义组件
Vue.component('account', {
  template: '#tmpl'
});

注意: 组件中的DOM结构,有且只能有唯一的根元素(Root Element)来进行包裹!

使用components属性定义局部子组件

<body>
    <div id="app">
        <!-- 组件的引用 -->
        <account></account>
    </div>
    <script>
        // 创建 Vue 实例,得到 ViewModel
        var vm = new Vue({
            el: '#app',
            data: {},
            methods: {},
            components: { // 定义当前实例的子组件
                account: { // account 组件
                    template: '<div><h1> 这是Account组件{{ name }}</h1 ><login></login></div > ',
                    components: { // 定义account 组件的子组件
                        login: {
                            template: "<h3>这是登录组件</h3>"
                        },
                        regist: {
                            template: "<h3>这是注册组件</h3>"
                        }
                    }
                }
            }
        });
    </script>
</body>

组件中展示数据和响应事件

  1. 在组件中,data需要被定义为一个方法并返回一个对象,例如:
Vue.component('account', {
    template: '#tmpl',
    data() {
        return {
            msg: '大家好!'
        }
    },
    methods: {
        login() {
            alert('点击了登录按钮');
        }
    }
});
  1. 在子组件中,如果将模板字符串,定义到了script标签中,那么,要访问子组件身上的data属性中的值,需要使用this来访问;

组件切换 使用component标签,来引用组件,并通过:is属性来指定要加载的组件

<body>
    <style>
        .v-enter,.v-leave-to {opacity: 0;transform: translateX(30px);}
        .v-enter-active,.v-leave-active { position: absolute;transition: all 0.3s ease;}
    </style>
    <div id="app">
        <a href="#" @click.prevent="comName='login'">登录</a>
        <a href="#" @click.prevent="comName='regist'">注册</a>
        <transition mode="out-in">
            <component :is="comName"></component>
        </transition>
    </div>
    <script>
        // 创建 Vue 实例,得到 ViewModel
        var vm = new Vue({
            el: '#app',
            data: {
                comName:'login'
            },
            methods: {},
            components: { // 定义当前实例的子组件
                login: {
                    template: "<h3>这是登录组件</h3>"
                },
                regist: {
                    template: "<h3>这是注册组件</h3>"
                }
            }
        });
    </script>
</body>

Vue组件间的传值

父组件向子组件传值

注意:一定要使用props属性来定义父组件传递过来的数据

<body>
    <div id="app">
        <son :finfo="msg"></son>
    </div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                msg: '这是父组件中的消息'
            },
            components: {
                son: {
                    template: '<h1>这是子组件 - {{finfo}}</h1>',
                    props: ['finfo']
                }
            }
        });
    </script>
</body>

子组件向父组件传值

  1. 原理:父组件将方法的引用,传递到子组件内部,子组件在内部调用父组件传递过来的方法,同时把要发送给父组件的数据,在调用方法的时候当作参数传递进去;

  2. 父组件将方法的引用传递给子组件,其中,getMsg是父组件中methods中定义的方法名称,func是子组件调用传递过来方法时候的方法名称

  3. 子组件内部通过this.$emit('方法名', 要传递的数据)方式,来调用父组件中的方法,同时把数据传递给父组件使用实例如下:

<body>
    <div id="app">
        <p v-text="msg"></p>
        <son @func="getMsg" :finfo="msg"></son>
    </div>
    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                msg: '这是父组件中的消息'
            },
            methods: {
                getMsg(val){
                    this.msg = val;
                }
            },  
            components: {
                son: {
                    template: `
                    <div>
                        <input type="text" v-model="finfo" />
                        <input type="button" value="向父组件传值" @click="sendMsg" />
                    </div>
                    `,
                    methods: {
                        sendMsg(){
                            this.$emit('func', this.finfo);
                        }
                    },
                    props: ['finfo']
                }
            }
        });
    </script>
</body>

Vue-Router的使用

什么是路由

  1. 对于普通的网站,所有的超链接都是URL地址,所有的URL地址都对应服务器上对应的资源;

  2. 对于单页面应用程序来说,主要通过URL中的hash(#号)来实现不同页面之间的切换,同时,hash有一个特点:HTTP请求中不会包含hash相关的内容;所以,单页面程序中的页面跳转主要用hash实现;

  3. 在单页面应用程序中,这种通过hash改变来切换页面的方式,称作前端路由(区别于后端路由);

vue-router的基本使用

  1. 导入 vue-router 组件类库:
<script src="./lib/vue-router-3.0.1.js"></script>
  1. 使用 router-link 组件来导航
<router-link to="/login">登录</router-link>
<router-link to="/regist">注册</router-link>
  1. 使用 router-view 组件来显示匹配到的组件
<router-view></router-view>
  1. 创建使用Vue.extend创建组件
var login = Vue.extend({
    template: '<h1>登录组件</h1>'
});
var regist = Vue.extend({
    template: '<h1>注册组件</h1>'
});
  1. 创建一个路由 router 实例,通过 routers 属性来定义路由匹配规则
var router = new VueRouter({
    routes: [
    { path: '/', redirect: '/login' },
    { path: '/login', component: login },
    { path: '/regist', component: register }
    ]
});
  1. 使用 router 属性来使用路由规则
var vm = new Vue({
    el: '#app',
    router: router // 使用 router 属性来使用路由规则
});
  1. 完整示例
<body>
    <div id="app">
        <router-link to="/login">登录</router-link>
        <router-link to="/regist">注册</router-link>
        <router-view></router-view>
    </div>
    <script>
        var login = Vue.extend({
            template: '<h1>登录组件</h1>'
        });
        var regist = Vue.extend({
            template: '<h1>注册组件</h1>'
        });
        var router = new VueRouter({
            routes: [
                
                { path: '/login', component: login },
                { path: '/regist', component: regist }
            ]
        });
        var vm = new Vue({
            el: '#app',
            router: router
        });
    </script>
</body>

使用redirect实现重定向

{ path: '/', redirect: '/login' }

在路由规则中定义参数

定义参数:参数名

{ path: '/register/:id', component: register }

获取参数this.$route.params

var regist = Vue.extend({
    template: '<h1>注册组件 --- {{this.$route.params.id}}</h1>'
});

使用 children 属性实现路由嵌套

 var router = new VueRouter({
    routes: [
        { path: '/', redirect: '/account/login' }, 
        {
            path: '/account',
            component: account,
            // 通过 children 数组属性,来实现路由的嵌套
            children: [ 
                // 注意,子路由的开头位置,不要加 / 路径符
                { path: 'login', component: login }, 
                { path: 'regist', component: regist}
            ]
        }
    ]
});

用Vue-cli3初始化一个Vue项目

安装

npm install -g @vue/cli
# OR
yarn global add @vue/cli

安装之后,你就可以在命令行中访问 vue 命令。你可以通过简单运行 vue,看看是否展示出了一份所有可用命令的帮助信息,来验证它是否安装成功。

创建一个项目

  1. 运行以下命令来创建一个新项目:
vue create hello-world

你会被提示选取一个 preset。你可以选默认的包含了基本的 Babel + ESLint 设置的 preset,也可以选“手动选择特性”来选取需要的特性。

  1. 通过 vue ui 命令以图形化界面创建和管理项目
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UTd8PTGp-1575449673653)(https://cli.vuejs.org/ui-new-project.png)]

使用命令启动或打包

在一个 Vue CLI 项目中,@vue/cli-service 安装了一个名为 vue-cli-service 的命令。你可以在 npm scripts 中以 vue-cli-service、或者从终端中以 ./node_modules/.bin/vue-cli-service 访问这个命令。

这是使用默认 preset 的项目的 package.json:

{
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build"
  }
}

通过 npm 或 Yarn 调用这些 script:

//启动项目
npm run serve
# OR
yarn serve
//打包项目
npm run build
# OR
yarn build

build会在 dist/ 目录产生一个可用于生产环境的包,带有JS/CSS/HTML的压缩

Ant Design of Vue 组件库的基本使用

整理中…

Ant Design Pro of Vue 的基本使用

整理中…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值