Vue基础

作者: 陈裔松的技术博客 | 来源:发表于2018-12-19 19:32 被阅读0次

    初识Vue

    • 框架作者 尤雨溪
    • 官网 Vue

    生命周期

    vue.png
    • beforeCreate:组件刚刚被创建
    • created:组件创建完成
    • beforeMount:挂载之前
    • mounted:挂载之后
      Ajax请求和DOM操作是在这里进行的
    • beforeDestory:组件销毁前调用
    • destoryed:组件销毁后调用

    安装Vue

    • 全局安装vue-cli,如果安装不上就以管理员身份尝试安装
      npm install -g vue-cli
    • 创建一个基于webpack模板的新项目
      vue init webpack my-project(你的项目名)
      Install vue-router? (Y/n) => 这里要输入Y
      Use ESlint to lint your code? (Y/n) => 这里最好输入Y,是用于规范代码的
    • 安装依赖包
      cd my-project(你的项目名)
      npm install
      npm run dev 或者 npm start都可以

    模板语法

    <template>
        <div>
            <!-- 数据绑定 -->
            <div>{{title}}</div>
    
            <!-- 函数绑定 -->
            <div>computed:{{aDouble}}</div>
    
            <!-- 事件绑定 -->
             <div v-on:click="say('hi')">点击我</div>
            <div @click="say('hi')">点击我</div>  <!-- 简写方式 -->
    
            <!-- 快速创建子元素 -->
            <div v-html="rawHtml"></div>
    
            <!-- 动态修改class -->
            <div v-bind:class="color">修改class</div>
            <div :class="color">修改class</div>  <!-- 简写方式 -->
    
            <!-- 过滤器 -->
            <div>{{message | capitalize}}</div>  <!-- 如果定义了capitalize,显示capitalize中的内容 -->
        </div>
    </template>
    <script>
    export default {
        // 全局组件的变量定义
        data() {
            return {
                title: "《诗经国风 .周南》",
                num: 1,
                rawHtml: '<span>123</span>',
                color: 'red',
                message: 'message'
            };
        },
    
        // 计算属性
        // 一般的函数定义都放在这里
        computed: {
            aDouble() {
                return this.num * 2;
            }
        },
    
        // 绑定事件的定义都放在这里
        methods: {
            say(h) {
                alert(h);
            }
        }
    
        // 过滤器
        filters: {
            capitalize() {
                return '123';
            }
        }
    };
    </script>
    

    Class与style绑定

    <template>
        <div>
            <!-- class绑定 -->
            <!-- 第一种绑定方式 -->
            <div class="static" v-bind:class="{'active':isActive,'text-danger':hasError}">
                class1
            </div>
    
            <!-- 第二种绑定方式 -->
            <div :class="classObject">
                class2
            </div>
    
            <!-- 第三种绑定方式 -->
            <div :class="[activeClass, errorClass]">
                class3
            </div>
    
            <!-- style绑定 -->
            <!-- 第一种绑定方式 -->
            <div :style="{'color':activeColor,'fontSize':fontSize + 'px'}">
                style1
            </div>
    
            <!-- 第二种绑定方式 -->
            <div :style="styleObject">
                style2
            </div>
    
            <!-- 第三种绑定方式 -->
            <div :style="[baseStyles, overridingStyles]">
                style3
            </div>
        </div>
    </template>
    <script>
    export default {
        data() {
            return {
                isActive: true,   // true的话,这个class会留下
                hasError: false,  // false的话,这个class不会留下
                classObject: {
                    'active': true,
                    'text-danger': false
                },
                activeClass: 'active',
                errorClass: 'text-danger',
    
                activeColor: 'red',
                fontSize: 26,
                styleObject:{
                    'color':'blue',
                    'fontSize':'26px'
                },
                baseStyles: {
                    'color':'black',
                },
                overridingStyles: {
                    'fontSize':'26px'
                },
            }
        },
    }
    </script>
    

    条件渲染

    <template>
        <div>
            <h1 v-if="ok">Yes</h1>  <!-- ok的值是true,所以会显示-->
    
            <div v-if="type==='A'">
                A
            </div>
            <div v-else-if="type==='B'">  <!-- type的值是B,所以会显示B-->
                B
            </div>
            <div v-else-if="type==='C'">
                C
            </div>
            <div v-else>
                Not A/B/C
            </div>
    
            <div v-show="isShow">123</div>  <!-- isShow的值是true,所以会显示-->
        </div>
    </template>
    <script>
    export default {
        data() {
            return {
                ok: true,
                type: "B",
                isShow: true
            };
        },
    };
    </script>
    

    列表渲染

    列表渲染指令v-for可以用于数组和对象

    <template>
        <div>
            <!-- 用于数组 -->
            <ul id="example-1">
                <li v-for="(item,index) in items" :key="index">
                    {{index}}- {{item.message}}
                </li>
            </ul>
    
            <!-- 用于对象 -->
            <ul id="example-2">
                <li v-for="(value,key) in object" :key="key">
                    {{key}} : {{value}}
                </li>
            </ul>
    
        </div>
    </template>
    <script>
    export default {
        data() {
            return {
                items: [
                    { message: 'Foo' },
                    { message: 'Bar' }
                ],
                object: {
                    firstName: 'John',
                    lastName: 'Doe',
                    age: 30
                }
            };
        },
    };
    </script>
    

    事件处理器

    <template>
        <div>
            <div id="example-1">
                <!-- 直接把触发后的处理写在这里 -->
                <button v-on:click="counter += 1">增加1</button>
                <p>这个按钮被点击了{{counter}}次</p>
            </div>
    
            <div id="example-2">
                <!-- 把触发后的处理写在方法greet里 -->
                <!-- 写成@click="greet()"也是一样的,因为这里不带参数,所以可以省略() -->
                <button @click="greet">Greet</button>
                <p>这个按钮被点击了{{counter}}次</p>
            </div>
            
            <div id="example-3">
                <!-- 带参数的方法say -->
                <button @click="say('hi')">say</button>
            </div>
    
            <div @click="dothis2">
                <!-- 事件修饰符(stop):阻止事件冒泡 -->
                <!-- 父元素上的dothis2事件不会被触发 -->
                <button @click.stop="doThis">
                    dothis
                </button>
            </div>
        </div>
    </template>
    
    <script>
    export default {
        data() {
            return {
                counter:0
            };
        },
        methods:{
            greet(){
                this.counter += 1;
            },
            say(h){
                alert(h);
            },
            dothis2(){
                alert('dothis2');
            },
            doThis(){
                alert('doThis');
            }
        }
    };
    </script>
    

    表单控件绑定

    <template>
        <div>
            <!-- input中的内容改变了,message的值也会随之改变 -->
            <input v-model="message"/>
            <p>Message is {{message}}</p> 
            
            <!-- checkbox中的内容改变了,checkedNames的值也会随之改变 -->
            <input type="checkbox" value="Jack" v-model="checkedNames"/>
            <input type="checkbox" value="Rose" v-model="checkedNames"/>
            <br/>
            <span>Checked names:{{checkedNames}}</span>
            
            <!-- select 中的内容改变了,selected的值也会随之改变 -->
            <div>
                <select v-model="selected">
                    <option disabled>请选择</option>
                    <option>A</option>
                    <option>B</option>
                    <option>C</option>
                </select>
                <span>selected:{{selected}}</span>
            </div>
        </div>
    </template>
    <script>
    export default {
        data() {
            return {
                message:'message',
                checkedNames:[],
                selected:'',
            };
        },
    };
    </script>
    

    自定义组件

    index.vue(使用组件)
    <template>
        <div>
            <CountDown color="blue" @end="ending()"/>  <!-- 组件使用 -->
            <!-- color="blue":传递参数给组件 -->
            <!-- @end="ending()":由组件触发的事件 -->
        </div>
    </template>
    <script>
    import CountDown from '@/components/CountDown.vue';  // 组件导入
    export default {
        methods:{
            ending(){
                alert("已经结束了");
            }
        },
        // 组件注册
        components:{
            CountDown
            // 'count-down':countDown   // 组件重名名
        }
    };
    </script>
    
    CountDown.vue(定义组件)
    <template>
        <p :style="{color:color}">{{time}}</p>
    </template>
    <script>
    export default {
        data() {
            return {
                time:10
            };
        },
        mounted(){
            var vm = this;
            var t = setInterval(() => {
                vm.time--;
                if(vm.time === 0){
                    clearInterval(t);
                    vm.$emit("end");  // 在这里触发end事件,父组件会响应到
                }
            }, 1000);
        },
        // 接受父组件传递过来的参数color
        props:{
            color:{
                type:String,      // 参数的类型是字符串
                default:'black'   // 参数的默认值是'black'
            }
        },
    };
    </script>
    

    Vue中的DOM操作

    <template>
        <div>
            <div ref="rhead" class="chead" id="ihead"></div>
        </div>
    </template>
    <script>
    export default {
        mounted(){
            // DOM已经生成
    
            // 如果已经引入jQuery,可以直接这样操作
            // $(".chead").html("123");
    
            // 利用原生javascript找到元素
            // document.getElementById("ihead");
    
            // Vue提供的找到元素方法
            this.$refs.rhead.innerHTML = 'helloworld';
        }
    };
    </script>
    

    Vue中的过渡效果

    <template>
        <div>
            <div id="demo">
                <!-- 点击按钮会慢慢显示/隐藏hello -->
                <button v-on:click="show = !show">
                    Toggle
                </button>
                <transition name="fade">
                    <p v-if="show">hello</p>
                </transition>
            </div>
        </div>
    </template>
    
    <script>
    export default {
        data() {
            return {
                show: false
            };
        },
    };
    </script>
    
    <style>
    /* xx是transition标签中name属性的值 */
    /* 显示:xx-enter(显示开始) -> xx-enter-active(显示进行中) -> xx-enter-to(显示结束) */
    /* 隐藏:xx-leave(隐藏开始) -> xx-leave-active(隐藏进行中) -> xx-leave-to(隐藏结束) */
    
    .fade-enter-active,
    .fade-leave-active {
      transition: opacity 0.5s;
    }
    
    .fade-enter,
    .fade-leave-to {
      opacity: 0;  /* 刚开始显示 和 隐藏结束 的时候,透明度是0,没有显示 */
    }
    
    .fade-leave,
    .fade-enter-to {
      opacity: 1;  /* 刚开始隐藏 和 显示结束 的时候,透明度是1,完全显示 */
    }
    </style>
    

    Vue-router:官网

    <template>
        <div>
            <!-- 第一种跳转写法:一个简单的跳转 -->
            <router-link to="/demo9">demo9</router-link>
    
            <!-- 第二种跳转写法:传递参数 -->
            <router-link :to="{name:'demo9',params:{userId:123}}">demo9-params</router-link>
    
            <!-- 第三种跳转写法:普通参数 + 查询参数 -->
            <router-link :to="{name:'demo9',params:{userId:123},query:{plan:'private'}}">demo9-query</router-link>
    
            <!-- 其他跳转写法 -->
            <button @click="toURL">跳转</button>
        </div>
    </template>
    
    <script>
    export default {
        data() {
            return {
                show: true
            };
        },
    
        methods: {
            toURL() {
                // !!注意这里是router
    
                // 第四种跳转写法:与第一种类似
                // this.$router.push({ path: '/demo8' });
    
                // 第五种跳转写法:与第二种类似
                // this.$router.push({ name: 'demo9', params: { userId: 123 } });
    
                // 第六种跳转写法:与第三种类似
                this.$router.push({ name: 'demo9', params: { userId: 123 }, query:{plan:'private'} });
            },
        }
    };
    </script>
    

    问题1:路由中该怎么设定,才能让demo9接收到参数?

    {
        path: '/demo9/:userId',  // 这里表示接收一个参数,名字叫userId
        name: 'demo9',
        component: Demo9
    },
    

    问题2:demo9中怎么接收参数?

    mounted(){
        // !!注意这里是$route
        console.log(this.$route.params.userId);
        console.log(this.$route.query.plan);
    }
    

    状态管理vuex:官网

    • npm install 引入vuex包
      npm install vuex --save
    • 全局状态管理,所有页面共享数据
    • 设置数据:this.$store.dispatch('increment',1000)
    • 获取数据:this.$store.state.num
    使用步骤1:新建src/store/index.js文件,以应用vuex
    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)   // 调用Vuex
    
    // state:数据,用于全局共享
    // mutations:转换,想做的操作
    // actions:动作,用于调用mutations里的处理
    export default new Vuex.Store({
        state: {
            count: 0,
            num: 1
        },
        mutations: {
            increment(state, num) {  // num是用户传入的参数,经由actions传递,就是下面的obj
                state.count++;
                state.num = num;
            }
        },
        actions: {
            inc({ commit }, obj) {
                commit('increment', obj);  // obj是用户传入的参数,调用increment的时候会传递给它
            }
        }
    })
    
    使用步骤2:main.js中引入和使用store,以构建可用的vuex环境
    import store from './store' // 引入store
    // ...其他import内容此处省略...
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      store,    // 使用store
      components: { App },
      template: '<App/>'
    })
    
    使用步骤3:获取和设置数据
    <template>
        <div>
            <div>{{msg}}</div>
            <button @click="change">change</button>
        </div>
    </template>
    
    <script>
    export default {
        data() {
            return {
                msg: '123'
            };
        },
    
        methods: {
            change(){
                // vuex修改数据
                this.$store.dispatch('inc',1000);
                // vuex取得数据
                this.msg = this.$store.state.num;
            }
        }
    };
    </script>
    

    Slot插槽:常用于组件调用中

    定义组件:components/slot.vue
    <template>
        <div>
            <slot></slot>                <!-- 第一个插槽 -->
            <slot name="bottom"></slot>  <!-- 第二个插槽 -->
        </div>
    </template>
    
    使用组件:pages/xxx.vue
    <template>
        <div>
            <Slots>
                <!-- 以下两个标签会插入到组件Slots的第一个插槽中 -->
                <div>插卡1</div>  
                <div>插卡2</div>
    
                <!-- 以下标签会插入到组件Slots的第二个插槽中,因为设置了属性slot="bottom" -->
                <div slot="bottom">插卡3</div>
            </Slots>
        </div>
    </template>
    
    <script>
    import Slots from '@/components/slot.vue';  // 引入组件
    export default {
        components: {
            Slots    // 定义组件
        }
    };
    </script>
    

    移动组件库Mint UI

    • npm install 引入Mint UI包
      npm install mint-ui@1 --save
    使用步骤1:main.js中引入和使用mint-ui,以构建可用的mint-ui环境
    import MintUI from 'mint-ui'    // 引入mint-ui
    import 'mint-ui/lib/style.css'  // 引入mint-ui的样式
    
    Vue.use(MintUI);                // 全局使用
    
    使用步骤2:使用mint-ui移动组件
    <template>
        <div>
            <mt-tabbar>
                <mt-tab-item id="外卖">
                    <img slot="icon" src="../../assets/logo.png">
                    外卖
                </mt-tab-item>
                <mt-tab-item id="订单">
                    <img slot="icon" src="../../assets/logo.png">
                    订单
                </mt-tab-item>
                <mt-tab-item id="发现">
                    <img slot="icon" src="../../assets/logo.png">
                    发现
                </mt-tab-item>
                <mt-tab-item id="我的">
                    <img slot="icon" src="../../assets/logo.png">
                    我的
                </mt-tab-item>
            </mt-tabbar>
        </div>
    </template>
    
    <script>
    import Vue from 'vue'
    import { Toast, MessageBox, Tabbar, TabItem } from 'mint-ui';
    // 相当于组件注册
    Vue.component(Tabbar.name, Tabbar);
    Vue.component(TabItem.name, TabItem);
    
    export default {
        mounted() {
            Toast('提示信息');
            MessageBox('提示','操作成功');
        }
    };
    </script>
    

    相关文章

      网友评论

          本文标题:Vue基础

          本文链接:https://www.haomeiwen.com/subject/cokskqtx.html