初识vue框架(一)

什么是Vue?

Vue是一种渐进式JavaScript 框架。易用,灵活,高效

易用:只要会HTML, css, Javascript就可以使用
灵活:Vue 的核心库只关注视图层,可以配合市场已流行的其他脚本库及平台使用
流行的脚本库及平台:如Jquary,axios,loadash,node.js,express,koa等
高效:40kB min+gzip 运行大小,超快虚拟DOM,省心优化

Vue作者?尤雨溪

Vue中文官网 http://cn.vuejs.org

命令行工具有两种版本,学习最新的CLI3.0
npm install -g @vue/cli

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 生产环境版本,优化了尺寸和速度 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>

高内聚,低耦合。
组件封装追求的低耦合

作业:
使用vue的v-if v-for等制作一个类似QQ的手风琴效果
效果:
在这里插入图片描述
源码:
https://blog.csdn.net/fengtingYan/article/details/82934542


下面的所有的源码都要导入(本地文件)

<script src="vue.min.js"></script>

声明式渲染

需要视图模板和数据,先声明数据,然后把数据和视图模板绑定在一起,让视图使用声明的数据进行视图渲染的过程

	<!-- 视图模板 -->
    <div id="app">
        {{message}}
    </div>

    <script>
        // 数据必须使用Vue传,使用原生js定义不行
        var message = "hello"

        // 必须用Vue框架来准备数据
        // 创建Vue对象的一个实例来对应一个视图,让他控制视图
        // vue构造函数中通过配置项来控制视图
        var app = new Vue({
            el:"#app", //el=>element,用来设置Vue实例控制的视图,它是Vue实例和视图练习的纽带
            data:{//向视图准备数据
                message:"Hello Vue!"
            }
        });

        /* 响应式
        app.$date.message 
        当你更改了Vue实例中的数据,Vue视图会立即更新视图,(立即响应数据变化)就叫做响应式
         */
        app.message = "你好"
    </script>

效果:
在这里插入图片描述

初识指令

<div id="app">
        <!-- Vue实例中的数据可以在元素内容区使用“{{}}” 语法来使用(插值语法),但在元素属性中使用{{}}不能被Vue解析
        想让Vue控制元素的属性,必须使用Vue指令
        v-bind:用来给属性绑定数据
        可以直接绑定一个常量字符串,注意引号,不加引号时,Vue会当做变量解析-->
        <h1 v-bind:title='message'>{{message}}</h1>
        <h1 v-bind:title="'hello'">{{message}}</h1>
        <!--v-if指令控制元素的显示/隐藏 ,值是一个布尔表达式
        v-if指令会控制dom的创建和销毁,不用担心性能问题,Vue使用缓存技术对这些操作做了特殊处理-->
        <div v-if="false">我是div</div>
        <div v-if="1==1">我是div</div>
        <div v-if="show">我是div</div>
        <!-- v-show也可以控制元素的显示/隐藏,但他不会创建和销毁dom,会通过简单的css样式(display=none)控制 -->
        <h2 v-show="show">我是h2</h2>
        <ul>
            <!-- v-for循环遍历数组 -->
            <li v-for="f in foods">{{f}}</li>
        </ul>
    </div>
    <script>
        var app = new Vue({
            el:"#app",
            data:{
                message:"让数据在元素中使用",
                show:true,
                foods:["肉","肉2","肉3"]
            }
        })
    </script>

效果:
在这里插入图片描述

v-for练习

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>初步认识Vue指令</title>
    <script src="vue.min.js"></script>
    <style>
        table{
            border-collapse: collapse;
            width: 600px;
        }
        th,td{
            border: grey groove 2px;
        }
    </style>
</head>

<body>
    <div id="app">
        <table>
            <tr>
                <th>索引</th>
                <th>价格</th>
                <th>姓名</th>
                <th>性别</th>
                <th>年龄</th>
                <th>生日</th>
            </tr>
            <!-- i表示数据的索引,key属性是Vue专门为v-for提供的属性,key属性对应的值唯一值v-bind:key="s.id" v-bind可以绑定所有属性(符合HTML5 规范是属性,Vue添加的属性,自定义属性data-dsh)-->
            <tr v-for="(s,i) in students" v-bind:key="i" v-bind:data-dsh="s.id">
                <td>{{i}}</td>
                <td>{{s.id | currency}}</td>
                <td>{{s.name | upperCase}}</td>
                <!-- <td v-if="s.sex">男</td>
                <td v-else-if="s.sex='zbc'">不男不女</td>                
                <td v-else>女</td>                 -->
                <td >{{s.sex?'男':'女'}}</td>      
                <td v-if="s.age==20">年轻</td>    
                <td v-else-if="s.age==50">中年</td>                
                <td v-else-if="s.age==80">老年</td>      
                <td v-else>未知</td>                   
                   <!-- 在Vue中想对数据进行格式化操作,不仅可以使用v-if判断,
                还可以使用过滤器,Vue1.x中有很多自带的过滤器,但vue.2把自带的过滤器全部移除了 -->
                <td>{{s.birthday | dateFormat}}</td>
            </tr>
        </table>
    </div>
    <script>
        var app = new Vue({
            el:"#app",
            data:{
                students:[
                    {id:1,name:"zhangsan",sex:true,age:20,birthday:new Date()},
                    {id:2,name:"ls",sex:false,age:50,birthday:new Date()},
                    {id:3,name:"ww",sex:true,age:80,birthday:new Date()}
                ]
            },
            filters:{//过滤器
                upperCase: function(value){
                    if(typeof value=="string"){
                        return value.toUpperCase();//大写
                    }
                },
                lowerCase: function(value){
                    if(typeof value=="string"){
                        return value.toLowerCase();
                    }
                },
                currency: function(value){
                    if(typeof value=="number"){
                        return '¥' + value.toFixed(2);
                    }
                },
                dateFormat: function(date){
                    var date = new Date(date);
                    var y = date.getFullYear();
                    var M = date.getMonth() + 1;
                    var d = date.getDate();
                    var h = date.getHours();
                    var m = date.getMinutes();
                    var s = date.getSeconds();                    
                    return `${y}-${m}-${d} ${h}:${m}:${s}`                    
                    
                }
            }
        })
    </script>
</body>
</html>

效果:
在这里插入图片描述

双向数据绑定(v-model)

<div id="app">
        <!-- v-bind指令是把数据绑定到视图,是单向的
             而v-model不仅把数据绑定到视图,当视图上的数据发生变化时,会影响Vue实例数据,是双向的

             v-model是“语法糖”,两个指令的封装,v-bind v-on
         -->
        <input type="text" v-model="message">{{message}}
    </div>
    <script>
        var app = new Vue({
            el:"#app",
            data:{
                message:"hello vue!"
            }
        })
    </script>

效果:
在这里插入图片描述

操作数据

<div id="app">{{message}}
        <!-- 当访问的方法不带参数时,小括号可以不加 -->
        <button v-on:click="changeMessage">更改message</button>
        <button v-on:click="changeMessage2('你好')">更改message(带参数)</button>
        <button v-on:click="fun">事件句柄</button>
    </div>
    <script>
        var app = new Vue({
            el:"#app",
            data:{
                message:"hello vue"
            },
            methods:{
                changeMessage:function(){
                    this.message = "abc";
                },
                changeMessage2:function(content){
                    this.message = content;
                },
                // ev就相当于给event起一个别名,不加形参ev时在方法中直接通过event访问
                fun:function(ev){
                    //event是事件句柄,Vue自带的
                    console.log(ev);
                    console.log(event);   
                    //ev.target获取当前点击的宿主                 
                    console.log(ev.target.innerText);

                }
            }
        })
    </script>

效果:
在这里插入图片描述

初识组件

<div id="app">
        <!-- 使用组件像使用标签一样 -->
        <dsh></dsh>
        <abc></abc>
    </div>
    <div id="app1">
            <dsh></dsh>
            <!-- abc不能在app1中使用,因为没有在app1实例中定义,全局组件也没有abc -->
            <abc></abc>
        </div>
    <script>
        // 在Vue中组件和过滤器一样,有两种创建方式:局部组件和全局组件

        // 创建全局组件,参数1:组件名称,不要和HTML已存在的标签名称同名。
        // 参数2:组件的配置项全局组件可以在所有的vue实例使用
        Vue.component('dsh',{
            template:"<h1>自定义的h1标签</h1>"
        })
        // 当全局和局部拥有同名组件时候,视图会优先使用局部组件
        Vue.component('abc',{
            template:"<p>我是全局组件abc</p>"
        })
        var app = new Vue({
            el:"#app",
            // 局部组件
            components:{
                abc:{
                    template:"<session>我是自定义的session标签</session>"
                }
            }
        })
        var app1 = new Vue({
            el:"#app1"
            
        })
    </script>

效果:
在这里插入图片描述

<div id="app">
         <!-- 使用组件像使用标签一样。 -->
        <dsh></dsh>
        <abc></abc>
        <zs></zs>
    </div>
    <!-- <script id="tpl-zs" type="text/html"> -->
    <script id="tpl-zs" type="x/template">
        <div>
            我是组件的视图模板 有且只有一个根元素
            
        </div>
    </script>
        
    <script>
        
        Vue.component('dsh',{
            // 使用``这种ES6的模板字符串语法,可以很容易控制template。
            // 组件中的模板有且只有一个根元素
            template:`
            <h1>
                自定义的h1标签
                <span style="color:red;">我是span</span>
            </h1>`
        })
        Vue.component('zs',{
            // 引用<script id="tpl-zs" type="text/html">
            template: '#tpl-zs'
        })
        var app = new Vue({
            el:"#app",
            
        })
        
    </script>

效果:
在这里插入图片描述

    <div id="app">
        <!-- :是v-bind: 指令的缩写形式。-->
        <dsh v-bind:abc="message" :persons="arr1"></dsh> 
    </div>

    <script>
        
        Vue.component('dsh',{
            // 组件中的模板有且只有一个根元素
            // 组件动态化,向组件传值
            // 数据从哪里来?谁使用组件,数据就从哪里来
            template:`
            <div>{{abc}}
                <ul>
                    <li v-for="p in persons">{{p}}</li>
                    <li v-for="persons">{{persons}}</li>
                    
                </ul>
            </div>            
            `,
            // props=>propertles
            props:['abc','persons']
        })
        
        var app = new Vue({
            el:"#app",
            data:{
                message:"hello",
                arr1:['zs','ls','ww']
            }
        })
        // message的内容是hello 他的属性abc,找到props:['abc'] template的abc
    </script>

组件props传值
在这里插入图片描述

效果:
在这里插入图片描述

组件实例

<div id="app">
        <ol>
            <!--
              现在我们为每个 todo-item 提供 todo 对象
              todo 对象是变量,即其内容可以是动态的。
              我们也需要为每个组件提供一个“key”,稍后再
              作详细解释。
            -->
            
            <!-- <todo-item v-for="item in groceryList" v-bind:todo="item" v-bind:key="item.id">
            </todo-item> -->

            <!-- ol中放一个自定义组件todo-item,不符合HTML5规范 -->
            <!-- 注意is的用法 -->
            <li 
                v-for="item in groceryList" v-bind:todo="item" 
                v-bind:key="item.id" 
                is="todo-item">
            </li>
        </ol>
    </div>
    <script>
        Vue.component('todo-item', {
            // todo-item 组件现在接受一个
            // "prop",类似于一个自定义特性。
            // 这个 prop 名为 todo。
            props: ['todo'],
            template: '<li>{{ todo.text }}</li>'
        })
        var app = new Vue({
            el:"#app",
            data:{
                groceryList: [
                    { id: 0, text: '蔬菜' },
                    { id: 1, text: '奶酪' },
                    { id: 2, text: '随便其它什么人吃的东西' }
                ]
            }
        })
    </script>

效果:
在这里插入图片描述

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>组件实例</title>
    <script src="vue.min.js"></script>
    <style>
        html,body,#app,aside,.content{
            height: 100%;
        }
        body{
            margin: 0;
        }
        nav{
            height: 80px;
            background-color: #ccc;
        }
        
        .containner{
            background-color:hotpink;
            height: calc(100% - 80px);
        }
        aside{
            background-color:greenyellow;
            width: 200px;
            float: left;
        }
        .content{
            background-color: rebeccapurple;
            width: calc(100% - 200px);
            float: right;
        }
        .clearfix::after{
            clear:both;
            visibility: hidden;
            content:'';
            display: inline-block;
            height: 0;
        }
    </style>

</head>
<body>
    <div id="app">
        <app-nav></app-nav>
        <app-view class="clearfix">
                <app-sidebar></app-sidebar>
                <app-content></app-content>
        </app-view>
    </div>
    <script>
        // 推荐中线命名法
        Vue.component('app-nav', {
            template:"<nav>我是导航</nav>"
        })
        // 组件如果使用了小驼峰命名法,在浏览器端使用时需要用中线分割
        Vue.component('appView', {
            // slot插槽 留一个空间
            template:`
        <div class="containner">
            <slot></slot>
        </div>           
            `
        })
        Vue.component('app-sidebar', {
            template:"<aside>我是侧边栏</aside>"
        })
        Vue.component('app-content', {
            template:`
        <div class="content">我是内容区</div>
            `
        })
        var app = new Vue({
            el:"#app"
            
        })
    </script>
</body>
</html>

效果:
在这里插入图片描述

总结练习

<div id="app">
    <!-- 1 文本插值绑定元素特性 -->
        {{message}}
        <span v-bind:title="message">鼠标悬停几秒钟查看此处动态绑定的提示信息!</span>
    <!-- 2 循环输出 -->
        <ol>
            <li v-for="todo in todos">
                {{ todo.text }}
            </li>
        </ol>
    <!--3 v-on 指令添加一个事件监听器  -->
        {{message}}
        <!-- 需求:点击让message倒着写 -->
        <button v-on:click="reverseMessage">逆转消息</button>
    <!--4 v-model 指令实现表单输入和应用状态之间的双向绑定。  -->
        <!-- 需求:输入框显示message -->
        <input type="text" v-model="message">
    <!-- 5 注册组件 -->

    <!-- 6 v-once 指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新 -->
    <span v-once>这个将不会改变: {{ msg }}</span>
    <!-- 7 v-bind 指令可以用于响应式地更新 HTML 特性: -->
        <!-- 完整语法 -->
        <a v-bind:href="">...</a>
        <!-- 缩写 -->
        <a :href="">...</a>
    <!-- 8 v-on 指令,它用于监听 DOM 事件: -->
        <!-- 完整语法 -->
        <a v-on:click="doSomething">...</a>
        <!-- 缩写 -->
        <a @click="doSomething">...</a>
    <!--9  -->
    <div class="static"
        v-bind:class="{ active: isActive, 'text-danger': hasError }">
    </div>
    </div>
    <script>
        Vue.component('todo-item',{
            prop:['todo'],
            template:'<li>{{todo.text}}</li>'
        })
        var app = new Vue({
            el: "#app",
            data: {
                message: 'Hello Vue!',
                todos: [
                    { text: '学习 JavaScript' },
                    { text: '学习 Vue' },
                    { text: '整个牛项目' }
                ],
                msg:1
            },
            methods:{
                reverseMessage(){
                    this.message = this.message.split('').reverse().join('')
                }
            }
        })
    </script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值