Vue - 基本指令

Vue

渐进式 JavaScript 框架

js是页面脚本语言,用来控制或是辅助页面搭建,js功能的集合体
vue可以更好更强大的去管理页面

1)vue可以控制一个页面中的一个标签
2)vue可以控制一个页面
3)vue可以控制整个项目

js要控制页面 - 需要在页面中script引入js => vue项目就只有一个页面 => 组件化开发

优点

1、三大前台框架:Angular(脸书)  React(Github)  Vue(优点:综合前两个框架的优点[轻量级]、一手文档是中文[上手快]、vue完全开源[免费])
2、单页面web应用 - 服务于移动端 - 客户端只需要问后台索要数据
3、MVVM设计模式
4、数据驱动 - 区别于DOM驱动(DOM加载后才能操作)- 在缓存中处理dom,在渲染给真实dom
5、虚拟dom - 页面的缓存机制
6、数据的双向绑定 - 页面中变量相同,数据就相同,实时变检测

Vue导入与挂载点

在官网下载vue.js文件,类似于js的导入。Vue就相当于一个类

<script src="js/vue.js"></script>
<h1>
    {{ }}
</h1>
<script>
    new Vue({
        // 挂载点:vue实例(对象)通过挂载点与页面建立关联
        // 挂载点只遍历第一个匹配的结果
        // html和body标签不可以作为挂载点
        // 挂载点的值一般只选择id选择性,具有唯一性
        el:'h1' 
    })
</script>

Vue插值表达式

<script src="js/vue.js"></script>
<div id='app'>
    <!--插值表达式:用来渲染值-->
    <h1>{{ msg.split('')[0] }}</h1>
    <h2>{{ info+msg }}</h2>
    <h3>
        {{ num|my_filter }}
    </h3>
    <h3>
        {{ a,b|my_filter(c,d)|f2 }}  <!--过滤后再过滤-->
    </h3>
</div>
<script>
    // 过滤器
    Vue.filter('my_filter',function(v){
        console.log(v);  // 将num传给v
        return 999
    })
    new Vue({
        el:'#app',
        // data成员用来为vue控制的变量提供值
        data:{
            msg:'message',
            info:'信息'
            num:10,
        }
    })
</script>

Vue文本指令

<div id='app'>
    <!--可以出现基本数据类型-->
    <h2 v-text='msg'></h2>
    <h2 v-text="msg + 'abc'"></h2>
    
    <!--解析标签-->
    <h2 v-html='html'></h2>
    
    <input v-model='msg' type='text'>
    <!--一次性渲染,插值表达式中的任何一个变量被限制,整个结果就不可变-->
    <h3 v-once='html'>{{ htm + msg}}</h3>  <!--html为限制的变量-->
</div>
<script>
    new Vue({
        el:'#app',
        data:{
            msg:'message'
            htm:'<i>标签内容被解析</i>'
        }
    })
</script>

Vue属性指令 - 控制样式

<style>
    .div {
        width: 200px;
        height: 200px;
        background-color: red;
    }
    .box {
        width: 200px;
        height: 200px;
    }
    .blue {
        background-color: blue;
    }
</style>
<!--属性指令  v-bind:属性名='属性值'-->
d<div id="app">
    <div class="div" style="border-radius: 50%"></div>
    <!--指令属性 v-bind:属性名='属性值' ==> v-bind:可以简写为:-->

    <!--自定义属性:没有太多应用场景-->
    <div abc="xyz"></div>
    <div v-bind:abc="xyz"></div>

    <!--title属性-->
    <div :title="xyz"></div>

    <!--style属性-->
    <!--1)变量:变量的值为字典-->
    <div :style="my_style"></div>
    <!--2)字典中的多个变量-->
    <div :style="{width:w,height:h,background:b}"></div>

    <!--class属性-->
    <div :class="c"></div>
    <div :class="[c1,c2]"></div>
    <div :class="[c1,'blue']"></div>
    <!--x是属性 是否生效由y(true|false)值决定 -->
    <div :class="{x: y}"></div>
    <div :class="{'blue': y}"></div>

</div>

</body>

<script src="Vue/vue.js"></script>
<script>
    new Vue({
        el: '#app',
        data: {
            xyz: 'ABC',
            my_style: {
                width: '100px',
                height: '100px',
                backgroundColor: 'cyan',
                borderRadius: '50%'
            },
            w: '100px',
            h: '100px',
            b: 'yellow',
            c: 'box blue',
            c1: 'box',
            c2: 'blue',
            y: true,
        }
    })
</script>iv

Vue事件指令

<style>
    .div {
        width: 200px;
        height: 200px;
        background-color: red;
    }
</style>
<div id="app">
    <!--事件指令 v-on:事件名='fn函数变量' => v-on:可以简写为@-->
    <!--内容操作每点一次,内容+1-->
    <div v-on:click="clickAction" class="div">{{num}}</div>

    <!--样式操作:点击切换背景颜色-->
    <div @click="changeColor" class="div" :style="{'backgroundColor':bgColor}"></div>

    <!--样式操作:点击切换整体样式-->
    <div @click="changeStyle" :style="my_style"></div>
</div>
<script>
    let app = new Vue({
        el: '#app',
        data: {
            num: 100,
            bgColor: 'cyan',
            my_style: {
                width: '200px',
                height: '200px',
                backgroundColor: 'orange'
            }
        },
        methods: {
            clickAction: function () {
                this.num++
            },
            changeColor() {  // 方法的写法
                // if (this.bgColor == 'cyan') {
                //     this.bgColor = 'blue'
                // } else {
                //     this.bgColor = 'cyan'
                // }
                this.bgColor = this.bgColor != 'cyan' ? 'cyan' : 'blue'

            },
            changeStyle: () => { // 这种写法,内部拿到的this是window
                app.my_style = app.my_style.backgroundColor == 'orange' ?
                    {
                        width: '200px',
                        height: '200px',
                        backgroundColor: 'yellow'
                    } :
                    {
                        width: '100px',
                        height: '100px',
                        backgroundColor: 'orange'
                    }
            }
        }
    });
    console.log(app);  // Vue对象
    console.log(app.$el);  // 这个标签
    console.log(app.$data.num);  // num的值
    console.log(app.num);  // 只有data提供数据,$data可以省略
</script>

Vue事件指令传参

<style>
    div {
        width: 100px;
        height: 100px;
        background-color: red;
        border-radius: 50%;
        line-height: 100px;
        text-align: center;
        cursor: pointer;
    }
</style>
<div id="app">
    <!--没有传值,默认传事件对象-->
    <div @click="btnClick1">{{ msg }}</div>
    <!--方法()不会直接调用方法,而是在点击触发后进行传参,接收到的参数就是传入的参数-->
    <div @click="btnClick2(1,msg)">{{ msg }}</div>
    <!--一旦书写方法()就不再传入事件对象,通过$event手动传入事件对象-->
    <div @click="btnClick3(msg,$event,$event)">{{ msg }}</div>
</div>
<script>
    new Vue({
        el: '#app',
        data: {
            msg: 'box'
        },
        methods: {
            btnClick1(ev) {
                console.log(ev.clientX)
            },
            btnClick2(a, b, c) {
                console.log(a, b, c)
            },
            btnClick3(a, b, c) {
                console.log(a, b, c)
            }
        }
    });
</script>

Vue斗篷指令-初次加载页面不会闪烁

<style>
    /*没有vue,不显示;有vue,会移除该属性 => 没有闪烁的显示内容*/
    [v-cloak]{
                display: none;
            }
</style>
<div v-cloak></div>

Vue表单指令

<div id="app">
    <form action="">
        <!--表单指令:v-model='变量'-->
        <!--双向绑定:一个地方修改值,所有地方的数据都会被更新-->
        <input type="text" v-model="info" name="user">
        <input type="password" v-model="info" name="pwd">
        <!--上面没内容,p为初始内容,上面有内容,就显示内容-->
        <p>{{ info | infoFilter }}</p>

        <div>
            <!--单选框:v-model="变量存放的是某个单选框的value值,代表该选框被选中"-->
            男<input type="radio" name="sex" value="male" v-model="sex_val">
            女<input type="radio" name="sex" value="female" v-model="sex_val">
        </div>

        <div>
            <!--单独的复选框:v-model='true|false代表该选框是否选中'-->
            是否同意 <input type="checkbox" name="agree" value="yes" v-model="cb_val">
        </div>

        <div>
            <!--群复选框:v-model='存放选中选框value的数组'-->
            男 <input type="checkbox" name="hobby" v-model="cbs_val" value="male">
            女 <input type="checkbox" name="hobby" v-model="cbs_val" value="female">
            哇塞 <input type="checkbox" name="hobby" v-model="cbs_val" value="others">
            <p>{{cbs_val}}</p>
        </div>
        <div>
            <input type="submit" value="提交">
        </div>
    </form>
</div>
<script>
    Vue.filter('infoFilter', (info) => {
        return info ? info : '初始内容'
    });
    new Vue({
        el: "#app",
        data: {
            info: '',
            sex_val:'male',
            cb_val: true,
            cbs_val: []
        }
    })
</script>

Vue条件指令

<style>
    button {width: 400px;}
    .box {
        width: 200px;
        height: 200px;
        float: left;
    }
    .wrap:after {
        content: '';
        display: block;
        clear: both;
    }
    .red {background-color: red;}
    .blue {background-color: blue;}
    .page {
        width: 300px;
        height: 100px;
    }
    .p1 {background-color: pink;}
    .p2 {background-color: yellow;}
    .p3 {background-color: green;}
    .btn {
        width: 100px;
        float: left;
    }
</style>
<div id="app">
    <!--条件指令
    v-if='true|false':false时不显示页面就不渲染了,推荐使用
    v-show='true|false':false时是用display:none来隐藏
    -->
    <button @click="btnClick">{{title}}</button>
    <div class="wrap">
        <!--v-if隐藏时在内存中建立缓存,可以通过key属性设置缓存的键-->
        <div class="box red" v-if="is_show"></div>
        <div class="box blue" v-show="is_show"></div>
    </div>
    
    <div class="wrap">
        <button class="btn" @click="changePage('pink')">粉</button>
        <button class="btn" @click="changePage('yellow')">黄</button>
        <button class="btn" @click="changePage('green')">绿</button>
    </div>
    <div>
        <div class="page p1" v-if="page == 'pink'"></div>
        <div class="page p2" v-else-if="page == 'yellow'"></div>
        <div class="page p3" v-else></div>
    </div>
</div>
<script>
    new Vue({
        el: "#app",
        data: {
            title: '隐藏',
            is_show: true,
            page: localStorage.page || 'pink'
        },
        methods: {
            btnClick() {
                this.title = this.title == '隐藏' ? '显示' : '隐藏'
                this.is_show = !this.is_show
            },
            changePage(page) {
                this.page = page;
                // localStorage.page=page;  // 永久缓存
                sessionStorage.page = page;  // 临时缓存
            }
        }
    })
</script>

Vue插槽指令

在数据信息交互的时候,父组件将数据传给子组件,子组件又将数据传给父组件,子组件仅仅起数据传递的作用。这种情况,可以通过插槽指令,避免传递数据

<div id="app">
    <p>
        <input type="text" v-model="info">
        <button @click="addMsg">留言</button>
    <ul>
        <my_dic :msg=msg v-for="(msg,i) in msgs" :key="i">
            <!--template通过v-slot绑定子组件内部slot插槽标签的name属性值-->
            <!--在父组件模板的自定义子组件标签中,template是属于子组件模板-->
            <template v-slot:del_btn>
                <span class="del" @click="del_fn">x</span>
            </template>
        </my_dic>
    </ul>
    </p>
</div>
<script>
    let my_dic = {
        props: ['msg'],
        // slot标签是用来在子组件中占位,name的值就是占位的对象
        template: `
        <li>
            <slot name="del_btn"></slot>
            <span>{{msg}}</span>
        </li>`,
    }
    new Vue({
        el: '#app',
        components: {
            my_dic
        },
        data: {
            info: '',
            msgs: JSON.parse(sessionStorage.msgs || '[]'),
        },
        methods: {
            addMsg() {
                if (this.info) {
                    this.msgs.unshift(this.info);
                    this.info = ''
                    sessionStorage.msgs = JSON.stringify(this.msgs);
                }
            },
            del_fn(i) {
                this.msgs.splice(i, 1)
                sessionStorage.msgs = JSON.stringify(this.msgs);
            }
        }
    })
</script>
posted @ 2019-08-27 21:21  Never&say&die  阅读(177)  评论(0编辑  收藏  举报