快速入门

环境配置

获取vue.js文件

前往 官网 下载vue2

去除浏览器提示

1.浏览器下载开发者工具

2.html中js脚本关闭生产提示

<script>
    Vue.config.productionTip = false //关闭生产vue提示
</script>

基本使用

创建容器

el的其他写法

<script>
    Vue.config.productionTip = false //关闭生产vue提示
    const v = new Vue({
        // el:"#app",
        data: {
            name: "miaolme"
        }
    })
    // 1s后执行
    setTimeout(() => {
        v.$mount("#app") //设置el
    }, 1000);
</script>

data的两种写法

函数式

//1. 创建vue核心对像
new Vue({
    el:"#app",
    data: function(){
        return {
            username:""
        }
    }
});

简写

//1. 创建vue核心对像
new Vue({
    el: "#app",
    data() {
        return {
            username: ""
        }
    }
})

例子

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue使用</title>
    <script src="./js/vue2.js"></script>
</head>

<body>
    <div id="app">

        <input v-model="username">
        <!-- 插值表达式 -->
        {{username}}
    </div>

</body>
<script>
    //1. 创建vue核心对像
    new Vue({
        el: "#app",
        data() {
            return {
                username: ""
            }
        }
    })

</script>

</html>

Vue常用指令

指令:HTML标签上带有V-前缀的特殊属性,不同指令具有不同含义

指令作用
v-bind为HTML标签绑定属性值,如设置href,css样式等
v-model在表单元素上创建双向数据绑定
v-on为HTML标签绑定事件
v-if
v-else
v-else-if
条件性的渲染某元素,判定为true时渲染,否则不渲染
v-show根据条件展示某元素,区别在于切换的是display属性的值
v-for列表渲染,遍历容器的元素或者对象的属性

v-model

v-model 在表单元素上创建双向数据绑定

表单的变化会影响整个vue的设定值

v-bind

修改href,css等样式

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue使用</title>
    <script src="./js/vue2.js"></script>
</head>

<body>
    <div id="app">
        <a v-bind:href="url">点击一下</a>
        <br>
        <a :href="url">简化格式</a>
    </div>

</body>
<script>
    //1. 创建vue核心对像
    new Vue({
        el: "#app",
        data() {
            return {
                username: "",
                url: "https://baidu.com"
            }
        }
    })

</script>

</html>

v-on

定义事件

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vue使用</title>
    <script src="./js/vue2.js"></script>
</head>

<body>
    <!-- 这个div中的id决定了下方vue是否可用 -->
    <div id="app">
        <input type="button" value="一个按钮" v-on:click="show()">
        <br>
        <!-- 简化书写 -->
        <input type="button" value="第二个按钮" @click="show()">
    </div>

</body>
<script>
    //1. 创建vue核心对像
    new Vue({
        el: "#app",
        data() {
            return {
                username: "",
                url: "https://baidu.com"
            }
        },
        methods: {
            show() {
                alert("我被点中了",number)
            }
        }
        /*
        methods: {
            show(number) { //可以传参
                alert("我被点中了",number)
            }
        }
        */
    })

</script>

</html>
<input type="button" value="一个按钮" v-on:click="show()">
<!-- 简化书写 -->
<input type="button" value="第二个按钮" @click="show()">

v-for

列表渲染,遍历容器的元素或者对象的属性

v-for:

<div v-for='addr in addrs'>
	{{addr}}<br>
</div>

加索引

<div v-for="(addr,i) in addrs">
 <!-- i表示索引,从0开始 -->
  {{i + 1}}:{{addr}}<br>
</div>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./js/vue2.js"></script>
</head>

<body>
    <div id="app">

        <div v-for="addr in addrs">
            {{addr}} <br>
        </div>
        <hr>
        <div v-for="(addr,i) in addrs">
            {{i+1}}--{{addr}} <br>
        </div>
    </div>

</body>
<script>
    new Vue({
        el: "#app",
        data() {
            return {
                addrs: ["北京", "上海", "天津"]
            }
        }
    })
</script>

</html>

Vue数据代理

对象添加数据

Object.defineProperty

<script>
    let person = {
        name: "张三",
        sex: "男"
    }

    Object.defineProperty(person, 'age', {
        value: 18 //往person对象中添加一个新的键值对 age:18
        enumerable: true //控制属性是否可枚举,默认false
        writable: true  //控制属性是否可用被修改,默认false
        configurable: true  //控制属性是否可被删除,默认false
    })
    console.log(person)  //{name: '张三', sex: '男', age: 18}
</script>

默认:不可枚举,不可遍历,不可修改,不可删除

let person = {
    name: "张三",
    sex: "男"
}
let number = 18

Object.defineProperty(person, 'age', {
    /*
    get: function () {
        return number //每次调用age的值会返回number
    }
    */
    //简写
     get(){
        return number //每次调用age的值会返回number
    },
    //当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
     set(value){
        console.log('有人修改了age属性,且修改的值是',value)
        number = value
	}
})
console.log(person)

事件处理

    new Vue({
        el: "#App",
        data: {
            name: 'xingli'
        },
        methods: {
            showInfo(e) {
                console.log(e.target.value)
            }
        },
    })

方法写入method中

v-on

用于事件绑定,可以用@代替 例如@click

@click.stop 停止事件冒泡

Vue中的事件修饰符: 1.prevent:阻止默认事件(常用); 2.stop:阻止事件冒泡(常用); 3.once:事件只触发一次(常用); 4.capture:使用事件的捕获模式; 在事件捕获阶段进行事件处理,自上而下 5.self:只有event.target是当前操作的元素是才触发事件; 6.passive:事件的默认行为立即执行,无需等待事件回调执行完毕;

键盘事件

绑定vue按键事件的@

常用@keydown @keyup

Vue中常用的按键别名:

  1. 回车=>enter
  2. 删除=>delete(捕获“删除”和“退格”键)
  3. 退出=>esc
  4. 空格=>space
  5. 换行=>tab
  6. 上=>up
  7. 下=>down
  8. 左=>left
  9. 右=>right
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./js/vue2.js"></script>
</head>

<body>
    <div id="App">
        <input type="text" placeholder="按下回车提示输入" @keyup="showInfo">
    </div>

</body>
<script>
    new Vue({
        el: "#App",
        data: {
            name: 'xingli'
        },
        methods: {
            showInfo(e) {
                if (e.keyCode !== 13) return //设置按下回车返回输入值
                console.log(e.target.value)
            }
        },
    })
</script>

</html>

2.Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要转为kebab-case(短横线命名)

showInfo(e) {//使用该代码可以得到key值
     console.log(e.key)
     console.log(e.keyCode)
}

**4.也可以使用keyCode去指定具体的按键(不推荐)**不同键盘的keyCode不同 5.Vue.config.keyCodes.自定义键名=键码,可以去定制按键别名

3.系统修饰键(用法特殊):ctrl、alt、shift、meta (1).配合keyup使用:按下修饰键的同时,再按下其他键,随后释放其他键,事件才被触发。 (2).配合keydown使用:正常触发事件。

修饰符可用.连接连续写

@keyup.ctrl.y 按下ctrl+y触发事件

@click.prevent.stop 先阻止默认事件,再停止冒泡

计算属性与监视

计算属性 computed

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./js/vue2.js"></script>
</head>

<body>
    <div id="App">
        姓<input type="text" v-model="firstName"> <br> <br>
        名<input type="text" v-model="lastName"> <br> <br>
        姓名: <span>{{fullName}}</span>
    </div>
</body>

<script>
    new Vue({
        el: '#App',
        data: {
            firstName: '张',
            lastName: '三'
        },
        computed: {
            fullName: {//最后存在data中
                get() {
                    console.log('get被调用了')
                    return this.firstName + '-' + this.lastName
                },
               /*   set(value) {
                    console.log('set被调用了',value)
                    const arr = value.split('-') // 数组之间有一个-
                    this.firstName = arr[0]
                    this.lastName = arr[1]
                }  */
            }
     
        },
    })
</script>

</html>

计算属性简写

computed: {
    fullname:function(){//只考虑读取不考虑修改
	console.log('get被调用了')
	return this.firstName + '-' + this.lastName
	}
}

监视属性 watch

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./js/vue2.js"></script>
</head>

<body>

    <div id="app">

        <!-- <h2>今天天气很{{ishot ? '炎热' : '凉爽'}}</h2> -->
        <h2>今天天气很{{info}}</h2>
        <br>
        <button @click="gaiTian">切换天气</button> <br>
        提示: <h3>{{tip}}</h3>

    </div>

</body>

<script>
    const vm = new Vue({
        el: '#app',
        data: {
            ishot: true,
            tip: '多喝凉水',
        },
        computed: {
            info() {
                return this.ishot ? '炎热' : '凉爽'
            }
        },
        watch: {
            ishot: {
                immediate: true,//布尔值 初始化时是否执行函数
                handler() { //这里只能使用handler函数
                    console.log('ishot被修改了')
                }
            }
        },
        methods: {
            gaiTian() {
                if (this.ishot)
                    this.ishot = false; else this.ishot = true
            }
        },
    })
    // 另一种监视方法
/*     vm.$watch('ishot', {//,前写监视的对象 ,后写函数和配置 监视对象不存在时不会报错
        immediate: true,//布尔值 初始化时是否执行函数
        handler() { //这里只能使用handler函数
            console.log('ishot被修改了')
        }
    }) */
</script>

</html>

深度监视

Vue自身可以检测对象内部值的改变,但Vue提供的watch默认不可以 根据实际情况觉得是否开启watch的深度监视

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./js/vue2.js"></script>
</head>

<body>

    <div id="app">

        <!-- <h2>今天天气很{{ishot ? '炎热' : '凉爽'}}</h2> -->
        <h2>今天天气很{{info}}</h2>
        <br>
        <button @click="gaiTian">切换天气</button> <br>
        <button @click="numbers.a++">点我让a+1</button>
        <h3>a的值是{{numbers.a}}</h3> <br>
        <br>
        <button @click="numbers.b++">点我让b+1</button> <br>
        <h3>b的值是{{numbers.b}}</h3>

    </div>

</body>

<script>
    const vm = new Vue({
        el: '#app',
        data: {
            ishot: true,
            numbers: {
                a: 1,
                b: 2
            }
        },
        computed: {
            info() {
                return this.ishot ? '炎热' : '凉爽'
            }
        },
        watch: {
            ishot: {
                handler() { //这里只能使用handler函数
                    console.log('ishot被修改了')
                }
            },
            /*   //监视多层结构中某个属性的变化
              'numbers.a': {// 该写法是原始写法
                  handler() {
                      console.log('a改变了')
                  }
              } */
            //监视多级结构中所有属性的变化 不开器只有numbers中所有值发生改变函数才会生效
            numbers: {
                deep: true,
                handler() {
                    console.log('numbers的值改变了')
                }
            }
        },
        methods: {
            gaiTian() {
                if (this.ishot)
                    this.ishot = false; else this.ishot = true
            }
        },
    })
</script>

</html>

监视的简写

watch: {
    /*ishot: { //正常写法
            handler(newValue, oldValue) { //这里只能使用handler函数
                console.log('ishot被修改了', newValue, oldValue)
            }
        }, */
    ishot(newValue, oldValue) {
        console.log('ishot被修改了', newValue, oldValue)
    },

},

样式绑定

绑定class样式

<div id="app">
	<div class ="basic" :class="a">
    <!--最后上面这个div的class是"basic normal"-->
	</div>
	<!--添加多个样式"-->
    <div class ="basic" :class="addr">
    <!--最后上面这个div的class是"basic class1 class2 class3"-->
	</div>
</div>
<script>
    new Vue({
        el:'#app',
        data:{
            a:'normal',
            addr:['class1','class2','class3']
        },
        methods: {
            change:{
                
            }
        },
    })
</script>
Math.floor(Math.random()*3) //随机数 范围0-3
//floor 四舍五入向下取整
//Math.random()生成0-1的数 不包含1 *3代表生成0-3的数 不包括3 生成的是小数

绑定style样式

<body>
    <div id="app">
        <div class="" :style="{fontSize: fsize + 'px'}">{{name}}</div>
        <!--:style 表示等号后内容为表达式 上方代码可改变字体大小"-->
    </div>
</body>
<script>
    new Vue({
        el: '#app',
        data: {
            a: 'normal',
            name: 'miaolme',
            fsize: 40
        },
    })
</script>

另一种写法

<body>
    <div id="app">
        <div class="" :style="styleObj">{{name}}</div>
        <!--:style 表示等号后内容为表达式 上方代码可改变字体大小"-->
    </div>
</body>
<script>
    new Vue({
        el: '#app',
        data: {
            a: 'normal',
            name: 'miaolme',
            styleObj:{
                fontSize:'40px',
                backgroundColor: 'orange',
                color: 'red'
            }
        },
    })
</script>

数组写法

<body>
    <div id="app">
         <div class="" :style="[styleObj,styleObj2]">{{name}}</div>
        <!--:style 表示等号后内容为表达式 上方代码可改变字体大小"-->
    </div>
</body>
<script>
    new Vue({
        el: '#app',
        data: {
            a: 'normal',
            name: 'miaolme',
 		    styleObj: {
                fontSize: '40px',
                backgroundColor: 'orange',
                color: 'red'
            },
            styleObj2: {
                color: 'red'
            }
        },
    })
</script>

条件渲染

v-show 和 v-if

<body>
    <div id="app">
        <!-- v-show等号后写表达式 结果是布尔值
             v-if和v-show用法一样 -->
        <!-- <h2 v-show="false">欢迎学习vue{{name}}</h2> -->
        <!-- <h2 v-show="1===1">欢迎学习vue{{name}}</h2> -->
        <h2 v-if="false">欢迎学习vue{{name}}</h2>
    </div>
</body>
<script>
    new Vue({
        el: '#app',
        data: {
            name: 'miaolme'
        }
    })
</script>

v-else-if和v-else

用法和常规编程的else if用法相同

if执行后 else if的代码不执行

所有条件不满足,执行else里的代码

v-show适用于切换频率高的场景 v-if适用于切换频率低的场景

可以嵌套div使用

列表渲染

v-for

<body>
    <div id="app">
        <h2>人员列表</h2>
        <ul>
            <!-- 根据persons数组长度生成li -->
            <!-- key代表节点标识 -->
            <li v-for="ren in persons" :key="ren.id">
                <!-- in可以用of代替 -->
                {{ren.name}}-{{ren.age}} 
            </li>
        </ul>
    </div>

</body>
<script>
    new Vue({
        el: '#app',
        data: {
            persons: [
                { id: '001', name: '张三', age: 18 },
                { id: '002', name: '李四', age: 19 },
                { id: '003', name: '王五', age: 20 }
            ]
        }
    })
</script>
<body>
    <div id="app">
        <h2>人员列表</h2>
        <ul>
            <!-- 根据persons数组长度生成li -->
            <!-- key代表节点标识 -->
            <!-- index可以用其他词替换 是索引 可以拿到这个数据 -->
            <li v-for="(ren,index) in persons" :key="ren.id">
                <!-- in可以用of代替 -->
                {{ren.name}}-{{ren.age}}-{{index}}
            </li>
        </ul>
    </div>
</body>

v-for可以遍历其他数据

<body>
    <div id="app">
        <h2>人员列表</h2>
        <ul>
            <!-- 根据persons数组长度生成li -->
            <!-- key代表节点标识 -->
            <!-- index可以用其他词替换 是索引 可以拿到这个数据 -->
            <li v-for="(value,key) in neko" :key="key.id">
                {{key}}-{{value}}
                <!-- 类似键值对 -->
            </li>
        </ul>
    </div>

</body>
<script>
    new Vue({
        el: '#app',
        data: {
            neko: {
                mao: '粉毛',
                eye: '大眼',
                tile: '大尾巴'
            }
        }
    })
</script>

v-for可以遍历字符串

<body>
    <div id="app">
        <h2>人员列表</h2>
        <ul>
            <!-- 根据persons数组长度生成li -->
            <!-- key代表节点标识 -->
            <!-- index可以用其他词替换 是索引 可以拿到这个数据 -->
            <li v-for="(char,index) in str" :key="index.id">
                {{index}}-{{char}}
                <!-- 类似键值对 -->
            </li>
        </ul>
    </div>

</body>
<script>
    new Vue({
        el: '#app',
        data: {
            str: 'Hello'
        }
    })
</script>

用的少

v-for可以遍历指定次数

<body>
    <div id="app">
        <h2>人员列表</h2>
        <ul>
            <!-- 根据persons数组长度生成li -->
            <!-- key代表节点标识 -->
            <!-- index可以用其他词替换 是索引 可以拿到这个数据 -->
            <li v-for="(number,index) in 5" :key="index.id">
                {{number}}-{{index}}
                <!-- 类似键值对 -->
            </li>
        </ul>
    </div>

</body>
key的值必须唯一

列表功能

过滤

1 双向绑定

2 判断+改色

.indexOf() 该方法判断点前的数是否包含()内的字符

包含会给出在第几位,第一位是0,不包含返回-1

this.persons = this.persons.filter((p) => {
    return p.name.indexOf(val) !== -1
})
// filter 过滤方法 
数组.filter((变量) => {
    return 布尔值
})
//返回一个新数组

完整watch方法

<body>
    <div id="app">
        <div>
            <input type="text" placeholder="请输入名字" v-model="keyWord">
            <button>这是按钮</button>
            <ul>
                <li v-for="(p, index) in fillPersons" :key="p.id">
                    {{p.name}}-{{p.age}}-{{p.sex}}
                </li>
            </ul>
        </div>
    </div>
</body>
<script>
    new Vue({
        el: '#app',
        data: {
            persons: [
                { id: '001', name: '马冬梅', age: 19, sex: '女' },
                { id: '002', name: '周冬雨', age: 20, sex: '女' },
                { id: '003', name: '周杰伦', age: 21, sex: '男' },
                { id: '004', name: '温兆伦', age: 22, sex: '男' }
            ],
            keyWord: '',
            fillPersons: []
        },
        watch: {
            keyWord: {
                immediate: true,
                handler(val) {
                    this.fillPersons = this.persons.filter((p) => {
                        return p.name.indexOf(val) !== -1
                    })
                }
            }
        }
    })
</script>

</html>

用computed实现

<body>
    <div id="app">
        <div>
            <input type="text" placeholder="请输入名字" v-model="keyWord">
            <button>这是按钮</button>
            <ul>
                <li v-for="(p, index) in fillPersons" :key="p.id">
                    {{p.name}}-{{p.age}}-{{p.sex}}
                </li>
            </ul>
        </div>
    </div>
</body>
<script>
    new Vue({
        el: '#app',
        data: {
            persons: [
                { id: '001', name: '马冬梅', age: 19, sex: '女' },
                { id: '002', name: '周冬雨', age: 20, sex: '女' },
                { id: '003', name: '周杰伦', age: 21, sex: '男' },
                { id: '004', name: '温兆伦', age: 22, sex: '男' }
            ],
            keyWord: '',
        },
        computed: {
            fillPersons() {
                return this.fillPersons = this.persons.filter((p) => {
                    return p.name.indexOf(this.keyWord) !== -1
                })
            }

        },
    })
</script>

</html>

排序

vue的数据检测原理

懒得学

看这里:

033_尚硅谷Vue技术_更新时的一个问题_哔哩哔哩_bilibili

看到037

收集表单数据

v-model 默认双向绑定 value值

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./js/vue2.js"></script>
</head>

<body>
    <div id="app">
        <form @submit.prevent="demo">
            <!-- 点击按钮触发表单提交 prevent阻止默认行为  -->
            <!-- <label for="demo"> -->
            <!-- label 和id可以连接两个对象 -->
            <!-- 账号:<input type="text" id="demo"> -->
            <!-- </label> -->
            账号: <input type="text" v-model="account"> <br>
            密码: <input type="password" v-model="password"> <br>
            性别: <br>
            男<input type="radio" name="sex" value="male" v-model="sex">
            <!-- 通过name可以为radio单选框分组 -->
            女<input type="radio" name="sex" value="femal" v-model="sex">
            <br>
            爱好: <br>
            <!-- vue默认读取多选框 checked的布尔值 -->
            学习<input type="checkbox" v-model="hobby" value="study">
            打游戏<input type="checkbox" v-model="hobby" value="game">
            吃饭<input type="checkbox" v-model="hobby" value="eat"> <br>
            所属校区 <br>
            <select v-model="city">
                <option value="">请选择校区</option>
                <option value="beijing">北京</option>
                <option value="shenzhen">深圳</option>
                <option value="shanghai">上海</option>
                <option value="wuhan">武汉</option>
                <br>
            </select> <br>
            其他信息: <br>
            <textarea v-model="other"></textarea> <br>
            <input type="checkbox" v-model="agree"> 阅读并接收<a href="http://baidu.com">《用户协议》</a> <br>
            <button>提交信息</button>
        </form>
    </div>
</body>
<script>
    new Vue({
        el: "#app",
        data: {
            account: '',
            password: '',
            sex: 'femal',// 双向绑定 会默认选中性别
            hobby: [],//hobby所获得的多选框的值是个字符串
            city: '',
            other: '',
            agree: 'false',

        },
        methods: {
            demo() {
                alert(1)
            }
        },
    })
</script>

</html>

vue基础

过滤器

效果:显示格式化后的时间

现在是:2021-01-09

现在是:2021-01-09 22:53:47

意义不大,vue3移除

    <script src="./js/vue2.js"></script>
    <script src="./js/dayjs.min.js"></script>
</head>

<body>
    <!-- 准备好一个容器 -->
    <div id="root">
        <h2>显示格式化后的时间</h2>
        <h3>现在是{{fmtTime}}</h3>
    </div>
</body>
<script>
    new Vue({
        el: '#root',
        data: {
            time: 1621561377603 //时间戳
        },
        computed: {
            fmtTime() {
                return dayjs(this.time).format('YYYY-MM-DD HH:mm:ss')
            }
        }
    })
</script>

</html>

时间格式化可以借助第三方库实现

内置指令

学过的指令

v-bind : 单向绑定解析表达式,可简写为:xxx

v-model : 双向数据绑定

v-for : 遍历数组/对象/字符串

v-on : 绑定事件监听,可简写为@

v-if : 条件渲染(动态控制节点是否存在)

v-else : 条件渲染(动态控制节点是否存在)

v-show : 条件渲染(动态控制节点是否展示)

v-text指令

<body>
    <div id="app">
        <div>{{name}}</div> <br>
        <div v-text="name"></div> <!-- v-text会替换到整个div内容 -->
        <!-- v-text插入文本 会替换节点内容 插值语法不会 -->
    </div>
</body>
<script>
    new Vue({
        el: '#app',
        data: {
            name: '小猫'
        }
    })
</script>

v-html指令

用法:和v-text用法相同,但是可以解析带标签的字符串 如<h2>呵呵</h2>

<div v-html="name"></div>

安全性问题 用于输入可无视屏蔽插入危险html语句

v-cloak指令

用在标签中,在vue挂载后,标签会消失

可单独设置样式 本质是一个id 可以设置携带改id的内容不显示 diskplay,可以防止因网速过慢导致vue未加载产生{{}}内容

v-once指令

1.v-once所在节点在初次动态渲染后,就视为静态内容了。 2.以后数据的改变不会引起v-once所在结构的更新,可以用于优化性能。

标签加入改内容 {{}}内代表的内容只会显示初始值

v-pre指令

1.v-prt.除过其所在节点的编译过程。 2.可利用它跳过:没有使用指令语法、没有使用插值语法的节点,会加快编译

自定义指令

目前用不到

生命周期

原理图

生命周期

下方所有字段都和vue中的data:{}平级

  new Vue({
        el: '#app',
        data: {
            name: '小猫'
        }
 })

mounted

mounted(){
	// 此函数内的代码只会在vue挂载完后执行
    // 可以在内部添加定时器函数等用于初始化的代码
}

template

用法1:不换行

template:'<h2>当前的n值是:{{n}}/h2><button@click="add">点我n+1</button>'

用法2:换行

template:`<h2>当前的n值是:{{n}}/h2>
<button@click="add">点我n+1</button>`

作用,替换容器内容即 <div id="app">内的所有内容

<div id="app">
    <div>{{name}}</div> <br>
    <div v-text="name"></div> <!-- v-text会替换到整个div内容 -->
    <!-- v-text插入文本 会替换节点内容 插值语法不会 -->
</div>

vue中使用template会覆盖原有容器所有内容。

模板可为空,但是必须包含template(根节点)

beforeUpdate

更新流程前的函数

beforeUpdate(){
	// 写在内部的函数会在vue的值即将发生更新前执行
}

update

update(){
	// 写在内部的函数会在vue的值发生更新后执行
}

beforeDestory

beforeDestory(){
	// 写在内部的函数会在vue即将销毁前执行
	// 主要用来写各项服务的终止函数,例如定时器函数的结束等
	//一般在此阶段:关闭定时器、取消订阅消息,解绑自定义事件等收尾操作
}

非单文件组件

基本案例

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./js/vue2.js"></script>
</head>

<body>
    <!-- 定义容器 -->
    <div id="app">
        <h1>{{msg}}</h1>
        <hr>
        <school />
    </div>
</body>
<script>
    //定义组件
    const school = Vue.extend({
        template: `
        <div>
            <h2>我的学校:{{name}}</h2>
            <h2>地址:{{address}}</h2>
        </div>`,
        data() {
            return {
                name: '喵校',
                address: '喵娘乐园'
            }
        }
    })

    new Vue({
        el: '#app',
        data: {
            msg: '你好Vue!'
        },
        //注册组件 (局部)
        components: {
            school: school //调用<school/>标签来使用 标签的内容由:左侧决定
        }
    })
</script>

</html>

全局注册组件

//全局注册组件
Vue.component('使用标签名',定义的组件名)

全局注册例子

Vue.component('xuexiao',school)
//使用<xuexiao/>即可调用改组件
const school = Vue.extend({
        template: `
        <div>
            <h2>我的学校:{{name}}</h2>
            <h2>地址:{{address}}</h2>
        </div>`,
        data() {
            return {
                name: '喵校',
                address: '喵娘乐园'
            }
        }
    })

局部注册和全局注册的区别

局部注册的组件只能在其所规定的容器可用,全局注册的组件可用在任意的容器中调用组件。

组件可套娃

但是执行顺序必须自上而下,否则报错

构造函数

057_尚硅谷Vue技术_VueComponent构造函数_哔哩哔哩_bilibili

先跳过,以后学

脚手架

安装脚手架

  1. 安装node.js
  2. 配置 淘宝源
npm config set registry=http://registry.npm.taobao.org
  1. 全局安装脚手架
npm install -g @vue/cli

创建脚手架文件

vue create 文件名 #(自己自定义)最好不要出现中文,可能会出错

单文件组件

文件后缀.vue

起名规范

school.vue my-school.vue

School.vue MySchool.vue

结构

<template>
	<!--组件的结构 -->
</template>

<script>
    //组件交互相关代码(数据、方法等)
</script>

<style>
    /*组件的样式*/
</style>

例子

<template>
  <div class="demo">
     <h2>我的学校:{{name}}</h2>
     <h2>地址:{{address}}</h2>
  </div>
</template>

<script>
    const school = Vue.extend({
        data() {
            return {
                name: '喵校',
                address: '喵娘乐园'
            }
        }
    })
</script>

<style>
    .demo{
        background-color: pink;
    }
</style>

暴露方法

类似public 公开访问方法 共3种

<script>
  	export const school = Vue.extend({ //分别暴露
        data() {
            return {
                name: '喵校',
                address: '喵娘乐园'
            }
        }
    })
</script>
<script>
    const school = Vue.extend({
        data() {
            return {
                name: '喵校',
                address: '喵娘乐园'
            }
        }
    })
    export default school //默认暴露 常用
</script>

<script>
/*或者*/
export default {
    name:'school',
    data() {
        return {
            name: '喵校',
            address: '喵娘乐园'
        }
    }
}
</script>
<script>
    const school = Vue.extend({
        data() {
            return {
                name: '喵校',
                address: '喵娘乐园'
            }
        }
    })
    export {school} //统一暴露
</script>

App.vue 汇总组件

<template lang="">
    <div>
        <school></school>
    </div>
</template>
<script>
//引入组件
import school from 'vue1/school'

export default {
    name: 'App',
    components: {
        school: school
    }
}
</script>
<style lang="">
    
</style>

vm main.js

import App from 'vue1/App'

new Vue({
    template:'<App></App>',
    el:'#root',
    components:{App}
    
})

入口文件 index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="root">
    </div>
    <script src="../js/vue2.js"></script>
    <script src="./main.js"></script>
</body>
</html>

常用属性

render函数

main.js

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App), // h可替换成其他内容 下方是例子
  //render: test => test(App), 同样的,App代表组件 也可以替换为模板结构
  //render: test => test('h1','hello') 类似于template效果 不常用
}).$mount('#app') // 这个相当于 el:'#app'

ref元素

作用: 类似于id选择器 用于获取组件的vm对象或者是某个元素的对象

例子:

<h1 ref="sch">你好vue!</h1>
console.log(this.$refs.sch)

ref属性

被用来给元素或子组件注册引用信息(id的替代者) 被应用在html标签上获取的是真实dom元素,应用在组件上是组件实例对象(vc)

props配置

用法:

props:['name','address','age']

用在script中与data平级

不能与data中值相同.用于外部数据传入.

可以通过内部写函数来控制传入的数值.

num+(){
	this.age++ //需要用到this 
}

mixin混入

例子

mixin.js

// 分别暴露
export const mixin = {
    methods: {
        showName() {
            alert(this.name)
        }
    },
}

MyStudent.vue

<template>
    <div>
        <h3 @click="showName">姓名:{{ name }}</h3>
        <h3>地址:{{ address }}</h3>
        <h3>年龄:{{ age }}</h3>
    </div>
</template>
<script>
//引入 混合 mixin
import { mixin } from '../mixin'
export default {
    name: 'MyStudent',
    data() {
        return {
            name: '喵喵',
            address: '樱花校园',
            age: '18'
        }
    },
    //启用混合 会自动根据结构判断 进行调用自定义的mixin中的方法
    mixins: [mixin],
    methods: {
    }

}
</script>

组件内的方法代码执行优先

mounted函数都会执行。 mixin中的代码优先执行

全局混合

只需要修改main.js

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false
//引入混合
import { mixin } from './mixin'
//应用混合
Vue.mixin(mixin)
new Vue({
  render: h => h(App),
}).$mount('#app')

作用域限制和插件

作用域限制

scoped

用于style中

<style scoped>
	.title{
		color: red;
	}
</style>

作用:限制style内的样式仅在当前组件生效。

vue内的样式会覆盖组件的同名样式

插件

使用方法script.js

定义插件

export default { //默认暴露
    install(Vue,x,y){ //可接收传入值x,y
        //全局过滤器
        Vue.filter('mySlice',function(value){...})
   
        //定义全局指令
        Vue.directive('fbind',{...})  
                               
    	//定义全局混入
        Vue.mixin({...})                       
   }
    //给vue原型添加方法              
    Vue.prototype.hello   = ()=>{alert('你好vue')}       
}

应用插件在App.vue

<script>
    	//引入插件
    	import plugins from './plugins'
    	//使用插件
    	Vue.use(plugins)
</script>

组件信息交互

全局事件总线

没学 084_尚硅谷Vue技术_全局事件总线1_哔哩哔哩_bilibili

消息订阅与发布

1 订阅消息 2 发布消息

安装第三方库

npm install [email protected]

引入 school.vue

<script>
    import pubsub from 'pubsub-js'
    //定义
    mounted(){ //不写箭头函数需要把执行函数定义在methods中
        this.pubId = pubsub.subscribe('hello',(msgName,data)=>{ //订阅消息
            console.log(this) //hello是消息名
        })
    }
    //取消订阅
    beforeDestory(){
        pubsub.unsubscribe(this.pubId)
    }
</script>

另一种方式

<script>
    import pubsub from 'pubsub-js'
    methods(){
        demo(data){...}
    }
    mounted(){ //不写箭头函数需要把执行函数定义在methods中
       this.pubId = pubsub.subscribe('hello',this.demo) //订阅消息
        //检测到 hello为事件名发布消息时会执行回调函数
    }
    //取消订阅
    beforeDestory(){
        pubsub.unsubscribe(this.pubId)
    }
</script>

发布消息

<script>
    import pubsub from 'pubsub-js'
    methods(){
        sendStudentName(){
        	pubsub.publish('hello',666) //调用方法后会创建一个名为hello的消息,数据是666
        }
    }
</script>

methods: $nextTick

this.$nextTick(function(){
    //会在dom节点更新完毕后执行 vue模板编译完成后执行
    this.$refs.inputTitle.focus()//自动获取焦点
})
setTimeout(){
	this.$refs.inputTitle.focus()//自动获取焦点
    //定时器函数会在vue模板编译完成后执行
}

过度与动画

vue动画

<template>
    <div>
        <!--isShow = !isShow代表按钮切换isShow的true和false-->
        <Button @click="isShow = !isShow">显示/隐藏</Button>
        <transition name="v" appear>
            <!-- :appear="true" 等同于appear 加上后会在刷新后播放动画  -->
            <!-- 过渡标签 设置好后自动播放来去的动画 -->
            <h1 v-show="isShow">你好啊!</h1>
        </transition>

    </div>
</template>
<script>
export default {
    name: 'MyTest',
    data() {
        return {
            isShow: true
        }
    }
}
</script>
<style scoped>
h1 {
    background-color: pink;
}

/*come和够为需要的元素添加class就可以播放设定的动画*/
.come {
    /*来时动画*/
    animation: dongHua 1s;
}

.go {
    /*走时动画*/
    animation: dongHua 1s reverse;
    /*reverse反转*/
}

/*过度动画标签类型 v是动画的name*/
.v-enter-active {
    /*来时动画*/
    animation: dongHua 1s;
}

.v-leave-active {
    /*走时动画*/
    animation: dongHua 1s reverse;
    /*reverse反转*/
}


@keyframes dongHua {

    /*定义动画关键帧 和动画名*/
    from {
        transform: translateX(-100%);
        /*单位是px*/
    }

    to {
        transform: translateX(0px);
    }
}
</style>

vue过度

例子

<div>
    <!--isShow = !isShow代表按钮切换isShow的true和false-->
    <Button @click="isShow = !isShow">显示/隐藏</Button>
    <transition-group name="v">
        <!-- :appear="true" 等同于appear 加上后会在刷新后播放动画  -->
        <!-- 过渡标签 设置好后自动播放来去的动画 -->
        <h1 v-show="isShow" key="1">你好啊!</h1>
        <h1 v-show="isShow" key="2">Vue</h1>
    </transition-group>
</div>

group中的所有元素必须有唯一的key值

name用于区分不同类型动画

集成第三方动画

animate.css - 第三方动画 (npmjs.com)

安装:

需要cmd进入在所需项目内执行

npm install animate.css --save

Animate.css 开发文档

引入

<script>
	import 'animate.css';
</script>

例子

<template>
    <div>
        <!--isShow = !isShow代表按钮切换isShow的true和false-->
        <Button @click="isShow = !isShow">显示/隐藏</Button>
        <transition-group
         name="animate__animated animate__bounce" 
         appear 
         enter-active-class="animate__rubberBand"
         leave-active-class="animate__bounceOut">
            <!-- :appear="true" 等同于appear 加上后会在刷新后播放动画  -->
            <!-- 过渡标签 设置好后自动播放来去的动画 -->
            <h1 v-show="isShow" key="1">你好啊!</h1>
            <h1 v-show="isShow" key="2">Vue</h1>
        </transition-group>
    </div>
</template>
<script>
//引入动画css
import 'animate.css'
export default {
    name: 'MyTest2',
    data() {
        return {
            isShow: true
        }
    }
}
</script>
<style scoped>
h1 {
    background-color: pink;
}
</style>

enter-active-class=“”leave-active-class=“”

“”内需要填入动画库所需动画的名称。 name=“”必须填入 animate__animated animate__bounce 不同动画库的要求略有差别

group中的所有元素必须有唯一的key值

插槽

默认插槽

使用方法:

  1. 组件写双标签
  2. 标签内填组件里额外需添加的元素
  3. 在组件中用slot双标签标记所放置位置

slot标签内写的内容会在组件双标签内的内容为空时展示

viedo想播放必须添加controls标签才能播放

具名插槽

使用:

  1. 组件双标签内写 solt="定义的name名称"
  2. solt标签中添加 name=“自定义名称”属性

不同元素使用相同的solt名字不会发生覆盖,会自动追加

另一种写法

使用<template>双标签包裹,类似于div但是不会产生dom结构 使用该标签包裹后可以用 v-solt:自定义名称来定义dom生成位置

作用域插槽

104_尚硅谷Vue技术_作用域插槽_哔哩哔哩_bilibili

因为感觉没啥用,先不学了

Vuex

理解vuex

原理图

vuex

vuex 是什么

1.概念:专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中 多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适 用于任意组件间通信。 2.Github地址: https://github.com/vuejs/vuexe

什么时候使用Vuex

1.多个组件依赖于同一状态 2.来自不同组件的行为需要变更同一状态

安装vuex

npm i vuex@3

动态路由

路由基本使用

  1. 需安装vue-router3
npm i vue-router@3

插件库

使用方法

main.js

import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'

//关闭Vuee生产提示
Vue.config.productionTip = false
//应用插件
Vue.use(VueRouter)
new Vue({
  render: h => h(App),
}).$mount('#app')

创建路由

router/index.js

// 改文件用于创建整个应用的路由器
import VueRouter from "vue-router";

//引入组件
import MyHome from "../comments/home"
import MyAbout from "../comments/about"

// 创建一个路由器并暴露在外部
export default new VueRouter({
    routes: [
        {
            path: '/about',
            component: MyAbout
        },
        {
            path: '/home',
            component: MyHome
        }
    ]
})

引入路由器

main.js

import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
//引入路由器
import router from './router'
//关闭Vuee生产提示
Vue.config.productionTip = false
//应用插件
Vue.use(VueRouter)
new Vue({
  render: h => h(App),
  router: router //引入路由
}).$mount('#app')

调整App.vue

<template>

  <div>
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <div class="page-header">
          <h2>Vue Router Demo</h2>
        </div>
      </div>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <!-- 原始html中我们使用a标签实现页面的跳转 -->
          <!-- <a class="list-group-item active" href="./about.html">About</a>
          <a class="list-group-item" href="./home.html">Home</a> -->

          <!-- 路由跳转 router-link 和 to 标签 最终转成a标签 active-class 元素激活时的样式-->
          <router-link class="list-group-item" active-class="active" to="/about">About</router-link>
          <router-link class="list-group-item" active-class="active" to="/home">Home</router-link>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
            <!-- 此处到底展示什么组件,得看用户点击的是哪个导航项 -->
            <!-- 指定组件的呈现位置 -->
            <router-view></router-view>
          </div>
        </div>
      </div>
    </div>
  </div>

</template>

<script>
export default {
  name: 'App',
  data() {
    return {

    }
  },
  components: {

  }
}
</script>

<style>

</style>

建议把路由组件放在单独的文件夹中

嵌套(多级)路由

router/index.js

// 改文件用于创建整个应用的路由器
import VueRouter from "vue-router";

//引入组件
import MyHome from "../comments/home"
import MyAbout from "../comments/about"
import MyNews from "../comments/news"
import MyMessage from "../comments/message"
// 创建一个路由器并暴露在外部
export default new VueRouter({
    routes: [
        {
            path: '/about',
            component: MyAbout
        },
        {
            path: '/home',
            component: MyHome,
            //二级路由
            children: [
                {
                    path: 'news',
                    component: MyNews
                },
                {
                    path: 'message',
                    component: MyMessage
                }
            ]
        }
    ]
})

home.vue

<template>
    <div>
        <h2>Home组件内容</h2>
        <div>
            <ul class="nav nav-tabs">
                <li>
                    <router-link class="list-group-item" active-class="active" to="/home/news">News</router-link>
                </li>
                <li>
                    <router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link>
                </li>
            </ul>
            <router-view></router-view>
        </div>
    </div>
</template>
<script>
export default {
    name: 'MyHome'
}
</script>
<style>

</style>

路由传参

query参数

可以通过to后写?…传递参数

跳转路由并携带query参数,to的字符串写法

<router-link class="list-group-item" active-class="active" to="/home/message?id=666&title=你好啊!">Message</router-link>

取参数

{{$route.query.id}} //666
{{$route.query.title}} //你好啊!

使用v-if可以插入指定内容

<li v-for="m in messageList" :key="m.id">
	<router-link class="list-group-item" active-class="active" :to="`/home/message?id=${m.id}&title=${m.title}`">Message</router-link>
</li>

跳转路由并携带query参数,to的对象写法

<li v-for="m in messageList" :key="m.id">
	<router-link :to="{
		path:'/home/message/detail',
		query:{
			id:m.id,
			title:m.title
		}
	}"
</li>

命名路由

添加方法 router/index.js

// 改文件用于创建整个应用的路由器
import VueRouter from "vue-router";

//引入组件
import MyHome from "../comments/home"
import MyAbout from "../comments/about"
import MyNews from "../comments/news"
import MyMessage from "../comments/message"
// 创建一个路由器并暴露在外部
export default new VueRouter({
    routes: [
        {
            name:'guanyu', //给谁起名就在哪里填写name:
            path: '/about',
            component: MyAbout
        },
        {
            path: '/home',
            component: MyHome,
            //二级路由
            children: [
                {
                    path: 'news',
                    component: MyNews
                },
                {
                    name:'xiangqing', //给谁起名就在哪里填写name:
                    path: 'message',
                    component: MyMessage
                }
            ]
        }
    ]
})

可以简化操作

仅支持下列两种

<li v-for="m in messageList" :key="m.id">
	<router-link :to="{
		name:'xiangqing',
		query:{
			id:m.id,
			title:m.title
		}
	}"
</li>
 <router-link class="list-group-item" active-class="active" :to="{name:'guanyu'}">关于</router-link>

params参数

配置路由

// 改文件用于创建整个应用的路由器
import VueRouter from "vue-router";

//引入组件
import MyHome from "../comments/home"
import MyAbout from "../comments/about"
import MyNews from "../comments/news"
import MyMessage from "../comments/message"
import MyDetail from "../comments/detail"
// 创建一个路由器并暴露在外部
export default new VueRouter({
    routes: [
        {
            name:'guanyu', //给谁起名就在哪里填写name:
            path: '/about',
            component: MyAbout
        },
        {
            path: '/home',
            component: MyHome,
            //二级路由
            children: [
                {
                    path: 'news',
                    component: MyNews
                },
                {
                    name:'xiangqing', //给谁起名就在哪里填写name:
                    path: 'message',
                    component: MyMessage,
                    children:{
                        {
                        	name:'xiangqing',
                        	path:'detail/:id/:title'
                        	component: MyDetail,
                    }
                    }
                }
            ]
        }
    ]
})

携带方式1

<li v-for="m in messageList" :key="m.id">
	<router-link class="list-group-item" active-class="active" :to="`/home/message/detail/${m.id}/${m.title}`">Message</router-link>
</li>

携带方式2

不可使用path

<li v-for="m in messageList" :key="m.id">
	<router-link :to="{
		name:'xiangqing',
		params:{
			id:m.id,
			title:m.title
		}
	}"
</li>

路由的props配置

配套的Detail组件

<template>
    <ul>
        <li>消息编号:{{ id }}</li>
        <li>消息标题:{{ title }}</li>
    </ul>
</template>
<script>
export default {
    name: 'Detail',
    props: ['id', 'title']
}
</script>
<style>

</style>

第二种写法

// 改文件用于创建整个应用的路由器
import VueRouter from "vue-router";

//引入组件
import MyHome from "../comments/home"
import MyAbout from "../comments/about"
import MyNews from "../comments/news"
import MyMessage from "../comments/message"
// 创建一个路由器并暴露在外部
export default new VueRouter({
    routes: [
        {
            path: '/about',
            component: MyAbout
        },
        {
            path: '/home',
            component: MyHome,
            //二级路由
            children: [
                {
                    path: 'news',
                    component: MyNews
                },
                {
                    path: 'message',
                    component: MyMessage,

                    //props的第二种写法,值为布尔值,若布尔值为真,就会把该路由组件收到的所有params参数
                    //,以props的形式传给Detail组件
                    props:true
                }
            ]
        }
    ]
})

另一种写法

// 改文件用于创建整个应用的路由器
import VueRouter from "vue-router";

//引入组件
import MyHome from "../comments/home"
import MyAbout from "../comments/about"
import MyNews from "../comments/news"
import MyMessage from "../comments/message"
// 创建一个路由器并暴露在外部
export default new VueRouter({
    routes: [
        {
            path: '/about',
            component: MyAbout
        },
        {
            path: '/home',
            component: MyHome,
            //二级路由
            children: [
                {
                    path: 'news',
                    component: MyNews
                },
                {
                    path: 'message',
                    component: MyMessage,

                    //props的第三种写法,值为函数
                    //1.
                    /*props({ query: { id, title } }) {
                        return { id, title }
                    } */
                    //2.
                    /*                     props({ query }) {
                                            return { id: query.id, title: query.title }
                                        } */
                    //3.
                    props($route) {
                        return {
                            id: $route.query.id,
                            title: $route.query.title
                        }
                    }

                }
            ]
        }
    ]
})

配套教程

编程式路由导航

push查看

按钮传递参数

<button> @click="pushShow(m)"push查看</button>

按钮绑定点击事件对应的函数

pushShow(m){ //m 是接收的参数
    this.$router.push({
        name:'xiangqing',
		query:{
			id:m.id,
			title:m.title
		}
    })
}

replace查看

按钮传递参数

<button> @click="replaceShow(m)"push查看</button>

按钮绑定点击事件对应的函数

replaceShow(m){ //m 是接收的参数
    this.$router.replace({
        name:'xiangqing',
		query:{
			id:m.id,
			title:m.title
		}
    })
}

区别:

  1. push查看浏览器可以回退,有历史记录
  2. replace查看浏览器的记录会被覆盖,无法正常回退

前进和后退

按钮绑定下列对应函数就能实现前进和后退

back(){ //后退
	this.$router.back()
}
forward(){ //前进
	this.$router.forward()
}
test(){
	this.$router.go() // ()内为正数前进对应步数,填写负数则后退对应的步数.
}

缓存路由

作用:可以防止在切换路由组件时导致填写的对应数据丢失.

<keep-alive include="组件名">
    <router-view></router-view>
</keep-alive>

include 填写的是要缓存的组件名,如果不填写则默认缓存所有的路由导航。

<!--缓存多个路由组件-->
<keep-alive :include = "['News','Message']">
    <router-view></router-view>    
</keep-alive>

新的生命周期钩子

例子:闪烁文本 (透明度随时间变化的文本)

路由组件独有

写在组件里

activated(){
	//切入组件时激活
},
deactivated(){
    //切走组件时激活
}

路由守卫

要求:每个路由都要有一个名字

全局前置路由守卫

// 改文件用于创建整个应用的路由器
import VueRouter from "vue-router";

//引入组件
import MyHome from "../comments/home"
import MyAbout from "../comments/about"

// 创建一个路由器并暴露在外部
const router = new VueRouter({
    routes: [
        {
            name: 'miao',
            path: '/about',
            component: MyAbout
        },
        {
            name: 'cao',
            path: '/home',
            component: MyHome,
        }
    ]
})

//全局前置路由守卫
router.beforeEach((to, from, next) => { //传入参数包含路由信息
    //在每次切换路由前调用,初始化时调用
    // to 去处(目标路由); from 来处(目前所处路由); next 放行

    //判断前往的路由路径是否为下方两个 是 则放行
    if (to.path === '/home/news' || to.path === '/home/message') {
        //判断本地存储中的school(key)的值是否是(ying) 如果是 则放行
        if (localStorage.getItem('school') === 'ying') {
            next() 
        }
    }else{
        alert('无权限访问') //不符合上述条件 提示无权限访问
    }

})

//暴露路由
export default router

meta:{}可以传入自定义参数(路由源信息)

// 改文件用于创建整个应用的路由器
import VueRouter from "vue-router";

//引入组件
import MyHome from "../comments/home"
import MyAbout from "../comments/about"

// 创建一个路由器并暴露在外部
const router = new VueRouter({
    routes: [
        {
            name: 'miao',
            path: '/about',
            component: MyAbout,
            meta: { pass: 'true' },//权限表示符 来确定是否进行权限校验
        },
        {
            name: 'cao',
            path: '/home',
            component: MyHome,
            meta: { pass: 'false' }, //false 按照下方的规则无法通过校验
        }
    ]
})

//全局前置路由守卫
router.beforeEach((to, from, next) => { //传入参数包含路由信息
    //在每次切换路由前调用,初始化时调用
    // to 去处(目标路由); from 来处(目前所处路由); next 放行

    //判断前往的路由路径是否为下方两个 是 则放行
    if (to.meta.pass) {
        next()
    } else {
        alert('无权限访问') //不符合上述条件 提示无权限访问
    }

})

//暴露路由
export default router

全局后置路由守卫

// 改文件用于创建整个应用的路由器
import VueRouter from "vue-router";

//引入组件
import MyHome from "../comments/home"
import MyAbout from "../comments/about"

// 创建一个路由器并暴露在外部
const router = new VueRouter({
    routes: [
        {
            name: 'miao',
            path: '/about',
            component: MyAbout,
            meta: { pass: 'true',title:'关于' },
        },
        {
            name: 'cao',
            path: '/home',
            component: MyHome,
            meta: { pass: 'false',title:'主页' },
        }
    ]
})

//全局前置路由守卫
router.beforeEach((to, from, next) => { //传入参数包含路由信息
    //在每次切换路由前调用,初始化时调用
    // to 去处(目标路由); from 来处(目前所处路由); next 放行

    //判断前往的路由路径是否为下方两个 是 则放行
    if (to.meta.pass) {
        next()
    } else {
        alert('无权限访问') //不符合上述条件 提示无权限访问
    }

})
//全局后置路由守卫
router.afterEach((to,from,next)=>{
    //在每次切换路由后调用,初始化时调用
    //主要用于修改跳转后的页面标题
    document.title = to.meta.title || '喵喵系统'
    
})
//暴露路由
export default router

独享路由守卫

// 改文件用于创建整个应用的路由器
import VueRouter from "vue-router";

//引入组件
import MyHome from "../comments/home"
import MyAbout from "../comments/about"

// 创建一个路由器并暴露在外部
const router = new VueRouter({
    routes: [
        {
            name: 'miao',
            path: '/about',
            component: MyAbout,
            meta: { pass: 'true', title: '关于' },
        },
        {
            name: 'cao',
            path: '/home',
            component: MyHome,
            meta: { pass: 'false', title: '主页' },
            beforeEnter: (to, from, next) => {
                //用法和全局路由守卫相同,仅在进入该组件前调用
            }
        }

    ]
})

//全局后置路由守卫
router.afterEach((to,from,next)=>{
    //在每次切换路由后调用,初始化时调用
    //主要用于修改跳转后的页面标题
    document.title = to.meta.title || '喵喵系统'
    
})

//暴露路由
export default router

只有前置没有独享后置路由守卫 路由守卫可自行按需搭配

组件内路由守卫

<template>
    <ul>
        <li>消息编号:{{ id }}</li>
        <li>消息标题:{{ title }}</li>
    </ul>
</template>
<script>
import { title } from 'process';

export default {
    name: 'Detail',
    props: ['id', 'title'],
    //通过路由规则,进入该组件时被调用
    beforeRouteEnter: () => {
        
    },
    //通过路由规则,离开该组件时被调用
    beforeRouteLeave: () => {

    }
}

</script>
<style>

</style>

路由工作模式

  1. hash模式 携带# 兼容好
  2. history模式 不携带#

更换模式方法

// 改文件用于创建整个应用的路由器
import VueRouter from "vue-router";

//引入组件
import MyHome from "../comments/home"
import MyAbout from "../comments/about"

// 创建一个路由器并暴露在外部
const router = new VueRouter({
  //mode: 'history',
    mode: 'hash',
    routes: [
        {
            name: 'miao',
            path: '/about',
            component: MyAbout,
            meta: { pass: 'true', title: '关于' },
        },
        {
            name: 'cao',
            path: '/home',
            component: MyHome,
            meta: { pass: 'false', title: '主页' },
            beforeEnter: (to, from, next) => {
                //用法和全局路由守卫相同,仅在进入该组件前调用
            }
        }

    ]
})

//全局后置路由守卫
router.afterEach((to,from,next)=>{
    //在每次切换路由后调用,初始化时调用
    //主要用于修改跳转后的页面标题
    document.title = to.meta.title || '喵喵系统'
    
})

//暴露路由
export default router
nekopara
我是一个全栈网络工程师,对一切新鲜事物充满好奇,希望我的文章能给你带来思考和帮助
👋我是nekopara
分享作者『nekopara』发表的文章『vue2快速入门』https://blog.cmao.me/post/20230603a/
© 请您在需要时著名本文内容来源信息,若在文末注明“参考、扩展”等字样涉及转载第三方内容,请您一同复制
clash
clash
linux下安装并使用clash
游戏开发目录结构推荐
游戏开发目录结构推荐
游戏开发目录结构推荐