Vue系列教程(一) - 基础语法v1.0

简介: 目录helloWorld双向绑定css操作样式操作绑定事件绑定事件-修饰符生命周期v-if 显示和隐藏(一)v-show 显示和隐藏(二)v-for 渲染列表(Key)数组更新couputed 关联属性(计算器属性)watc...

目录

  1. helloWorld

  2. 双向绑定

  3. css操作

  4. 样式操作

  5. 绑定事件

  6. 绑定事件-修饰符

  7. 生命周期

  8. v-if 显示和隐藏(一)

  9. v-show 显示和隐藏(二)

  10. v-for 渲染列表(Key)

  11. 数组更新

  12. couputed 关联属性(计算器属性)

  13. watch 监听变化(监听数组和对象需要加deep参数,immediate)

  14. refs 获取元素

  15. 异步更新

  16. helloWorld以及双向绑定(这是一个完整的例子,后面的例子只有body部分)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>hello world</title>
    <script src="https://cdn.bootcss.com/vue/2.4.4/vue.js"></script>
</head>
<body>
    <h3>hello world</h3><hr>
    <div id="app">
        <p>{{ message }}</p>
        <input v-model="username" />
        <p>{{username}}</p>
    </div>
    <script>
        new Vue({
            el: '#app',
            data: {
                message: 'Hello Vue.js!',
                username: '沃土前端'
            }
        })
    </script>
</body>
</html>
  1. css和样式渲染
<style type="text/css">
    div {margin: 5px;}
    .active {border: 1px solid green;}
    .error {color: red;}
</style>
// 方法一: 当isActive为true时,元素添加class ‘active’
<div id="app">
    <div v-bind:class="{ active: isActive }">绑定class样式</div>
<div :class="{ active: isActive }">class样式(缩略写法)</div>
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            isActive: true,
            isError: true
        }
    })
</script>

// 方法二: 以类的方式添加class
<div id="app">
      <div :class="classObj">对象</div>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            classObj: {
                active: true,
                error: true
            }
        }
    })

// 方法三: 使用数组的方式添加class
<div id="app">
    <div :class="[activeClass, errorClass]">数组的方法</div>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            activeClass: 'active',
            errorClass: 'error'
        }
    })
</script>

// 方法四: 使用表达式的方式添加class
<div id="app">
    <div :class="isActive ? 'active' : ''">使用表达式</div>
    <div :class="[isActive ? 'active' : '', isError?'error':'']">同时使用两个表达式</div>
</div>

<script>
    new Vue({
        el: '#app',
        data: {
            isActive: true,
            isError: true
        }
    })
</script>

  1. 事件处理器以及事件修饰符: https://cn.vuejs.org/v2/guide/events.html
<div id="example-3" @click="clickFather()">
    <button v-on:click="say('hi')">Say hi</button><br />
    <button v-on:click="say('what')">Say what</button><br />
    <button v-on:click.stop="doThis">stop(阻止事件冒泡)</button>
</div>
<script type="text/javascript">
    new Vue({
        el: '#example-3',
        methods: {
            say(message) {
                alert(message)
            },
            doThis() {
                alert('stop');
            },
            clickFather() {
                console.log('你点击了父元素');
            }
        }
    })
</script>
  1. 生命周期
<div id="app">
    <p>{{msg}}</p>
</div>

<script type="text/javascript">
    var vm = new Vue({
        el: '#app',
        data: {
            msg: '生命周期'
        },
        // 实例创建完毕,el内的元素还没被替换,可以去发送请求
        created() {
            console.log('create');
        },
        // 挂载完毕,el内的元素被替换,可以操作页面元素
        mounted() {
            console.log('mounted');
        }
    })
</script>
  1. 渲染列表
// (1)渲染列表 为了优化渲染效率,要加上 :key="index"
<div id="app">
    <ul style="list-style: none;">
        <li v-for="(item, index) in items" :key="index">
            <span>{{ index }}</span>
            <span>名字-{{item.name}}</span>
            <span> 产地-{{ item.addr }}</span>
        </li>
    </ul>
</div>

<script type="text/javascript">
    var example2 = new Vue({
        el: '#app',
        data: {
            items: [{
                    name: '苹果',
                    addr: '山东'
                },
                {
                    name: '香蕉',
                    addr: '海南'
                }
            ]
        }
    })
</script>

// (2)更新列表中某条数据
<div id="app">
    <ul style="padding: 0;list-style: none;">
        <li v-for="(item, index) in items" :key="index">
            <span>{{ index }}</span>
            <span>名字-{{item.name}}</span>
            <span> 产地-{{ item.addr }}</span>
        </li>
    </ul>
    <button @click="update()">更新成员1的所有属性</button><br />
    <button @click="update1()">更新成员1的某个属性</button><br />
    <button @click="update2()">更新成员2</button><br />
</div>

<script type="text/javascript">
    new Vue({
        el: '#app',
        data: {
            items: [{
                    name: '苹果',
                    addr: '山东'
                },
                {
                    name: '香蕉',
                    addr: '海南'
                }
            ]
        },
        methods: {
            update() {
                // 更新成员1的所有属性
                this.$set(this.items, 0, {
                    name: '石榴',
                    addr: '山西'
                });
            },
            update1() {
                // 如果只希望只改变数组其中一个成员对象的其中一个属性的值,其他属性不改变,可以这样写
                this.$set(this.items, 0, { ...this.items[0],
                    name: '番茄'
                });
            },
            update2() {
                // 第二种更新数组对象的方式
                this.items.splice(0, 1, {
                    name: '雪梨',
                    addr: '广西'
                });

            }
        }
    })
</script>

  1. 异步更新组件 Vue.nextTick,举个栗子,下面是一个添加轮播图的例子
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <link href="https://cdn.bootcss.com/Swiper/4.0.0-beta.2/css/swiper.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
    <script src="https://cdn.bootcss.com/Swiper/4.0.0-beta.2/js/swiper.min.js"></script>
    <script src="https://cdn.bootcss.com/vue/2.4.4/vue.js"></script>
    <!-- Demo styles -->
    <style> html, body { position: relative; height: 100%; }  body { background: #fff; font-family: Helvetica Neue, Helvetica, Arial, sans-serif; font-size: 14px; color: #000; margin: 0; padding: 0; }  .swiper-container { width: 300px; height: 300px; position: absolute; left: 50%; top: 50%; margin-left: -150px; margin-top: -150px; }  .swiper-slide { background-position: center; background-size: cover; } </style>
</head>
<body>
    <div id="app">
        <div class="swiper-container">
            <div class="swiper-wrapper">
                <div v-for="item in list" class="swiper-slide" :key="item.id"
                    :style=`backgroundImage:url(${item.url})`>
                </div>
            </div>
            <div class="swiper-pagination"></div>
        </div>
    </div>

    <script type="text/javascript">
        new Vue({
            el: '#app',
            data: {
                msg: 'aaa',
                list: []
            },
            mounted() {
                this.add();
            },

            methods: {
                add() {
                    var url = 'http://www.easy-mock.com/mock/59b89b82e0dc663341a7cced/vue/imgList';
                    $.get(url, (res) => {
                        this.list = res.list;
                        // 等图片加载完毕才添加轮播图,不然不生效
                        this.$nextTick(()=> {
                            this.addCarousel();
                        })
                    })
                },
                // 添加轮播图
                addCarousel() {
                    var swiper = new Swiper('.swiper-container', {
                        effect: 'cube',
                        loop: true
                    });
                }
            }
        })
    </script>
</body>
</html>
  1. 计算属性computed
<div id="app">
    <div id="example">
        <p>message: "{{ message }}"</p>
        <p>翻转字符串: "{{ reversedMessage }}"</p>
    </div>
</div>

<script type="text/javascript">
    var vm = new Vue({
        el: '#example',
        data: {
            message: 'Hello'
        },
        computed: {
            // 根据message生成一个新的属性
            reversedMessage: function () {
                return this.message.split('').reverse().join('')
            }
        }
    })
</script>
  1. watch(监听数组或对象需要加deep参数,immediate)
<div id="app">
    <p>消息:{{msg}}</p>
    <p>对象属性值a:{{obj.a}}</p>
    <button @click="updateMsg">修改消息的值</button><br />
    <button @click="updateObj">修改属性a的值</button>
</div>

<script type="text/javascript">
    var vm = new Vue({
        el: '#app',
        data: {
            msg: 'hello',
            obj: {
                a: 2,
                b: 3
            },
            tip:''
        },
        methods: {
            updateMsg() {
                this.msg = 'haha';
            },
            updateObj() {
                this.obj.a = '222';
            }
        }
    })
    // watch msg的值
    vm.$watch('msg', function(newValue, oldValue) {
        console.log('新值:'+newValue,'旧值:'+oldValue);
    })
    // watch对象的属性时需要添加一些参数
    vm.$watch('obj', function (obj) {
        console.log(obj.a);
    }, {
        // 没有这个参数不会触发回调
         deep: true,
        // 有这个参数立即触发回调,不需要obj有改变
        immediate: true
    })
</script>

// 总结:同一个功能computed和watch都能实现,能用computed的时候一般都用computed,更简洁,参考地址: http://www.cnblogs.com/annie211/p/7324631.html
9.1 自定义组件

<div id="app">
<!--使用组件-->
    <Hello></Hello>
    <Second></Second>
</div>

<script type="text/javascript">
    // 声明Hello组件
    var Hello = {
        template: '<p>{{userName}}</p>',
        data() {
            return {
                userName: '我是老胡'
            }
        }
    }
    // 声明Second组件
    var Second = {
        template: '<p>{{msg}}</p>',
        data() {
            return {
                msg: '这是第二个组件'
            }
        }
    }

    new Vue({
        el: '#app',
        data: {
            msg: '2222' 
        },
        // 注册组件
        components: {
            Hello,
            Second
        }
    })
</script>

9.2 父组件向子组件传参props

<div id="app">
    <!-- parentMsg1 需要用连字符 -->
    <Hello parent-msg1="hello" :parent-msg2="msg"></Hello>
    <!--动态绑定参数-->
    <input v-model="msg" />
</div>

<script type="text/javascript">
    // 定义子组件First 要注意的是,template只能有一个根标签
    var Hello = {
        template: `<div><p>静态参数:{{ parentMsg1 }}</p>
        <p>动态参数: {{parentMsg2}}</p></div>`,
        props: ['parentMsg1','parentMsg2'],
        data() {
            return {}
        }
    }

    new Vue({
        el: '#app',
        data: {
            msg: '哈哈哈'
        },
        components: {
            Hello
        }
    })
</script>

9.3 子组件的$emit(子组件向父组件传值)

<div id="app">
    <p>{{ total }}</p>
    <!--传递一个函数给子组件-->
    <Counter @add="count"></Counter>
</div>

<script type="text/javascript">
    // 子组件
    var Counter = {
        template: '<button @click="myClick()">增加</button>',
        data: function () {
            return {
                num: 0
            }
        },
        methods: {
            myClick: function () {
                // 触发父组件的add函数
                this.$emit('add',222)
            }
        },
    }

    // 父组件
    new Vue({
        el: '#app',
        data: {
            total: 0
        },
        components: {
            Counter
        },
        methods: {
            count: function (param) {
                // 可以接收到子组件传回来的参数param
                console.log(param);
                this.total += 1
            }
        }
    })
</script>

10 自定义组件v-model(针对非input标签)
请参考链接: https://segmentfault.com/a/1190000008662112

11 单文件组件,在现在的项目中一般使用单文件组件

// 模板
<template>
    <div class="wrap">
        <h3>单文件组件</h3>
        <p>{{msg}}</p>
    </div>
</template>

// js代码
<script>
export default {
    data() {
        return {
            msg: 'hello world'
        }
    }
}
</script>

// 样式
<style lang="less" scoped>
.wrap {
    border: 1px solid;
    height: 100px;
    h3 {
        color: red;
    }
    p {
        background: gray;
    }
}
</style>
本教程github地址:https://github.com/wotu-courses/vue_basics.git
参加沃土前端社区(深圳)线下技术交流请加微信 huruqing_wt
目录
相关文章
|
1天前
|
JavaScript 前端开发
【vue】iview如何把input输入框和点击输入框之后的边框去掉
【vue】iview如何把input输入框和点击输入框之后的边框去掉
7 0
|
1天前
|
JavaScript
【vue实战】父子组件互相传值
【vue实战】父子组件互相传值
6 1
|
1天前
|
JavaScript
vue2_引入Ant design vue
vue2_引入Ant design vue
6 0
|
1天前
|
JavaScript
vue知识点
vue知识点
10 4
|
2天前
|
存储 JavaScript 前端开发
【Vue】绝了!这生命周期流程真...
【Vue】绝了!这生命周期流程真...
|
2天前
|
JavaScript 索引
【vue】框架搭建
【vue】框架搭建
7 1
|
2天前
|
JavaScript 前端开发 容器
< 每日小技巧: 基于Vue状态的过渡动画 - Transition 和 TransitionGroup>
Vue 的 `Transition` 和 `TransitionGroup` 是用于状态变化过渡和动画的组件。`Transition` 适用于单一元素或组件的进入和离开动画,而 `TransitionGroup` 用于 v-for 列表元素的增删改动画,支持 CSS 过渡和 JS 钩子。
< 每日小技巧: 基于Vue状态的过渡动画 - Transition 和 TransitionGroup>
|
2天前
|
JavaScript
【vue】setInterval的嵌套实例
【vue】setInterval的嵌套实例
8 1
|
2天前
|
JavaScript 前端开发 安全
【Vue】内置指令真的很常用!
【Vue】内置指令真的很常用!
|
2天前
|
JavaScript
【Vue】过滤器Filters
【Vue】过滤器Filters