vue进阶

计算属性

# 插值的普通函数,只要页面一刷新,函数就会重写计算,跟函数没关的值的变化,函数也会重写计算
# 计算属性把函数当成属性来用---》只有这个函数使用的属性(变量)变化,函数才重写运算
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
    <input type="text" v-model="mytest2">-->{{mytest2}}
    <br>
    <input type="text" v-model="mytext">--->{{mytext.substring(0,1).toUpperCase()+mytext.substring(1)}}
    <br>
    函数方式:{{getName()}}
    <br>
    计算属性:{{getName2}}

</div>

</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            mytext: '',
            mytest2: '',
        },
        methods:{
            getName(){
                console.log("我执行了")
                return this.mytext.substring(0,1).toUpperCase()+this.mytext.substring(1)
            }
        },
        // 8生命周期
        computed:{
            getName2(){
                console.log("计算属性我执行了")
                return this.mytext.substring(0,1).toUpperCase()+this.mytext.substring(1)

            }
        }


    })
</script>
</html>

通过计算属性重写过滤案例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>过滤案例</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.12/vue.min.js"></script>
</head>
<body>
<div id="box">
    <p><input type="text" v-model="myText"  placeholder="请输入要筛选的内容:"></p>
    <ul>
        <li v-for="data in newList">{{data}}</li>
    </ul>
</div>
</body>
<script>
    var vm = new Vue({
        el: '#box',
        data: {
            myText: '',
            dataList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'],
        },

        computed:{
            newList(){
                console.log('我执行了')
                 var datalist2 = this.dataList.filter(item => {
                    return item.indexOf(this.myText) > -1
                })
                return datalist2

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

侦听属性

只要变量发生变化,就会执行监听属性中的方法

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">

    <input type="text" v-model="mytext">--->{{mytext}}


</div>

</body>
<script>
    var vm = new Vue({
        el: '#app',
        data: {
            mytext: '',
        },
        watch: {
            // 只要mytext发生变化,就会执行该函数
            mytext: function () {
                console.log('我变化了,执行')

            }
        }


    })
</script>
</html>

 

组件

局部组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
    <Top></Top>
    <br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
    <Bottom></Bottom>


</div>

</body>
<script>
    var vm = new Vue({
        // el  data  methods watch computed 8个
        el: '#app',
        data: {},
        // 定义再这里面的叫局部组件,只能再局部使用,只能再id为app的标签内使用
        components: {
            'Top': {
                template: `
                    <div>
                        <h1 style="background: pink;font-size: 60px;text-align: center">{{name}}</h1>
                        <hr>
                        <button @click="handleC">点我看美女</button>
                    </div>
                `,
                data() {
                    return {
                        name: "我是头部"
                    }
                },
                methods: {
                    handleC() {
                        alert('美女')
                    }
                },
            },
            'Bottom': {
                template: `
                    <div>
                        <hr>
                        <h1 style="background: green;font-size: 60px;text-align: center">{{name}}</h1>

                    </div>
                `,
                data() {
                    return {
                        name: "我是尾部"
                    }
                },

            },

        },


    })
</script>
</html>

全局组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
    <top></top>


</div>

</body>
<script>
    // 定义全局组件--->任意位置都可以用
    Vue.component('top', {
            template: `
                <div>
                    <h1 style="background: pink;font-size: 60px;text-align: center">{{name}}</h1>
                    <hr>
                    <button @click="handleC">点我看美女</button>
                </div>
            `,
            data() {
                return {
                    name: "我是头部"
                }
            },
            methods: {
                handleC() {
                    alert('美女')
                }
            },

        },)

    var vm = new Vue({
        // el  data  methods watch computed 8个
        el: '#app',
        data: {},



    })
</script>
</html>

注意事项

# 扩展 HTML 元素,封装可重用的代码,目的是复用
    -例如:有一个轮播,可以在很多页面中使用,一个轮播有js,css,html
    -组件把js,css,html放到一起,有逻辑,有样式,有html
  
# 局部组件,全局组件
    -

# 注意事项
1 自定义组件需要有一个root element,一般包裹在一个div中
2 父子组件的data是无法共享
3 组件可以有data,methods,computed....,但是data 必须是一个函数

 

组件通信之父传子

通过自定义属性传值

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">


    <!--通过自定义属性:myheader-->
    <top :myheader="headerName"></top>
    {{headerName}}
    <input type="text" v-model="headerName">


</div>

</body>
<script>
    // 定义全局组件--->任意位置都可以用
    Vue.component('top', {
            template: `
                <div>
                    <h1 style="background: pink;font-size: 60px;text-align: center">{{myheader}}</h1>
                </div>
            `,
            data() {
                return {
                    name: "我是头部"
                }
            },
            // 必须叫props,数组内放自定义属性的名字
            // props:['myheader',],
            // 属性验证
            props:{
                myheader:String,  // key是自定义属性名,value是类型名,如果是别的类型就报错
            },


        },)

    var vm = new Vue({
        // el  data  methods watch computed 8个
        el: '#app',
        data: {
            headerName:999
        },



    })
</script>
</html>

组件通信之子传父

通过自定义事件传值

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">

<!--    自定义了一个myevent事件 -->
    <top @myevent="handelRecv"></top>
    <hr>
    接收到子组件的数据是:{{childText}}


</div>

</body>
<script>
    // 定义全局组件--->任意位置都可以用
    Vue.component('top', {
        template: `
            <div>
                <h1 style="background: pink;font-size: 60px;text-align: center">{{myheader}}</h1>
                <input type="text" v-model="text">
                <button @click="handleSend">点我传出去</button>
            </div>
        `,
        data() {
            return {
                myheader: "我是头部",
                text: '',
            }
        },
        methods:{
            handleSend(){
                // 触发绑定在该组件上的事件,myevent---》父组件中会执行事件对应的函数handelRecv--》
                this.$emit('myevent',this.text)
            }
        }


    },)

    var vm = new Vue({
        // el  data  methods watch computed 8个
        el: '#app',
        data: {
            childText: ''
        },
        methods:{
            handelRecv(text){
                // 接收一个参数,赋值给父组件的childText
                this.childText=text
            }
        }


    })
</script>
</html>

 

ref属性

# ref属性,如果放在普通标签上,就是普通标签的原生html,操作,设置
# ref属性,如果放在组件上,就是当前组件对象
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">

    <top ref="top"></top>

    <input type="text" v-model="text" ref="myinput">
    <img src="" alt="" ref="myimg" height="80px" width="80px">
    <hr>
    <button @click="handleC">点我</button>



</div>

</body>
<script>
    // 定义全局组件--->任意位置都可以用
    Vue.component('top', {
        template: `
            <div>
                <h1>{{myheader}}</h1>
                <button @click="handleC">点我看美女</button>
                <hr>
            </div>
        `,
        data() {
            return {
                myheader: "我是头部",
            }
        },
        methods:{
            handleC(){
                alert("美女")
            }
        }



    },)

    var vm = new Vue({
        el: '#app',
        data: {
            text:''

        },
        methods:{
            handleC(){
                console.log('我被点了')
                //把所有有ref属性的标签 弄到 一个对象中
                console.log(this.$refs) // 是所有标签写了ref属性的对象{myinput:真正的标签,myimg:真正的标签}
                //111111 放在普通标签上示例
                // 取到input的value值
                // console.log(this.$refs.myinput.value)
                // this.$refs.myinput.value='lqz is nb'
                // this.$refs.myimg.src='https://tva1.sinaimg.cn/large/00831rSTly1gd1u0jw182j30u00u043b.jpg'
                //222222 放在组件上示例
                // console.log(this.$refs.top)
                // 既然能够拿到组件对象,组件中的data中的值也可以拿到,组件中的方法也可调用
                console.log(this.$refs.top.myheader) // 父组件中拿到了子组件的值
                // 不区分是子传父还是父传子了
                // 想子传父--》下面就是子传父
                // console.log(this.$refs.top.myheader)
                // this.text=this.$refs.top.myheader

                // 想父传子
                // this.$refs.top.myheader='刘清政 is nb'
                // this.$refs.top.myheader=this.text

                // 还可以调用组件的方法
                this.$refs.top.handleC()  //如果有参数,是不是也可以传到子组件中


            }
        }



    })
</script>
</html>

动态组件与keep-alive

keep-alive:组件不销毁

component:有个is属性,指定显示的组件是哪个
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<ul>
    <li @click="changeC('index')">首页</li>
    <li @click="changeC('order')">订单</li>
    <li @click="changeC('good')">商品</li>
</ul>
<!--    笨办法-->
<!--<index v-if="index_show"></index>-->
<!--<order v-if="order_show"></order>-->
<!--<good v-if="good_show"></good>-->
<keep-alive>
    <component :is='who'></component>
</keep-alive>



</div>

</body>
<script>
    // 定义全局组件--->任意位置都可以用
    Vue.component('index', {
        template: `
            <div>
                <h1>我是首页</h1>
            </div>
        `,
    },)
    Vue.component('order', {
        template: `
            <div>
                <h1>我是订单</h1>
                请输入要查询的订单:<input type="text">
            </div>
        `,
    },)
    Vue.component('good', {
        template: `
            <div>
                <h1>我是商品</h1>
            </div>
        `,
    },)

    var vm = new Vue({
        el: '#app',
        data: {
            // index_show:true,
            // order_show:false,
            // good_show:false,
            who:'index'

        },
        methods:{
            changeC(i){
                this.who=i
            }
        }




    })
</script>
</html>

插槽与具名插槽

普通插槽

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">

<index>
    <div>
        用户名:<input type="text">
        密码:<input type="text">
    </div>
</index>


</div>

</body>
<script>
    Vue.component('index', {
        template: `
            <div>
                <h1>我是首页</h1>
                <slot></slot>
            </div>
        `,
    },)

    var vm = new Vue({
        el: '#app',
        data: {


        },
        methods:{

        }




    })
</script>
</html>

具名插槽

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./js/vue.js"></script>
</head>
<body>
<div id="app">

    <index>
        <p slot="a">pppp</p>
        <div slot="b">
            div--div
        </div>
    </index>


</div>

</body>
<script>
    Vue.component('index', {
        template: `
            <div>
                <slot name="a"></slot>
                <h1>我是首页</h1>
                <slot name="b"></slot>


            </div>
        `,
    },)

    var vm = new Vue({
        el: '#app',
        data: {},


    })
</script>
</html>

 

posted @ 2022-04-14 18:40  椰子皮0oo0  阅读(51)  评论(0)    收藏  举报
1