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
相关实践学习
Serverless极速搭建Hexo博客
本场景介绍如何使用阿里云函数计算服务命令行工具快速搭建一个Hexo博客。
目录
相关文章
|
1天前
|
JavaScript
Vue基础知识总结 4:vue组件化开发
Vue基础知识总结 4:vue组件化开发
|
1天前
|
存储 JavaScript
Vue 状态管理工具vuex
Vue 状态管理工具vuex
|
7天前
|
缓存 JavaScript UED
Vue 中实现组件的懒加载
【10月更文挑战第23天】组件的懒加载是 Vue 应用中提高性能的重要手段之一。通过合理运用动态导入、路由配置等方式,可以实现组件的按需加载,减少资源浪费,提高应用的响应速度和用户体验。在实际应用中,需要根据具体情况选择合适的懒加载方式,并结合性能优化的其他措施,以打造更高效、更优质的 Vue 应用。
|
6天前
|
JavaScript
如何在 Vue 中使用具名插槽
【10月更文挑战第25天】通过使用具名插槽,你可以更好地组织和定制组件的模板结构,使组件更具灵活性和可复用性。同时,具名插槽也有助于提高代码的可读性和可维护性。
13 2
|
7天前
|
JavaScript
Vue 中的插槽
【10月更文挑战第25天】插槽的使用可以大大提高组件的复用性和灵活性,使你能够根据具体需求在组件中插入不同的内容,同时保持组件的结构和样式的一致性。
11 2
|
7天前
|
前端开发 JavaScript 容器
在 vite+vue 中使用@originjs/vite-plugin-federation 模块联邦
【10月更文挑战第25天】模块联邦是一种强大的技术,它允许将不同的微前端模块组合在一起,形成一个统一的应用。在 vite+vue 项目中,使用@originjs/vite-plugin-federation 模块联邦可以实现高效的模块共享和组合。通过本文的介绍,相信你已经了解了如何在 vite+vue 项目中使用@originjs/vite-plugin-federation 模块联邦,包括安装、配置和使用等方面。在实际开发中,你可以根据自己的需求和项目的特点,灵活地使用模块联邦,提高项目的可维护性和扩展性。
|
7天前
|
缓存 JavaScript UED
Vue 中异步加载模块的方式
【10月更文挑战第23天】这些异步加载模块的方式各有特点和适用场景,可以根据项目的需求和架构选择合适的方法来实现模块的异步加载,以提高应用的性能和用户体验
|
8天前
|
数据采集 监控 JavaScript
在 Vue 项目中使用预渲染技术
【10月更文挑战第23天】在 Vue 项目中使用预渲染技术是提升 SEO 效果的有效途径之一。通过选择合适的预渲染工具,正确配置和运行预渲染操作,结合其他 SEO 策略,可以实现更好的搜索引擎优化效果。同时,需要不断地监控和优化预渲染效果,以适应不断变化的搜索引擎环境和用户需求。
|
11天前
|
JavaScript
Vue 指令速查表
【10月更文挑战第12天】Vue 指令速查表
|
8天前
|
缓存 JavaScript 搜索推荐
Vue SSR(服务端渲染)预渲染的工作原理
【10月更文挑战第23天】Vue SSR 预渲染通过一系列复杂的步骤和机制,实现了在服务器端生成静态 HTML 页面的目标。它为提升 Vue 应用的性能、SEO 效果以及用户体验提供了有力的支持。随着技术的不断发展,Vue SSR 预渲染技术也将不断完善和创新,以适应不断变化的互联网环境和用户需求。
27 9