vue语法 vscode插件列表

Vue基础

Vue简介

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式JavaScript框架。 [6] 与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用(SPA)提供驱动。

尤雨溪,前端框架Vue.js的作者,HTML5版Clear的打造人,独立开源开发者。曾就职于Google Creative Labs和Meteor Development Group。由于工作中大量接触开源的JavaScript项目,最后自己也走上了开源之路,现全职开发和维护Vue.js。

1、简化dom操作

2、前后端分离的开发

3、数据双向绑定

vscode

nodeJS: http://nodejs.cn/download/
vsstudio: https://code.visualstudio.com/
在文件夹中 cmd code . 则直接打开当前工程。
安装 auto rename tag插件。
安装code runner插件。
安装open in brower插件。
安装live server插件。
vetur 写vue必备插件
Vue 2 Snippets 写vue必备插件
axios插件
VueHelper vscode插件,vue,vue-router和vuex的代码提示
Path Intellisense 路径自动补全
Auto Close Tag 自动闭合标签
Beautify 格式化文件,保证正确的缩进
HTML CSS Support CSS提示插件
JavaScript (ES6) code snippets es6代码提示插件
VSCode Great Icons 给文件夹增加图标的插件

MVVM框架

model-view-viewmodel

Vue快速起步

1、添加vue的js文件

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

2、声明挂载点(操作的dom对象)

<div id="app">
    {{name}}    <!-- 差值表达式,输出vue中的数据 -->
</div>

3、声明vue对象

let vue = new Vue({
        el:"#app",  //绑定挂载点
        data:{
            name:"关羽"   //声明属性(数据)
        }
    });

基础指令

1、v-text innerText text()

2、v-html innerHTML html()

3、v-on 事件 @

4、v-bind 属性绑定 :

<div id="app">
    <p v-text="message"></p>
    <span v-html="message2"></span>
    <button v-on:click="abc()">btn</button>
    <font v-bind:color="c">ok</font>
    <input v-bind:value="val" >
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    let vue = new Vue({
        el:"#app",
        data:{
            message:"hello vue world!!!",
            message2:"<font color='red'>no</font>",
            c:"red",
            val:"hello"
        },
        methods: {
            abc(){
                alert(123);
            }
        }
    });
</script>

做了一个数量加减

<div id="app">
    <button @click="jian()">-</button><input size="3" :value="count"><button @click="jia()">+</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    let vue = new Vue({
        el:"#app",
        data:{
            count:0
        },
        methods: {
           jian(){
                this.count--;
           },
           jia(){
                this.count++;
           }
        }
    });
</script>

事件修饰符

1、stop

当页面出现事件冒泡,而业务需要各自触发,在底层事件中添加修饰符stop,当该事件执行后,不再进行冒泡。

<div id="app">
    <div v-on:click="a()" style="width: 600px; height: 600px; background-color: antiquewhite;">
        <div v-on:click.stop="b()"  style="width: 400px; height: 400px; background-color:blue;">
            <button type="button" v-on:click.stop="c()">事件冒泡</button>
        </div>
    </div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    let vue = new Vue({
        el:"#app",
        methods: {
            a(){
                alert("a");
            },
            b(){
                alert("b");
            },
            c(){
                alert("c");
            }
        }
    });
</script>

2、prevent

当触发事件的事件源有默认功能,通过prevent取消默认功能。

<div id="app">
    <a @click="a()" href="https://www.baidu.com">百度</a>
    <form action="index.html">
        <button @click.prevent="a">submit</button>
    </form>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    let vue = new Vue({
        el:"#app",
        methods: {
           a(){
               alert("a");
           }
        }
    });
</script>

3、capture

当有事件冒泡,被capture描述的事件会放在第一位执行,余下的冒泡继续执行

<div id="app">
    <div v-on:click="a()" style="width: 600px; height: 600px; background-color: antiquewhite;">
        <div v-on:click.capture="b()"  style="width: 400px; height: 400px; background-color:blue;">
            <button type="button" v-on:click="c()">事件冒泡</button>
        </div>
    </div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    let vue = new Vue({
        el:"#app",
        methods: {
            a(){
                alert("a");
            },
            b(){
                alert("b");
            },
            c(){
                alert("c");
            }
        }
    });
</script>

4、once

该事件执行一次

<div id="app">
    <a href="https://www.baidu.com" @click.prevent.once="a()">百度</a>
    <button @click.once="a()">once</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    let vue = new Vue({
        el:"#app",
        methods: {
            a(){
                alert("a");
            }
        }
    });
</script>

v-model双向绑定

对Vue对象中数据进行修改,则所有展示该数据的位置都进行变化。

<div id="app">
    <span>{{name}}</span>
    <input v-model="name">
    <select v-model="name">
        <option>张无忌</option>
        <option>张三丰</option>
        <option>张翠山</option>
    </select>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    let vue = new Vue({
        el:"#app",
        data:{
            name:"张三丰"
        }
    });
</script>

Vue绑定元素的class属性

1、class添加方式

<div id="app">
    <button @click="red()">red</button>
    <button @click="green()">green</button>
    <button @click="blue()">blue</button>
    <div id="div1" style="width: 400px; height: 400px;" v-bind:class="clazz">

    </div>
</div>
<style>
    .red{
        background-color: red;
    }
    .green{
        background-color: green;
    }
    .blue{
        background-color: blue;
    }
</style>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    let vue = new Vue({
        el:"#app",
        data:{
            clazz:"red"
        },
        methods: {
            red(){
                this.clazz = "red";
            },
            green(){
                this.clazz = "green";
            },
            blue(){
                this.clazz = "blue";
            }
        }
        
    });
</script>

通过boolean值解决class是否添加

<div id="app">
    <div id="div1" style="width: 400px; height: 400px;" :class="clazz">

    </div>
</div>ji
<style>
    .border{
        border: 10px solid red;
    }
    
</style>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    let vue = new Vue({
        el:"#app",
        data:{
            clazz:{"border":false}
        }
        
    });
</script>

class值可以是多个,按照数据结构放置

<div id="app">
    <input type="radio" @click="border()">加边框
    <input type="radio" @click="bg()">加背景
    <div id="div1" style="width: 400px; height: 400px;" :class="clazz">

    </div>
</div>ji
<style>
    .border{
        border: 10px solid red;
    }
    .bg{
        background-color: rosybrown;
    }
</style>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    let vue = new Vue({
        el:"#app",
        data:{
            clazz:[]
        },
        methods: {
            border(){
                this.clazz.push("border");
            },
            bg(){
                this.clazz.push("bg");
            }
        }
        
    });
</script>

可以通过三目运算添加class

2、style

直接在:style中编写样式json结构

可以在data中声明样式的变量,这个变量也可以是多个,用数组保存

<div id="app">
    <!-- 
        style属性添加内容时结构是width:400px
        :style添加结构是{width:'400px'}
    -->
    
    <div id="div1" :style="{width:'400px',height:'400px',backgroundColor:'red'}">

    </div>
    <div id="div2" :style="styleObj">

    </div>
    <div id="div2" :style="[styleObj,styleObj2]">

    </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    let vue = new Vue({
        el:"#app",
        data:{
            styleObj:{width:'400px',height:'400px',backgroundColor:'blue'},
            styleObj2:{border:'10px solid green'}
        }
        
    });
</script>

v-for

1、数组循环

2、对象循环

3、对象数组循环

<div id="app">
    <ul>
        <!-- 
            1、循环数组时:
            in前面可以加单参,就是值
            in前面可以加双参,第一个是值,第二个是下标
        -->
        <li v-for="wujiang,index in wujiangs">{{index+1}},{{wujiang}}</li>
        
    </ul>
    <!-- 
            2、循环对象
            第一个是值
            第二个是属性
            第三个是下标
     -->
     <p v-for="x,y,z,i in wujiang1">{{x}}---{{y}}-----{{z}}</p>
     <!-- 
         3、循环对象数组
     -->
     <ul v-for="x in wujiangs2">
        <li v-for="a in x">
            {{a}}
        </li>
     </ul>
     <!-- 
         数据展示样例
     -->
     <table>
         <tr>
             <th>编号</th>
             <th>姓名</th>
             <th>武器</th>
         </tr>
         <tr v-for="wj,index in wujiangs2">
             <th>{{index+1}}</th>
             <th v-text="wj.name"></th>
             <th v-text="wj.weapon"></th>
         </tr>
     </table>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    let vue = new Vue({
        el:"#app",
        data:{
            wujiangs:['黄忠','小乔','盾山'],
            wujiang1:{
                name:'小乔',
                weapon:'扇子'
            },
            wujiangs2:[
                {
                    name:'小乔',
                    weapon:'扇子'
                },
                {
                    name:'黄忠',
                    weapon:'大炮'
                },
            ]
        }
        
    });
</script>

v-if、v-show

v-if和v-show都可以控制页面元素的显示与不显示

v-if对于不显示的元素,不生成。

v-show对于不显示的元素,生成并设置样式不可显

如果该元素一直不显示就使用v-if

如果该元素会根据状况一会显示一会不显示,则使用v-show

<div id="app">
    <button v-if="permission.indexOf('delete')!=-1">删除</button>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    let vue = new Vue({
        el:"#app",
        data:{
           permission:"update,add"
        }
        
    });
</script>

Vue进阶

Vue全局过滤器

可以跨Vue使用,字符串格式化、日期格式化、金额格式化等等。

声明全局过滤器

 //全局过滤器
    //生成过滤器,通过静态方法filter,第一个参是过滤器名称,第二个是过滤器功能(函数)
    Vue.filter("dateFormat", function(value){
        let year = value.getFullYear();
        let month = value.getMonth()+1;
        let date = value.getDate();
        return `${year}-${month}-${date}`;
    });

使用过滤器

<div id="app">
    {{birth|dateFormat}}
</div>
<div id="app2">
    {{birth|dateFormat}}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    //全局过滤器
    //生成过滤器,通过静态方法filter,第一个参是过滤器名称,第二个是过滤器功能(函数)
    Vue.filter("dateFormat", function(value){
        let year = value.getFullYear();
        let month = value.getMonth()+1;
        let date = value.getDate();
        return `${year}-${month}-${date}`;
    });

    let vue = new Vue({
        el:"#app",
        data:{
           birth:new Date()
        }
        
    });

    let vue2 = new Vue({
        el:"#app2",
        data:{
           birth:new Date()
        }
        
    });
</script>

Vue私有过滤器

在Vue对象中声明的过滤器,只能在当前Vue对象中使用,不能跨Vue使用。

<div id="app">
    {{salary|numFormat}}
</div>
<div id="app2">
    {{comm|numFormat}}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    
    let vue = new Vue({
        el:"#app",
        data:{
           salary:30000  //30,000
        },
        filters: {
            "numFormat":function(value){
                value+="";
                console.log(value.length);
                let start = value.length-3;
                console.log(start);
                let front = value.substring(0,start);
                console.log("front:"+front);
                let back = value.substring(start);
                return `${front},${back}`;
            }
        }
        
    });

    let vue2 = new Vue({
        el:"#app2",
        data:{
           comm:5300  //5,300
        }
        
    });

</script>

按键修饰符

获得键盘事件

不需要在事件处理中判断点的是哪个键

直接使用按键修饰符即可。

@keyup.enter="add()"   //在输入框中添加该事件及按键修饰符等同于点按钮
<div id="app">
    <form>
        uname<input name="uname" id="uname" v-model="user.uname">
        upwd<input name="upwd" id="upwd" v-model="user.upwd" @keyup.enter="add()">
        <button type="button" @click="add()">add</button>
    </form>
    <table width="600" border="1">
        <tr>
            <th>编号</th>
            <th>用户名</th>
            <th>密码</th>
        </tr>
        <tr v-for="user,index in userList">
            <th>{{index+1}}</th>
            <th>{{user.uname}}</th>
            <th>{{user.upwd}}</th>
        </tr>
    </table>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    let vue = new Vue({
        el:"#app",
        data:{
            user:{
                uname:"",
                upwd:""
            },
           userList:[
               {"uname":"admin","upwd":"123"}, 
               {"uname":"andy","upwd":"456"}
           ]
        },
        methods: {
            add(){
                this.userList.push(this.user);
            }
        }
        
    });
</script>

Vue自定义指令

v-text、v-html

当前需要新的指令完成一定的功能

例如:将焦点直接设置某个控件上

全局自定义指令和局部自定义指令

<div id="app">
    <input name="n1" >
    <input name="n2" v-focus >
    <input name="n3" >
</div>

<div id="app2">
    <input name="n1" >
    <input name="n2" >
    <input name="n3" v-focus >
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    //定义全局的自定义指令
    //
    // Vue.directive("focus",{
    //    inserted:function(dom){
    //        dom.style.backgroundColor='red';
    //         dom.focus();
    //    } 
    // });
    let vue = new Vue({
        el:"#app",
        directives: {
            "focus":{
                inserted:function(dom){
                    dom.style.backgroundColor="green";
                    dom.focus();
                }
            }
        }
        
    });
    let vue2 = new Vue({
        el:"#app2"
        
    });
</script>

Vue组件的生命周期

<img src="https://woniumd.oss-cn-hangzhou.aliyuncs.com/java/panfeng/20210507143352.png" style="zoom: 80%;" />

1、初始化数据

beforeCreate() //这时Vue还没有初始化数据,没有el、data等等,只有默认事件和vue生命周期

created() //data、methods都已经初始化了,这时还没有el

2、挂载

beforeMount() //获得el,但是el的数据没有添加上

mounted() //将数据与模板整合。

3、修改数据

beforeUpdate() //修改数据之前方法

updated() //修改数据之后的方法

4、销毁

this.$destroy();

完全销毁一个实例。清理它与其它实例的连接,解绑它的全部指令及事件监听器。

触发 beforeDestroydestroyed 的钩子。

beforeDestroy() //销毁之前,还可以使用vue的数据

destroy(); //销毁之后,所有vue数据不可用。

<div id="app">
   {{message}}
   <input v-bind:value="message">
   <button @click="message='数据修改了'">修改message数据</button>
   <button @click="clear()">clear</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
   
    let vue = new Vue({
        el:"#app",
        data:{
            message:"hello vue life!!"
        },
        methods: {
          clear(){
              this.$destroy();
          }  
        },
        //编写钩子函数 在创建、挂载、修改、销毁4个点分别2个钩子函数
        beforeCreate () {
            console.log(this.$el);
            console.log(this.$data);
            console.log(this.message);
        },
        created () {
            console.log(this.$el);
            console.log(this.$data);
            console.log(this.message);
        },
        beforeMount () {
            console.log(this.$el);
            console.log(this.$data);
            console.log(this.message);
        },
        mounted () {
            console.log(this.$el);
            console.log(this.$data);
            console.log(this.message);
        },
        //this.$el的数据已经解析
        beforeUpdate () {
            console.log(this.$el);
            let div = document.getElementById("app");
            console.log(div.innerHTML);
            console.log(this.message);
        },
        updated () {
            console.log(this.$el);
            let div = document.getElementById("app");
            console.log(div.innerHTML);
            console.log(this.message);
        },
        
        //虽然这里的数据还可以看到,但是所有功能已经不存在了。
        beforeDestroy () {
            console.log("------------------");
            console.log(this.$el);
            let div = document.getElementById("app");
            console.log(div.innerHTML);
            console.log(this.message);
        },
        destroyed () {
            console.log(this.$el);
            let div = document.getElementById("app");
            console.log(div.innerHTML);
            console.log(this.message);  
        }
        
        
    });

</script>

Computed和Watch

1、computed计算列

结构类似于方法

computed: {
            result:function(){
                return parseInt(this.num1)+parseInt(this.num2);
            }
        }

在需要展示的地方,放置计算列的名称

当计算列中的属性值发生变化,则重新计算并加载到页面

2、watch

<div id="app">
    <input v-model="age" >
    {{age}}
</div>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    let vue = new Vue({
        el:"#app",
        data:{
           age:0
        },
        watch: {
            age(newVal,oldVal){
                this.age = newVal.replace(/[^\d]/g,'');
            }
        }
        
    });
</script>

前后端分离案例

1、通过Springboot搭建Controller接口

package com.woniu.controller;

import com.woniu.service.EmpService;
import com.woniu.util.ResultVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
 * @Author: Panda
 * @Date: 2021/5/8 09:32
 * @Description:
 */
@RestController     //@ResponseBody和@Controller 所有handler返回json数据
@RequestMapping("emp")
public class EmpController {
    @Autowired
    private EmpService empService;
    @GetMapping     //@RequestMapping(method=RequestMethod.GET)
    public ResultVO list(){
        return ResultVO.Result(200,"员工列表查询成功",empService.findByPage());
    }
}

2、配置跨域

package com.woniu.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

/**
 * @Author: Panda
 * @Date: 2021/5/8 09:44
 * @Description:
 */
@Configuration
public class CORSConfig extends WebMvcConfigurationSupport {
    @Override
    protected void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "HEAD", "POST","PUT", "DELETE", "OPTIONS")
                .allowedHeaders("*")
                .exposedHeaders("access-control-allow-headers",
                        "access-control-allow-methods",
                        "access-control-allow-origin",
                        "access-control-max-age",
                        "X-Frame-Options")
                .allowCredentials(false).maxAge(3600);
        super.addCorsMappings(registry);
    }
}

3、编写vue页面

添加axios的js文件

<div id="app">
    <table width="1000" border="1" align="center">
        <caption><h2>员工管理</h2></caption>
        <tr>
            <th>序号</th>
            <th>姓名</th>
            <th>职位</th>
            <th>上级</th>
            <th>雇佣日期</th>
            <th>工资</th>
            <th>奖金</th>
            <th>部门</th>
            <th>编辑</th>
            <th>删除</th>
        </tr>
        <tr v-for="emp,index in empList">
            <th>{{index+1}}</th>
            <th>{{emp.ename}}</th>
            <th>{{emp.job}}</th>
            <th>{{emp.mgr}}</th>
            <th>{{emp.hiredate}}</th>
            <th>{{emp.sal|numFormat}}</th>
            <th>{{emp.comm|numFormat}}</th>
            <th>{{emp.deptno}}</th>
            <th>{{emp.empno}}</th>
            <th>{{emp.empno}}</th>
        </tr>
        <tr>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
            <th></th>
        </tr>
    </table>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

<script>
    //发送ajax请求,在vue中是用axios
    Vue.filter("numFormat",function(value){
        if(value==null||value==""){
            return "";
        }
        value=value+"";
        if(value.length<=3){
            return value;
        }
        let start = value.length-3;
        return value.substring(0,start)+","+value.substring(start);
    });
    let vm = new Vue({
        el:"#app",
        data:{
            empList:null
        },
        mounted () {
            this.list();  
        },
        methods: {
            list(){
                let _this = this;
                axios.get("http://localhost:8080/emp")
                .then(function(response){
                    console.log(response.data.data);
                    _this.empList = response.data.data;
                    console.log(this);
                })
                .catch(function(error){
                    consolse.log(error);
                })
            }
        }
    });
</script>

日期类型需要配置格式

axios({
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    method: 'POST',
    url: 'http://localhost:9000/save',
    params:{
        uid: this.uid,
        uname: this.uname,
        upass: this.upass
    },
})
.then((res) => {
    this.show();
})
.catch((err) => {
    console.error(err);
})
axios发请求的基本语法:
    axios({
      url: '路径', // 这个路径中可以包含params或query参数
      method: 'get/post/put/delete',
      params: {}, // 包含query参数的对象,问号后面的参数
      data: {}, // 包含请求体参数的对象
    })
    axios.get(url, {配置})  // {params: {id: 1}}
    axios.delete(url, {配置})
    axios.post(url, data数据对象)
    axios.put(url, data数据对象)

  使用axios发ajax请求携带参数:
    params参数: 只能拼在路径中: /admin/product/baseTrademark/delete/1
    query参数: 
      拼在路径中的?后面: /admin/product/baseTrademark?id=1
      通过params配置来指定: axios({params: {id: 1}})
    请求体参数: 
      通过data配置或post()/put()的第二个参数指定

Vue组件

创建Vue组件的三种方式

Component是一个自定义控件,相当于自定义标签,将多个标签组合成一个模块,可以在需要的地方进行添加

<div id="app">
    <com3></com3>
    <com4></com4>
</div>
<div id="app2">
    <com3></com3>
    <com4></com4>
</div>

<!-- 
    声明模板 
    如果有多个标签,这时模板的内容只展示第一个标签
    在多个标签的外层添加一个根标签
-->
<template id="temp3">
    <div>
        <h2>第三种组件</h2>
        <h3>第三种组件2</h3>
    </div>
</template>

<template id="temp4">
    <div>
        <font color='red'>组件4</font>
    </div>
</template>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    //声明一个添加表单


    //声明全局组件,所有的Vue都可以使用
    //1、先使用extend声明模板、将模板注册为全局组件
    //声明模板
    // let temp1 = Vue.extend({
    //     template:`<form>
    //         uname<input />
    //         upwd<input />
    //         <button>add</button>
    //     </form>`
    // });
    // //将模板注册为组件
    // //"com1"就是自定义了一个标签名
    // Vue.component("com1",temp1);
    //2、直接将模板内容注册为全局组件
    // Vue.component("com2",{
    //     template:`<h1>组件2</h1>`
    // });
    //编写模板内容太麻烦
    //3、在html代码直接编写模板,将模板注册到组件中
    Vue.component("com3",{
        template: "#temp3"  //#temp3对应html中声明的模板
    });

    let vue = new Vue({
        el:"#app",
        //声明局部组件,只能在当前Vue中使用
        components: {
            "com4":{
                template:"#temp4"
            }
        }
    });

    let vue2 = new Vue({
        el:"#app2"
    });
</script>

在组件中可以声明属性和方法

<div id="app">
    <component1></component1>
</div>

<template id="template1">
    <div>
        <h2>{{messageCom}}</h2>
        <button @click="cm()">changeMessage</button>
    </div>
</template>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    let vue = new Vue({
        el:"#app",
        data:{
            message:"这是Vue中data" //组件无法直接访问Vue中的data
        },
        components: {
            "component1":{
                template:"#template1",
                data(){      //组件中的data必须按照方法声明,必须有return
                    return{
                        messageCom:"这是组件中的data" 
                    }
                },
                methods: {
                    cm(){
                        console.log("这是组件中的cm方法");
                        this.messageCom="组件中的cm方法改变了我";
                    }
                }
            }
        },
        methods: {
            cm(){   //组件不能直接访问Vue中的方法
                console.log("这是Vue中的cm方法");
            }
        }
        
    });

</script>

组件的切换

在Vue挂载点上声明<component :is="组件名">

通过按钮或者超链接改变组件名称,从而达到切换组件的功能。

<div id="app">
    <a href="#" @click.prevent="comName='logincom'">login</a>
    <a href="#" @click.prevent="comName='regcom'">reg</a>
    <!-- <logincom v-if="showLogin"></logincom>
    <regcom v-if="!showLogin"></regcom> -->
    <!-- 
        component标签作为组件的载体 
        :is=组件名称
    -->
    <component :is="comName"></component>
</div>

<template id="login">
    <div>
        <h3>用户登录</h3>
        <form>
            uname<input type="text">
            upwd<input type="text">
            <button>login</button>
        </form>
    </div>
</template>


<template id="reg">
    <div>
        <h3>用户注册</h3>
        <form>
            uname<input type="text">
            upwd<input type="text">
            upwd<input type="text">
            <button>reg</button>
        </form>
    </div>
</template>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    let vue = new Vue({
        el:"#app",
        data:{
            showLogin: false,
            comName: "logincom"
        },
        components: {
            "logincom":{
                template:"#login"
            },
            "regcom":{
                template:"#reg"
            }
        }
    });

</script>

父子组件相互访问属性和方法

1、子组件访问父组件的data

父组件通过子组件的属性props将父组件中的data传递到子组件中

2、子组件访问父组件的method

父组件通过在子组件上声明事件,将父组件的方法放到事件里,子组件通过this.$emit("事件名",参数)

<div id="app">
    <myfont v-bind:color="color" @abc="m1"></myfont>  <!-- 如果m1方法有参数,则省略()  -->
</div>

<template id="template1">
    <div>
        <font v-bind:color="color">abc</font>
        <button @click="m2()">按钮</button>
    </div>
</template>

<!-- 假设font标签就是自定义的,那么怎么改变字的颜色,需要在声明该标签时,声明对应的属性  -->
<!-- 
    子组件访问父组件的data
    1、定义子组件
    2、定义该组件的属性
    3、在父组件中声明子组件
    4、绑定子组件的属性,这时将父组件的data数据通过属性传递到子组件中
    子组件访问父组件的方法
    1、定义子组件
    2、定义该组件的方法
    3、在父组件中声明子组件,并声明一个事件调用父组件的方法
    4、在子组件中使用this.$emit("事件名")
    5、如果父组件的方法带参数,在this.$emit("事件名",参数)即可
    父组件访问子组件的data和method
    
-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    let vue = new Vue({
        el:"#app",
        data:{
            color:"red"  
        },
        methods: {
            m1(val){
                alert(val);
            }  
        },
        components: {
            "myfont":{
                template:"#template1",
                props:['color'],
                methods: {
                    m2(){
                       //通过子组件的方法调用父组件的方法
                       this.$emit("abc","this is a message"); 
                    }
                }
            }
        }
    });

</script>

3、父组件访问子组件的data和method

在子组件中声明ref,通过this.$refs.refVal.data|method

<div id="app">
    <com ref="refName"></com>
    <button @click="m()">btn</button>
</div>

<template id="template1">
    <div>
        
    </div>
</template>

<!-- 

    父组件访问子组件的data和method
    
-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    let vue = new Vue({
        el:"#app",
        data:{
            color:"red"  
        },
        methods: {
            m(){
                console.log(this.$refs.refName.message);
                this.$refs.refName.m1();
            }  
        },
        components: {
            "com":{
                template:"#template1",
                data(){
                    return{
                        message:"子组件的data"
                    }
                },
                methods: {
                    m1(){
                        console.log("子组件的method");
                    }
                }
            }
        }
    });

</script>

Vue如何获取DOM元素

使用两种方式获取dom元素

1、document.getElementById()提供的方法获取,可以获取当前页面中所有的有id的dom节点

2、通过ref获取,只能获取当前访问的dom节点

<div id="app">
    <com ref="r3"></com>
    <input ref="r2" value="456">
    <button @click="m2()">btn2</button>
    
</div>

<template id="template1">
    <div>
        <input ref="r1" value="123" id="r1">
        <button @click="m()">btn</button>
    </div>
</template>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
    let vue = new Vue({
        el:"#app",
        methods: {
            m2(){
                // console.log(this.$refs.r1);
                // console.log(this.$refs.r2);
                this.$refs.r2.style.backgroundColor='red';
                console.log(document.getElementById("r1"));
            }
        },
        components: {
            "com":{
                template:"#template1",
                methods: {
                    m(){
                        console.log(this.$refs.r1);
                        console.log(this.$refs.r2);
                    }
                }
            }
        }
    });

</script>

Vue路由

Vue路由

声明组件就是模块化开发,通过链接进行组件切换

<component>和组件名

添加vue-router.js

<script src="https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js"></script>

需要在vue.js后添加

1、声明所有的组件

let list = Vue.component("list",{
        template:"#list"
    });
let list = {
        template:"#list"
    };

2、声明路由,将所有组件对应访问路径

let router2 = new VueRouter({
        routes:[
            {component:list,path:"/list"},
            {component:add,path:"/add"}
        ]
    });

3、声明路由展示标签

<router-view></router-view>

4、声明链接进行切换

    <a href="#/list">list</a>
    <a href="#/add">add</a>

链接的位置需要加#,等同于锚点链接

5、可以把链接改成<router-link>

<router-link to="/list">list</router-link>
    <router-link to="/add">add</router-link>

链接的位置不需要加#

传参方式:

a、?绑定传参 this.$route.query.参数名
b、rest传参 this.$route.params.参数名(该参数名需在路由中配置,/:参数名)
<router-link to="/list?id=1">list</router-link>
    <router-link to="/add/123">add</router-link>
    let list = {
        template:"#list",
        methods: {
            m1(){
                console.log(this.$route);
                console.log(this.$route.query);
                console.log(this.$route.query.id);
            }
        }
    };
    let add = {
        template:"#add",
        methods: {
            m2(){
                console.log(this.$route);
                console.log(this.$route.params);
                console.log(this.$route.params.deptno);
            }
        }
    };

Vue二级路由

当页面中有多个模块的组件,将这些组件分别管理路由

需要添加模块的根路由,在根路由中添加子路由

在根组件中添加子组件的路由和展示。

在根组件中切换子组件

<div id="app">
    <router-link to="/emp">员工管理</router-link>
    <router-link to="/user">用户管理</router-link>
    <router-view></router-view>
</div>

<template id="empList">
    <div>
        <h2>员工列表页</h2>
        <router-link to="/add">员工添加</router-link>
        <router-view></router-view>
    </div>
</template>

<template id="empAdd">
    <div>
        <h2>员工添加页</h2>
    </div>
</template>

<template id="userList">
    <div>
        <h2>用户列表页</h2>
        <router-link to="/add">用户添加</router-link>
        <router-view></router-view>
    </div>
</template>

<template id="userAdd">
    <div>
        <h2>用户添加页</h2>
    </div>
</template>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js"></script>
<script>
    let empList = {
        template:"#empList"
    }
    let empAdd = {
        template:"#empAdd"
    }
    let userList = {
        template:"#userList"
    }
    let userAdd = {
        template:"#userAdd"
    }

    let router = new VueRouter({
        routes:[
            {
                component:empList,
                path:"/emp",
                children:[
                    {component:empAdd,path:"/add"},
                ]
            },
            {
                component:userList,
                path:"/user",
                children:[
                    {component:userAdd,path:"/add"}
                ]
            }
           
        ]
    });

    let vue = new Vue({
        el:"#app",
        router  //router:router
    });
</script>

Vue命名路由

命令路由

命名路由方便调用,并可以直接按照rest传值

<div id="app">
    <router-link :to="{'name':'emp',params:{'id':1001}}">员工管理</router-link>
    <router-view></router-view>
</div>

<template id="empList">
    <div>
        <h2>员工列表页</h2>
        <button @click="method1()">btn</button>
    </div>
</template>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js"></script>
<script>
    let empList = {
        template:"#empList",
        methods: {
            method1(){
                console.log(this.$route.params.id);
            }
        }
    }
    
    let router = new VueRouter({
        routes:[
            {
                component:empList,
                path:"/emp/:id",
                name:"emp"
            }
           
        ]
    });

    let vue = new Vue({
        el:"#app",
        router  //router:router
        
    });
</script>

命名视图

<div id="app">
    <router-view></router-view>
    <router-view name="nav"></router-view>
    <router-view name="main"></router-view>
</div>

<template id="logo">
    <div style="width: 1000px; height: 150px; background-color: antiquewhite;">
        <h2>标题</h2>
    </div>
</template>

<template id="nav">
    <div style="width: 150px; height: 700px; background-color: chartreuse; float: left;">
        <h2>导航</h2>
    </div>
</template>

<template id="main">
    <div style="width: 850px; height: 700px; background-color: coral; float: left;">
        <h2>主界面</h2>
    </div>
</template>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js"></script>
<script>
    let logo = {
        template:"#logo"
    }
    let nav = {
        template:"#nav"
    }
    let main = {
        template:"#main"
    }
    let router = new VueRouter({
        routes:[
            {
                path:"/",
                components: {
                    default:logo,
                    nav:nav,
                    main:main
                }
            }
           
        ]
    });

    let vue = new Vue({
        el:"#app",
        router  //router:router
        
    });
</script>

守卫路由

也称为导航守卫

全局前置守卫router.beforeEach(to,from,next)

路由守卫

组件守卫

<div id="app">
    <router-link to="/login">login</router-link>
    <router-link to="/list">list</router-link>
    <router-view ></router-view>
</div>

<template id="list">
    <div>
        <h2>list</h2>
    </div>
</template>

<template id="login">
    <div>
        <h2>login</h2>
    </div>
</template>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js"></script>
<script>
    let list = {
        template:"#list"
    }
    let login = {
        template:"#login"
    }
    
    let router = new VueRouter({
        routes:[
            {
                path:"/",
                component:login
            },
            {
                path:"/list",
                component:list
            },
            {
                path:"/login",
                component:login
            }
           
        ]
    });
    //全局前置守卫
    router.beforeEach((to, from, next) => {
        //通过Vuex进行共享数据的存储,所有的组件都可以访问到
       if(to.path=="/login"){
            next();
       } 
    });
    let vue = new Vue({
        el:"#app",
        router  //router:router
        
    });
</script>

完整的导航解析流程
导航被触发。
在失活的组件里调用 beforeRouteLeave 守卫。
调用全局的 beforeEach 守卫。
在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
在路由配置里调用 beforeEnter。
解析异步路由组件。
在被激活的组件里调用 beforeRouteEnter。
调用全局的 beforeResolve 守卫 (2.5+)。
导航被确认。
调用全局的 afterEach 钩子。
触发 DOM 更新。
调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容