vue基础语法

1、插值语法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>插值语法</title>
    <script src="../vu/js/vue.js"></script>
</head>
<body>

<!--插值语法示例-->
<div id="insertValue">
    <p>插值语法</p>
    <hr>
    <p>{{str}}</p>
    <p>这是一个数字插值: {{num}}</p>
    <p>这是一个数组插值语法根据索引取值:{{arr[0]}}</p>
    <p>这是一个对象插值:{{obj.c}}</p>
</div>
</body>
<script>
    var insertValue = new Vue({
        el: "#insertValue", // /根据id找到div,这个div就是被vue托管
        data: {
            str: "这是一个插值字符串",
            num: 10,
            arr: ['A', 'B', 'C'],
            obj: {c: 100, d: 200},
        }
    })
</script>
</html>

2、v-html和v-text示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-html和v-text</title>
    <script src="../vu/js/vue.js"></script>
    <style>
        .box1{
            width: 150px;
            height: 150px;
            background-color: red;
            text-align: center;
            line-height: 150px;
        }

        .box2{
            width: 200px;
            height: 200px;
            background-color: blue;
            text-align: center;
            line-height: 200px;
        }
    </style>
</head>
<body>
<!--v-html和v-text示例-->
<div id="htmlText">
    <hr>
    <p>文本指令</p>
    <hr>
    <!--将v-html:htmlText功能里面的data html变量里面的input渲染成html标签语法-->
    <h3>v-html指令</h3>
    <p v-html="html"></p>
    <h3>v-text指令</h3>
    <!-- v-text渲染成字符串, 如果p标签里面有内容v-text会把<p>测试</p>内容替换-->
    <p v-text="content">这是老而v-text</p>
    <hr>
    <h3>v-show和v-if指令</h3>
    <!-- v-show:如果是false 对内容或设置的样式不进行显示,但是标签存在,会将标签样式设置为display: none  -->
    <!-- v-if:如果是false 对内容或设置的样式不进行显示,但是标签不存在(注:删除和添加标签,效率低)  -->
    <div class="box1" v-show="b1">v-show-class-box1</div>
    <p>v-if指令</p>
    <div class="box2" v-if="b2">v-show-class-box2</div>
</div>
</body>
<script>
    var htmlText = new Vue({
        el: "#htmlText",
        data: {
            html: '<input type="text">',
            content: '新的v-text指令',
            b1: false,
            b2: true,
        }
    })
</script>
</html>

3、点击事件on-click和v-bind

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>on-click和v-bind</title>
    <script src="../vu/js/vue.js"></script>
</head>
<body>
<!--点击事件on-click(注:@click)和v-bind示例-->
<div id="onBind">
    <hr>
    <h3>这个是v-on:</h3>
    <button v-on:click="handledClick">点击显示alert</button>
    <!--v-on:click="handledClick" 可以写 @click="handledClick"-->
    <button @click="handledClick">点击</button>
    <hr>
    <h3>v-bind</h3>
    <img v-bind:src="url" alt="">
    <hr>
    <h3>结合点击事件click和bind图片进行切换</h3>
    <img v-bind:src="url" alt="" @click="imgClick">
</div>
</body>
<script>
    var onBind = new Vue({
        el: "#onBind",
        data:{
            url: 'http://gips2.baidu.com/it/u=195724436,3554684702&fm=3028&app=3028&f=JPEG&fmt=auto?w=1280&h=960',
            url_list: [
                "http://gips0.baidu.com/it/u=2298867753,3464105574&fm=3028&app=3028&f=JPEG&fmt=auto?w=960&h=1280",
                "http://gips1.baidu.com/it/u=1410005327,4082018016&fm=3028&app=3028&f=JPEG&fmt=auto?w=960&h=1280",
                "http://gips2.baidu.com/it/u=1192674964,3939660937&fm=3028&app=3028&f=JPEG&fmt=auto?w=1280&h=960",
            ]
        },
        methods:{
            handledClick(){
                alert("这个是点击显示alert内容")
            },
            imgClick(){
                this.url=this.url_list[Math.floor(Math.random()*3)]
            }
        }
    })
</script>
</html>

4、style和class指令绑定css样式

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>style和class指令绑定css样式</title>
    <script src="../vu/js/vue.js"></script>
    <style>
        .font{
            font-size: 20px;
        }

        .back{
            background-color: orange;
        }

        .color{
            color: blue;
        }
    </style>
</head>
<body>
<h3>style和class指令绑定css样式示例</h3>
<div id="styleClass">
    <hr>
    <div>
        <h3>:class指定绑定css样式</h3>
        <p :class="fontSize">字符绑定class指令 css类class字体大小</p>
        <p :class="arrClass">数组绑定class指令,css类class 字体大小,字体颜色,背景色</p>
        <p :class="objClass">对象绑定class指令,css类class 字体大小,字体颜色</p>
    </div>
    <hr>
    <div>
        <h3>:style指定绑定style属性css样式</h3>
        <p :style="styleStr">字符串绑定style指定实现style属性css样式字体大小,字体颜色</p>
        <p :style="styleList">数组绑定style指令实现style属性css样式字体颜色,背景色</p>
        <p :style="styleObj">数组绑定style指令实现style属性css样式字体颜色,字体大小,背景色</p>
    </div>
</div>

</body>
<script>
    var styleClass = new Vue({
        el: '#styleClass',
        data: {
            // 1-1 class指令绑定css样式
            // 字符串方式
            fontSize: '',
            // 推荐使用数据组进行css class类样式设置
            arrClass: ['font', 'color', 'back'],
            // 对象方式绑定class类样式。注:font, color, back代表css样式类,true代表使用此类,false代表不使用
            objClass: {
                font: true,
                color: true,
                back: false,
            },

            // style指定字符串模式绑定style属性实现css样式
            styleStr: "font-size: 30px; color: red",
            // 数组方式
            styleList: [{color: "green"}, {backgroundColor: "red"}],
            // 对象方式, 推荐使用对象方式进行style样式设置
            styleObj: {
                color: "red",
                backgroundColor: "green",
                fontSize: "35px",
            }
        }
    })
</script>
</html>

5、v-if和v-for渲染

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-if和v-for渲染</title>
    <script src="../vu/js/vue.js"></script>
</head>
<body>
<h3>v-if条件渲染和v-for循环渲染</h3>
<div id="forIf">
    <div>
        <h5>条件判断显示正确而数据渲染</h5>
        <!--v-if:代码开始的if判断, 代表的else if或elif判断 v-else:else判断-->
        <!--根据条件判断正确的显示-->
        <p v-if="score >= 90">优秀</p>
        <p v-else-if="score > 70 && score < 90">良好</p>
        <p v-else-if="score > 60 && score < 70">及格</p>
        <p v-else></p>
    </div>
    <h5>v-for循显示数据</h5>
    <div>
        <p>循环列表显示数据</p>
        <ul>
            <li v-for="item in list">{{item}}</li>
        </ul>
        <p>循环列表数据值和索引号</p>
        <ul>
            <!--item代表获取数据值 index代表的索引,索引从0开始(注: 位置不能换,第一个只能是值,第二个索引-->
            <li v-for="(item, index) in list">{{index}}: {{item}}</li>
        </ul>
        <p>循环对象获取key和值</p>
        <ul>
            <!-- v-for循环对象value:代表获取对象的值,key:代表获取对象的key-->
            <li v-for="(value, key) in obj">{{key}}: {{value}}</li>
        </ul>
        <ul>
            <!--v-for循环对象单独变量获取对象是值-->
            <li v-for="value in obj">{{value}}</li>
        </ul>

    </div>
</div>
</body>
<script>
    var forIf = new Vue({
        el: "#forIf",
        data: {
            score: 65,
            list: ['A', 'B', 'C', 'D'],
            obj: {
                beijing: "北京",
                shanghai: "上海",
                shenzhen: "深圳",
            }
        }
    })
</script>
</html>

6、v-model双向绑定

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>v-model</title>
    <script src="../vu/js/vue.js"></script>
</head>
<body>
<h3>v-model双向绑定示例</h3>
<div id="model">
    <!--
    v-model:数据会根据变化而变化
    v-model.lazy: input框内输入完后鼠标移除input框后内容才会显示
    v-model.number:input框内开头是数字后面输入字母或字符,字母或字符不会取值。如果开头是字母会正常显示
    v-model.trim:去除两侧空白
    -->
    <h5>v-model随着数据变化而变化</h5>
    <p><input type="text" v-model="bind">{{bind}}</p>
    <h5>v-model.lazy离开input框数据发生变化</h5>
    <p><input type="text" v-model.lazy="bindLazy">{{bindLazy}}</p>
    <h5>v-model.number input框中开头输入数字后面数据内容不会取值显示,如果开头字母或字符正常取值显示</h5>
    <p><input type="text" v-model.number="bindNumber">{{bindNumber}}</p>
    <h5>v-model.trim 去除input框输入内容两侧空白</h5>
    <p><input type="text" v-model.trim="bindTrim">{{bindTrim}}</p>
</div>
</body>
<script>
    var model = new Vue({
        el: "#model",
        data: {
            bind: "",
            bindLazy: "",
            bindNumber: "",
            bindTrim: "",
        }
    })
</script>
</html>
6-1、v-model表单案例
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>表单</title>
    <script src="../../vu/js/vue.js"></script>
</head>
<body>
<div id="app">
    <p>用户名:<input type="text" v-model="username"></p>
    <p>密码:<input type="password" v-model="password"></p>
    <p><input type="checkbox" v-model="isCheck">记住密码</p>
    <p>
        <input type="radio" value="1" v-model="gender"><input type="radio" value="2" v-model="gender"><input type="radio" value="0" v-model="gender">未知
    </p>

    <p>
        <input type="checkbox" value="Linux" v-model="book">Linux
        <input type="checkbox" value="PHP" v-model="book">PHP
        <input type="checkbox" value="Go" v-model="book">Go
        <input type="checkbox" value="Python" v-model="book">Python
        <input type="checkbox" value="JAVA" v-model="book">JAVA
    </p>
    <p><input type="submit" value="提交" @click="handledSubmit"></p>

    <hr>
    记住密码:{{isCheck}}
    <hr>
    gender:{{gender}}
    <hr>
    book:{{book}}
</div>
</body>
<script>
    new Vue({
        el: "#app",
        data: {
            username: '',
            password: '',
            isCheck: false,
            gender: '',
            book: [],
        },
        methods: {
            handledSubmit(){
                console.log(this.username)
                console.log(this.password)
                console.log(this.isCheck)
                console.log(this.gender)
                console.log(this.book)

            }
        }
    })
</script>
</html>

7、blur change input事件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>blur change input事件</title>
    <script src="../vu/js/vue.js"></script>
</head>
<body>
<h3>blur change input事件示例</h3>
<div id="blurChangeInput">
    <p><input type="text" v-model="blur" @blur="blurClick"></p>
    <p><input type="text" v-model="change" @change="changeClick"></p>
    <p><input type="text" v-model="input" @input="inputClick"></p>
</div>

</body>
<script>
    var blurChangeInput = new Vue({
        el: "#blurChangeInput",
        data: {
            blur: "鼠标移开失去焦点事件",
            change: "数据发生变化触发事件",
            input: "输入内容触发事件",
        },
        methods: {
            blurClick(){
               console.log(this.blur)
            },
            changeClick(){
                console.log(this.change)
            },
            inputClick(){
                console.log(this.input)
            }

        }
    })
</script>
</html>

8、背景颜色切换

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>背景颜色切换</title>
    <script src="../vu/js/vue.js"></script>
    <style>
        .clsIn{
            background-color: red;
            text-align: center;
            width: 200px;
            height: 200px;
            line-height: 200px;
        }

        .clsOut{
            background-color: orange;
            text-align: center;
            width: 200px;
            height: 200px;
            line-height: 200px;
        }
    </style>
</head>
<body>
<h3>动态背景颜色切换</h3>
<div id="mousemove">
    <!--mousemove鼠标移近发生变化,mouseout鼠标移除发生变化-->
    <div :class="cls" @mousemove="seMove" @mouseout="seOut">OK</div>
</div>
</body>
<script>
    var mousemove = new Vue({
        el: "#mousemove",
        data: {
            // 绑定css 样式类,将样式类分别设置为true,false
            cls:  {clsIn: true, clsOut: false}
        },
        methods: {
            seMove(){
                // 鼠标移进将
                this.cls.clsIn=false
                this.cls.clsOut = true
            },
            seOut(){
                this.cls.clsIn=true
                this.cls.clsOut = false
            }
        }
    })
</script>
</html>

9、事件修复符

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>事件修复符</title>
    <script src="../vu/js/vue.js"></script>
</head>
<body>
<div id="clickModify">
    <h1>点击子标签,父标签的事件也触发,事件冒泡</h1>
    <ul @click="handledUl">
        <!--@click.stop:只处理自己的事件,不再冒泡到父标签 -->
        <li @click.stop="handledLi">第一次点击</li>
        <li>点击触发父标签冒泡</li>
    </ul>

    <h1>子标签的冒泡不处理:父标签写self, 父标签只处理自己的事件,冒泡的事件不管</h1>
    <!--@click.self:只处理自己的事件,子控件冒泡的事件不处理-->
    <ul @click.self="handledUl">
        <li @click.stop="handledLi">第一次点击</li>
        <li>第二次点击</li>
    </ul>

    <h1>阻止a标签的跳转</h1>
    <!--@click.prevent:阻止a标签的跳转-->
    <a href="https://www.baidu.com" @click.prevent="handledA">点击跳转到百度</a>

    <h1>只能点击1次</h1>
    <!--@click.once:只能点击1次,如果需要多次点击需要刷新才可以点击-->
    <button @click.once="handledBut">点击获取</button>
</div>
</body>
<script>
    var clickModify = new Vue({
        el: "#clickModify",
        data: {},
        methods:{
            handledLi(){
                console.log("li被点击")
            },
            handledUl(){
                console.log("触发ul父标签冒泡")
            },
            handledA(){
                console.log("禁止访问")
            },
            handledBut(){
                alert("只能被点击一次,在点击需要刷新")
            }
        }
    })
</script>
</html>

10、按键修饰符

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>按键修饰符</title>
    <script src="../../vu/js/vue.js"></script>
</head>
<body>
<div id="app">
    <h1>按键修饰符</h1>
    <!--可以根据keyup获取相应的按键-->
    <input type="text" @keyup="handledKeyUp($event)">
    <br>
    <!--  @keyup.enter源代码默认设置了enter回车键-->
    <input type="text" @keyup.enter="handledKeyEnter($event)">
</div>
</body>

<script>
    new Vue({
        el: "#app",
        data:{},
        methods: {
            handledKeyUp(event){
                if (event.code === "Enter"){
                    console.log(event)
                }
            },

            handledKeyEnter(event){
                console.log("回车键")
            }
        }
    })
</script>
</html>

11、vue生命周期

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue对象的生命周期</title>
    <script src="../../vu/js/vue.js"></script>
</head>
<body>
<div id="app">
    <button @click="handleShow">点击隐藏组件</button>
    <home v-if="show"></home>
</div>

</body>
<script>
    Vue.component("home", {
        template: `
            <div>
                <p>这个是组件</p>
                <p>{{content}}</p>
                <button @click="handleClick">更新</button>
            </div>
        `,
        data(){
            return {
                content: "这个是组件里面的data",
                timer: "",
            }
        },
        methods: {
            handleClick(){
                this.content = "组件data数据更新"
            }
        },
        // 创建Vue实例,组件实例对象创建之前调用
        beforeCreate(){
            console.log("beforeCreate")
            // this.$data数据和this.$el模板是:undefined
            console.log("当前data状态:", this.$data) //数据
            console.log("当前el状态:", this.$el) //模板
            // console.log(this.$refs)
        },
        // 创建Vue实例成功后调用(可以在此处发送ajax请求后端数据)
        // 当前函数执行时,vue实例对象已经初始化完成
        // 在开发中,我们可以在这个函数中进行初始化数据相关的操作,例如:使用ajax从服务器中读取数据,并赋值给data
        created(){
            // 一般使用多,用于发送ajax请求。data数据好了,在发送请求,去后端拿数据
            console.log("create")
            // this.$data:已经有数据,this.$el: undefined
            console.log("当前data状态:", this.$data) //数据
            console.log("当前el状态:", this.$el) //模板
            // 启动一个定时器,每隔一段执行一次
            this.timer = setInterval(function () {
                // 每隔3秒打印一次
                console.log("hello word")
            }, 3000)

            // 定时器:延迟调用,执行一次
            // setTimeout()
        },
        // 渲染DOM之前调用
        // 已经把对应的vue语法的变量替换成了html内容了,但是并没有挂载到el标签的内容中
        beforeMount(){
            console.log("beforeMount")
            console.log("当前data状态:", this.$data) //数据
            console.log("当前el状态:", this.$el) //模板
        },
        // 渲染DOM之后调用
        // vue生成的HTML内容已经挂载到了$el属性中
        mounted(){
            console.log("mounted")
            console.log("当前data状态:", this.$data) //数据
            console.log("当前el状态:", this.$el) //模板
        },
        // 变量更新前,data选项中的数据发生了改变,但是没有重新生成虚拟DOM,所以HTML中的变量值没有被同步
        // 修改数据前,判断本次修改是否合法?发送ajax,
        beforeUpdate(){
            console.log("beforeUpdate")
            console.log("当前data状态:", this.$data) //数据
            console.log("当前el状态:", this.$el) //模板
        },
        // 变量更新后,html内容已经与data选项中的数据同步了,因为重新生成了虚拟DOM
        // 修改数据后,发送ajax,同步数据库
        updated(){
            // 一般使用多,数据变化,页面更新完后,执行
            console.log("updated")
            console.log("当前data状态:", this.$data) //数据
            console.log("当前el状态:", this.$el) //模板
        },
        // 销毁之前调用
        beforeDestroy() {
            console.log("beforeDestroy")
            console.log("当前data状态:", this.$data) //数据
            console.log("当前el状态:", this.$el) //模板
        },
        // 销毁之后调用
        destroyed(){
            // 组件销毁,会触发,也会使用
            console.log("destroyed")
            console.log("当前data状态:", this.$data) //数据
            console.log("当前el状态:", this.$el) //模板

            //释放定时器,(会将created 设置的定时器打印hello word释放消除)
            clearInterval(this.timer)
            this.timer = null
        }

    })

    var app = new Vue({
        el: "#app",
        data: {
            show: true,
        },
        methods: {
            handleShow(){
                this.show =! this.show
            }
        },
    })
</script>
</html>

12、计算属性

12-1、计算属性示例1
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>计算属性</title>
    <script src="../../vu/js/vue.js"></script>
</head>
<body>
<div id="app">
    <input type="text" v-model="search">
    <ul>
        <li v-for="item in data">{{item}}</li>
    </ul>
</div>

</body>

<script>
    new Vue({
        el: "#app",
        data: {
            search: '',
            data_list: ["beijing", "shanghai", "shenzhen", "guangzhou", "hebei"],
        },
        // 只要input框数据发生变化search, data会重新运算,只要一运算,v-for重新循环,实现联动
        // computed计算属性需要使用return
        computed: {
            data (){
                return this.data_list.filter(item=>{
                    return item.indexOf(this.search) > -1
                })
            }

        }
    })
</script>
</html>
12-2、计算属性示例2
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>计算属性</title>
    <script src="../vu/js/vue.js"></script>
</head>
<body>
<div id="app">

    <input type="text" v-model.number="num1">+
    <input type="text" v-model.number="num2">={{result}}
</div>

</body>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            num1: 10,
            num2: 20,
        },
        <!--所谓的计算属性,是vue提供给开发者用于编写代码时保存计算出新的数据结果的变量。主要通过computed选项进行声明的-->
        computed: {
            result(){
                return this.num1 + this.num2
            }
        }
    })
</script>
</html>

13、监听属性

13-1、分组向后端发送请求数据
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>监听属性</title>
    <script src="../../vu/js/vue.js"></script>
</head>
<body>
<div id="app">
<!--监听属性相当于分组,添加点击事件后会选择对应内容 例如@click="group='书籍'" 会选择这里group='书籍'作为选项内容-->
    <span @click="group='书籍'">书籍</span>
    <span @click="group='古城'">古城</span>
    <span @click="group='景色'">景色</span>
</div>
</body>
<script>
    new Vue({
        el: "#app",
        data: {
            group :'',
        },
        // 监听的是data里面而group,只要group watch里的函数触发
        // watch一般用于向后端发送请求,请求回应相应的分类数据展示,一般对相关数据的分类或分组,减少监听事件使用
        watch: {
            group: function (val) {
                console.log("group发生变化")
                console.log(val)

            }
        }
    })
</script>
</html>
13-2、判断用户和密码规则
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>监听属性</title>
    <script src="../vu/js/vue.js"></script>
    <style>
        input{
            outline: none;
            border: 1px solid #333;
        }
    </style>
</head>
<body>
<div id="app">
    <p><input ref="username" type="text" v-model="username" @blur="handledBlur"></p>
    <p><input ref="password" type="text" v-model="password"></p>
</div>
</body>
<script>
    var app = new Vue({
        el: "#app",
        data: {
            username: '',
            password: '',
        },
        methods: {
            handledBlur() {
                console.log("check_name执行")
            }
        },

        watch: { // 侦听选项API,成员就是data变量名
            // 这里的username指定是data里面设置的username变量
            username(new_data, old_data){
                // 侦听data中的username
                console.log(`old_data=${old_data}, new_data=${new_data}`)
                let length = this.username.length;
                if(length>=6 && length<=16){
                    // 这里的username是设置的ref="username"
                    this.$refs.username.style.border="1px solid blue";
                }else{
                    this.$refs.username.style.border="1px solid red";
                }
            },
            password(new_value, old_value){ // 参数为:修改前的变量值以及修改后的变量值
                if(/^\d+$/.test(this.password)){
                    this.$refs.password.style.border="1px solid red";
                }else{
                    this.$refs.password.style.border="1px solid blue";
                }
            }
        },
    })
</script>
</html>

14、全局和局部

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>全局和局部组件</title>
    <script src="../../vu/js/vue.js"></script>
</head>
<body>
<div id="app">
    <navbar></navbar>
    <com></com>
</div>
</body>
<script>
    var obj = {
        // 全局组件
        // template这里是反引号Esc按键下面的按键上面的反引号
        template: `
            <div>
                <h1>全局组件</h1>
                <button @click="handledClick">点击获取</button>
                <p>全局内容:{{book}}</p>
            </div>
        `,
        data(){
            return {
                book: "水浒传"
            }
        },
        methods: {
            handledClick(){
                alert("点击数据展示")
            }
        }
    }
    Vue.component('navbar', obj)
    new Vue({
        el: "#app",
        data: {
        },

        // 定义局部组件,自定组件只能在div id=app中使用,不能在子组件'navbar'中模板使用
        components:{
            com:{
                template:`
                    <div>
                        <hr>
                        <p>局部组件显示</p>
                        <p>局部内容:{{book}}</p>
                    </div>
                `,
                data(){
                    return {
                        book: "西游记"
                    }
                },
                methods: {

                }
            }
        }
    })
</script>
</html>

15、自定义父传子组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>组件通信父传子</title>
    <script src="../../vu/js/vue.js"></script>
</head>
<body>
<h1>组件通信父传子</h1>
<div id="app">
    <p>父变量city数据:{{city}}</p>
    <hr>
    <!--在组件中自定义属性添加父data里面的变量到自定义属性里面,在组件中使用props获取自定义属性,组件中使用自定义的属性获取父变量数据-->
    <navbar :mycity="city"></navbar>
</div>

</body>
<script>
    <!--"注:Vue.component('自定义标签名称'{})需要在 new Vue({})上面,如果在下面则会不显示" -->
    Vue.component('navbar', {
        template: `
            <div>
                <p>继承父变量数据内容</p>
                <!--这里mycity是自定义属性获取的父变量数据-->
                <p>继承父city变量数据:{{mycity}}</p>
            </div>
        `,
        data(){
            return {}
        },
        <!--{{mycity}}这里的mycity是定义在 navbar:里面的自定义属性 再把自定义mycity属性添加到props组列表里面进行获取-->
        props: ["mycity"],
        methods:{}
    })

    new Vue({
        el: "#app",
        data: {
            city: "北京",
        },
    })


</script>
</html>

16、自定义子传父组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>组件通信子传父</title>
    <script src="../../vu/js/vue.js"></script>
</head>
<body>
<div id="app">
    <p>接受子组件传递的数据:{{accept_data}}</p>
    <hr>
    <!--
    设定自定义触发事件,将子组件的数据传递到父组件,自定义触发事件绑定函数名称父组件会使用到
    @event 设置的自定义事件名称
    acceptSonData 绑定的事件触发函数名称(注:这里的名称父组件函数名称需要使用)
    -->
    <home @event="acceptSonData"></home>

</div>

</body>
<script>
    Vue.component('home', {
        template: `
            <div>
                <p>这个是子组件</p>
                <p><input type="text" v-model="send_data"></p>
                <button @click="sendClick">点击传递数据给父组件</button>
            </div>
        `,
        data(){
            return {
                send_data: "",
            }
        },
        methods: {
            sendClick(){
                // 触发自定义事件执行,并且传入当前子组件的send_data数据
                // 将子组件数据传递到父组件,$emit是不可以改变。
                // event需要跟 <home @event="acceptSonData"></home> 自定义的事件名称保持一致
                // this.send_data 是传递子组件的数据
                this.$emit('event', this.send_data)
            }
        }
    })

    var app = new Vue({
        el: '#app',
        data: {
            accept_data: ''
        },
        methods: {
            <!--
            这里是绑定子组件自定义触发事件绑定的函数名称
            value: 接受子组件传递的数据参数(value参数名称可以自定义)
            -->
            acceptSonData(value){
                // 将子组件传递过来的数据赋值给this.accept_data
                this.accept_data = value
            }
        }
    })
</script>
</html>

17、ref属性实现组件通信

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ref属性实现组件通信</title>
    <script src="../../vu/js/vue.js"></script>
</head>
<body>
<div id="app">
    <h1>ref属性实现组件通信</h1>
    <p>获取子组件input值:{{name}}</p>
    <!--放在普通标签,通过this.$refs.ref -->
    <input type="text" v-model="name" ref="myref">
    <button @click="handledClick">点击获取</button>
    <hr>

    <navbar ref="navbar"></navbar>
    <!--设置子组件点击事件操作-->
    <button @click="handledClickNav">点击</button>

</div>

</body>
<script>
    Vue.component("navbar", {
        template: `
            <div>
                <p>获取父组件input数据值:{{navname}}</p>
                <input type="text" v-model="navname">
            </div>
        `,
        data(){
            return{
                navname: "",
            }
        },
        methods: {
            handledClick(){
                console.log("远程调用子组件"+this.navname)
            }
        }
    })

    new Vue({
        el: "#app",
        data: {
            name:'',
        },
        methods:{
            handledClick(){
                // 获取了组件对象
                console.log(this.$refs)
                // this.$refs.ref对应的名字,拿到的原生dom对象。也就是获取的上面input标签
                console.log(this.$refs.myref)

                // this.$refs.myref.value这个是获取的是输入input的value值内容
                console.log(this.$refs.myref.value)

                // 将父组件变量值赋值给子组件里面的navname变量重
                this.$refs.navbar.navname=this.name

                // 调用子组件methods里面的handledClick函数
                this.$refs.navbar.handledClick()
            },
            handledClickNav(){
                // 获取到是子组件对象
                console.log(this.$refs.navbar)
                // 将子组件值赋值给父组件变量name
                this.name=this.$refs.navbar.navname
            }
        }
    })
</script>
</html>

18、动态组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>动态组件</title>
    <script src="../../vu/js/vue.js"></script>
</head>
<body>
<div id="app">
    <h1>动态组件</h1>
    <ul>
        <!--这里的home,shop, book分别是指定的自定义的组件名称-->
        <li @click="myType='home'">首页</li>
        <li @click="myType='shop'">商品</li>
        <li @click="myType='book'">书籍</li>
    </ul>
    <!--动态组件,is是哪个组件名称,这里会显示哪个组件-->
    <component :is="myType"></component>


</div>

</body>
<script>
    Vue.component("home", {
        template: `
            <div>
                <h2>首页</h2>
            </div>
        `,

    })
    Vue.component("shop", {
        template: `
            <div>
                <h2>商店</h2>
            </div>
        `,

    })
    Vue.component("book", {
        template: `
            <div>
                <h2>书籍</h2>
            </div>
        `,

    })
    new Vue({
        el: "#app",
        data:{
            // 这里的home指的就是定义的组件名称,home组件
            myType: "home",
        },
    })
</script>
</html>

19、keep-alive保留input框内容

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>动态组件</title>
    <script src="../../vu/js/vue.js"></script>
</head>
<body>
<div id="app">
    <h1>动态组件</h1>
    <ul>
        <li @click="myType='home'">首页</li>
        <li @click="myType='shop'">商品</li>
        <li @click="myType='book'">书籍</li>
    </ul>
    <!--keep-alive 切换页面会保留input搜索框里输入的内容-->
    <keep-alive>
        <!--动态组件,is是哪个组件名称,这里会显示哪个组件-->
        <component :is="myType"></component>
    </keep-alive>


</div>

</body>
<script>
    Vue.component("home", {
        template: `
            <div>
                <h2>首页</h2>
            </div>
        `,

    })
    Vue.component("shop", {
        template: `
            <div>
                <h2>商店</h2>
            </div>
        `,

    })
    Vue.component("book", {
        template: `
            <div>
                <h2>书籍</h2>
                <input type="text">
            </div>
        `,

    })
    new Vue({
        el: "#app",
        data:{
            myType: "首页",
        },
    })
</script>
</html>

20、插槽

20-1、无名插槽
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>不具名插槽</title>
    <script src="../../vu/js/vue.js"></script>
</head>
<body>
<div id="app">
    <h1>插槽页面显示</h1>
    <hr>
    <home>
        <!--不具名插槽利用slot显示-->
        <div style="width: 200px; height: 200px; background-color: red; text-align: center; line-height: 200px">
            <h1>不具名插槽</h1>
        </div>
    </home>
    <hr>
</div>

</body>
<script>
    Vue.component("home", {
        template: `
            <div>
                <h2>插入页面显示</h2>
                <!--不具名插槽显示-->
                <slot></slot>
            </div>
        `
    })
    new Vue({
        el: "#app",
        data: {},
    })
</script>
</html>

​ 20-2、有名插槽

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>有名查询</title>
    <script src="../../vu/js/vue.js"></script>
</head>
<body>
<div id="app">
    <navbar>
        <div slot="bottom" style="width: 200px; height: 200px; background-color: orange">
            <span>这是具名插槽</span>
        </div>
    </navbar>

</div>

</body>
<script>
    Vue.component("navbar", {
        template: `
            <div>
                <!--lot 添加name属性是具名插槽-->
                <slot name="top"></slot>
                <p>这是自组件</p>
                <slot name="bottom"></slot>
            </div>
        `
    })
    new Vue({
        el: "#app",
        data: {},
    })
</script>
</html>

21、小案例

21-1、购物车案例
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>购物车</title>
    <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css">
    <script src="../../vu/js/vue.js"></script>
    <style>
        .container-fluid .row .table thead tr th{
            text-align: center;
        }
        .row .table button{

            text-align: center; /* 设置按钮内文本居中 */
            vertical-align: middle; /* 设置按钮内文本垂直居中 */
            background-color: transparent;
            border: none;
        }
        #plus-right{
            float: right;
        }

        #minus-left{
            float: left;
        }
    </style>
</head>
<body>
<div id="app">
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <table class="table table-bordered">
                    <thead>
                        <tr>
                            <th>商品id</th>
                            <th>商品名称</th>
                            <th>商品价格</th>
                            <th>商品数量</th>
                            <th><input type="checkbox" v-model="checkAll" @change="handledCheckAll"></th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr v-for="book in shopList" class="text-center">
                            <td>{{book.id}}</td>
                            <td>{{book.name}}</td>
                            <td>{{book.price}}</td>
                            <td><button id="minus-left" @click="handledMinus(book)">-</button>{{book.count}}<button id="plus-right" @click="book.count++">+</button></td>
                            <td><input type="checkbox" :value="book" v-model="shopCar" @change="checkAllOne"></td>
                        </tr>
                    </tbody>
                </table>
                <hr>
                商品购物车: {{shopCar}}
                <hr>
                商品总价格: {{getPrice()}}
            </div>
        </div>
    </div>
</div>


</body>

<script>
    new Vue({
        el: "#app",
        data: {
            shopList:[
                {id: "1", name: "Linux", price: 50, count: 5},
                {id: "2", name: "Go", price: 55, count: 10},
                {id: "3", name: "PHP", price: 30, count: 3},
                {id: "4", name: "JAVA", price: 40, count: 6},
                {id: "5", name: "Python", price: 35, count: 8},
                {id: "6", name: "MySQL", price: 25, count: 5},
            ],
            shopCar: [],
            checkAll: false
        },
        methods: {
            getPrice(){
                var sum=0
                // forEach循环计算
                // this.shopCar.forEach(function (v) {
                //     sum+=v.count*v.price
                //
                // })

                // 普通方式for计算
                for (i=0; i<this.shopCar.length; i++){
                    const book = this.shopCar[i]
                    sum+=book.price*book.count
                }
                return sum
            },

            // 实现全部选中
            handledCheckAll(){
                if (this.checkAll){
                    this.shopCar = this.shopList
                }else{
                    this.shopCar=[]
                }
            },

            // 如果没有全部选中,取消全部选中图标
            checkAllOne(){
                this.checkAll = this.shopCar.length === this.shopList.length
            },

            handledMinus(num){
                if (num.count <= 1){
                    alert("数量为"+num.count+"不能在减")
                }else{
                    num.count--
                }
            }
        }
    })
</script>
</html>
posted @   点点滴滴的努力  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示