vue组件


组件作用就是把一个复杂的界面拆成一块一块,然后组合起来

全局组件

  • 组件具有复用性,定义了就可以随便在哪里用
  • 弊端就是定义了就会占资源
<script>
    // 创建全局组件app
    // 将website,describe,count都放入根组件中
    const app = Vue.createApp({
        template: `
            <website />
            <describe />
            <count />
                <count />
                    <count />
        `

    })
    
    // 创建一个子组件 website
    app.component('website',{
        template: `
            <h2>
                fujingjie
            </h2>
        `
    })

    // 创建一个子组件 describe
    app.component('describe',{
        template: `
            <h2>
                henshuai
            </h2>
        `
    })

    // 创建一个子组件count
    app.component('count', {
        data(){
            return{
                count: 0
            }
        },

        template: `
        <div>
            {{count}}
            <button @click="count++">
                增加1
            </button>
        </div>
        `
    })

    const vm = app.mount("#app")
</script>

局部组件

  • 局部组件定义就是类型声明一个变量
  • 局部组件需要注册到app中,用components
  • 局部组件命名用大驼峰命名法,FuJingJie这样的
<script>

    // 定义局部组件
    const Counter = {
        data() {
            return {
                count: 0
            }
        },
        template: `<div>{{count}}<button @click="count++">增加1</button></div>`
    }
    
    // 定义局部组件
    const XieDaJiao = {
        template: `<h2>xxxxx</h2>`
    }
    const app = Vue.createApp({
        // 注册局部组件
        components: {
            jspang: Counter,
            XieDaJiao
        },
        
        template: `
            <h2>JSPang.com</h2>
            <XieDaJiao />
            <jspang />

        `
    })
    const vm = app.mount("#app")

</script>

父子组件的传值

  • 静态传值,也就是写死的。传的值都是string,写123,出来的也是string
const app = Vue.createApp({
    template:`
        <h2>JSPang.com</h2>
        <Son name=123 />
    `
})

app.component('Son',{
    props:['name'],
    template:`<div>{{name}} div </div>`
})
  • props 用来接收变量的
  • 动态参数传值,就是把动态参数放到data中
const app = Vue.createApp({
    data(){
        return {
            name: "技小胖"
        }
    },
    template:`
        <h2>JSPang.com</h2>
        // 动态参数绑定用v-bind
        <Son v-bind:name="name" />
    `
})
  • 传递的的参数为函数
  • 箭头函数,类似于python里的lambda,参考https://www.runoob.com/js/js-function-definition.html
// 定义一个子组件,需要参数pay
app.component('XiaoJieJie',{
    props:['pay'],
    methods:{
        handleClick(){
            alert('请付钱....')
            this.pay()  // 付多少钱,是顾客说的算的,所以调用时才能确定
        }
    },
    template:`<div @click="this.handleClick"> 和小姐姐,打招呼! </div>`
})


const app = Vue.createApp({
    data(){
        return {
            name:123,
            // 箭头函数
            pay:()=>{
                alert('给你500元')
            }
        }
    },
    template:`
        <h2>JSPang.com</h2>
        <Son :name="name" />
        <xiao-jie-jie :pay="pay"/>
    `
}

参数校验

  • 类型校验
  • required 必填项
  • default 默认值
  • 精准校验 validator
  • search 方法,找到了返回位置,没找到返回-1
<script>
    const app = Vue.createApp({
        data() {
            return {
                name: 'qwer',
            }
        },

        template: `
            <Son :name="name" />
            <Son />
        `
    })

   app.component('Son',{
            props:{
                name: {
                    type: String,
                    default: 'axtat', 
                    required: true,
                    validator: function(value) {
                        console.log(value.search("x"))
                        return value.search("x") != -1
                    }
                } 
            },
            template:`<div>{{ typeof name}} </div>`
        })

    const vm = app.mount("#app")
</script>

单向数据流机制

  • 数据从父级组件传递给子组件,只能单向绑定。子组件内部不能直接修改从父组件传递过来的数据。
  • 目的是防止数据在复用时,造成重复。就是改了一个,另一个也变了。
  • 要修改父组件传过来的参数,就要在组件内的数据项中声明一个变量,把父组件传递过来的变量赋值给内部变量,然后就可以随意修改了
<script>
    const app = Vue.createApp({
        data() {
            return {
                counter: 0
            }
        },
        template: `
            <h2>JSPang.com</h2>
            <counter :counter="counter"/>
        `
    })

    app.component('Counter', {
        props: ['counter'],
        data(){
            return {
                newCounter: this.counter
            }
        },
        template: `
            {{newCounter}}<button @click="this.newCounter+=1">增加数量</button>
        `
    })

    const vm = app.mount("#app")
</script>

Non-props

  • 子组件中没有写props的时候。也是可以把参数传递到子组件中的。不要的话,可以在子组件中写一个props来接受参数,但是不用就好。
const app = Vue.createApp({
    template: `
    <h2>JSPang.com</h2>
    <hello msg="jspang" />
`
})

app.component('Hello', {
     props: ['msg'],
     template: `<h3>Hello World</h3>`
 })
  • 父组件上写的style,也是会完全传递到子组件上的
const app = Vue.createApp({
    template: `
        <h2>JSPang.com</h2>
        <hello style="color:red;" />
    `
})
  • inheritAttrs 用了之后就不会接受任何参数了
app.component('Hello', {
    inheritAttrs: false,
    template: `<h3>Hello World</h3>`
})
  • Non-props在多节点的时候会失效,用attrs来解决
<script>
    const app = Vue.createApp({
        template: ` 
            <h2>JSPang.com</h2>
            <hello style="color:red;"  msg="jspang" />
            `
    })

    app.component('Hello', {          
        template: `
            <h3 v-bind="$attrs">Hello World</h3>
            <h3 :style="$attrs.style" >Hello World</h3>
            `
    })

    const vm = app.mount("#app")
</script>
  • 在业务逻辑中也是可以用Non-props属性,比如在生命周期中就可以用attrs
app.component('Hello', {
    mounted() {
        console.log(this.$attrs.msg)
    },
    template: `
    <h3 v-bind="$attrs">Hello World</h3>
    <h3 v-bind:style="$attrs.style">Hello World</h3>
    <h3>Hello World</h3>
    `
})

组件之间通过事件进行通信

  • 子组件中如果想改变父组件中的值,就需要调用父组件的事件.父组件中要添加响应事件<counter :counter="counter" @add="handleAddCounter"/>
  • 用emits来调用父组件中的事件 emits: ['add'],
  • param 父组件可以接受子组件中的参数
  • 子组件中可以增加对值得校验
<script>
    const app = Vue.createApp({
        data() {
            return {
                counter: 0
            }
        },
        
        
        // param 来接受子组件的参数
        methods: {
            handleAddCounter(param) {
                console.log(param)
                this.counter = param
            }
        },

        // counter中增加add事件
        template: `
                    <h2>JSPang.com</h2>
                    <counter :counter="counter" @add="handleAddCounter"/>  
             `
    })
    
    // emits调用父组件中的add参数
    app.component('Counter', {
        props: ['counter'],
        // emits: ['add'],
        
        // 对值进行校验,大于20就告警
        emits: {
            add: (value) => {
                return value < 20 ? true : false
            }
        },
        methods: {
            handleClick() {
                this.$emit('add', this.counter + 3)
            },
        },
        template: `
            {{counter}}<button @click="handleClick">增加数量</button>
        `
    })

    const vm = app.mount("#app")
</script>

插槽slot

  • 在子组件中加入slot,在父组件中使用双标签进行调用
  • 插槽中可以使用子组件
  • 插槽中可以使用动态数据
  • 父模板里调用的数据属性,使用的都是父模板里的数据
  • 子模板里调用的数据属性,使用的都是子模板里的数据
<script>
    const app = Vue.createApp({

        data() {
            return {
                jishi: '晓红'
            }
        },

        template: ` 
            <h2>欢迎光临红浪漫-请选择您的技师</h2>
            <ji-shi > 
                <div style="color:red;font-size:50px;">{{jishi}}, <project /></div> 
            </ji-shi>
            <ji-shi > <div style="color:green;font-size:50px;">刘英</div> </ji-shi>
        `
    })

    

    app.component('JiShi', {

        data() {
            return {
                jishi: '谢大脚'
            }
        },

        template: `
            <div>
                <span>经过你的慎重考虑.最终选择了。</span>
                <span>
                    <slot> </slot>
                </span>
            </div>
        `
    })

    app.component('project', {
        template: `<span style="color:blue;">项目是胖哥老三样</span>`
    })

    const vm = app.mount("#app")

</script>
  • 插槽可以添加默认值
  • 可以命名,使用就是
    v-solt:name也可以用简写#name
    const app = Vue.createApp({
        template: ` 
            <h2>欢迎光临红浪漫-请选择您的技师</h2>
            <ji-shi></ji-shi>
            <hong-lang-man>
                <template v-slot:one><div>1.女宾一位,请上三楼。</div></template> // 指定name是one的slot
                <template #two><div>3.顾客选择了全身SPA。</div></template>
            </hong-lang-man>
        `
    })

    app.component('JiShi',{
        template:`
            <div>
                你选择了
                <slot>
                    <span style="color:green;">晓红</span>  // 默认值
                </slot>
                为你服务。
            </div>
        `
    })

    app.component('HongLangMan',{
        template:`
            <div>
                    <slot name="one"></slot>  // 取名为one
                    <div>2.你选择了大脚为你服务</div>
                    <slot name="two"></slot>
            </div>
        `
    })

    const vm = app.mount("#app")
  • 作用域插槽
    • 子组件中有插槽,也有变量,这些变量如何在父组件中进行使用。作用域插槽就是解决这个问题的。
    • 子组件中的信息类型要父组件使用时才能确定,就需要用到作用域插槽,比如标签之类的
    • 父组件中用子组件中的值要用v-bind,确定之后父组件中就可以用v-slot="xxx"的形式接受。
    • props中传递的数据都是对象,要加item。{{props.item}}
    • 简写可以直接v-slot="{item}"
<script>
    const app = Vue.createApp({
        template: `  
            <h2>欢迎光临红浪漫-请选择您的技师</h2>
            <list v-slot="props"> 
                <span>{{props.item}}-{{props}}</span> 
            </list>
        `
        // 简写
        // <list v-slot="{item}"> 
        //     <div>{{item}}</div> 
        // </list>

    })
    app.component('List', {
        data() {
            return {
                list: ['大脚', '刘英', '晓红']
            }
        },
        template: `
            <div>
                <slot v-for="item in list" :item="item">
            </div>
        `
    })

    const vm = app.mount("#app")
  • 动态组件和状态保存
    • <component :is="xxxx" />这样就表示使用动态组件
    • <keep-alive>可以启动缓存,保存信息
<script>
    const app = Vue.createApp({
        data(){
            return {showItem:'dajiao'}
        },

        methods:{
            handleClick(){
                this.showItem= this.showItem=='dajiao'?'liuying':'dajiao'
            }
        },

        template: ` 
            <h2>欢迎光临红浪漫-请选择您的技师</h2> 
            <keep-alive>
                <component :is="showItem" />
            </keep-alive>
            <button @click="handleClick">切换佳丽</button>

        `
    })

    app.component('dajiao',{
        template:`
                <input />
        `
    })

    app.component('liuying',{
        template:`<img src="https://newimg.jspang.com/liuying01.jpg" />`
    })

    const vm = app.mount("#app")
</script>

promise

  • Promise 构造函数只有一个参数,是一个函数,这个函数在构造之后会直接被异步运行,所以我们称之为起始函数。起始函数包含两个参数 resolve 和 reject。
    • 调用 resolve 代表一切正常,reject 是出现异常时所调用的
  • Promise 类有 .then() .catch() 和 .finally() 三个方法,这三个方法的参数都是一个函数
    • .then() 可以将参数中的函数添加到当前 Promise 的正常执行序列
    • .catch() 则是设定 Promise 的异常处理序列,
    • .finally() 是在 Promise 执行的最后一定会执行的序列。
    • .then() 传入的函数会按顺序依次执行,有任何异常都会直接跳到 catch 序列

异步组件

  • 就是要等到相应的条件触发的时候,才会执行,比如等了10秒再执行,这种就是异步组件
  • defineAsyncComponent() 声明一个异步组件
<script>
    const app = Vue.createApp({
        template: `  <div><tongbu /></div>`
    })
    app.component('tongbu',{
        template:`<div>JSPang.com</div>
            <async-component />
        `
    })
    
    app.component('async-component',Vue.defineAsyncComponent(()=>{
    return new Promise((resolve,reject)=>{
            setTimeout(()=>{
                resolve({
                    template:`<div>这是一个异步组件</div>`
                })
            },3000)
        })

    }))

    const vm = app.mount("#app")
</script>

provider和inject多级传值

  • 组件之间有很多层级关系的时候,要传递参数,用props不方便,可以用provider和inject
  • 在最高层中提供了newHouse,在child-child中可以直接用inject接收
<script>
    const app = Vue.createApp({
        data(){
            return {house:'北京别墅一套'}
        },

        provide:{
            newHouse:'北京200平方房子一套'
        },

        template: `
            <div>我有一套房子,我先传给我的儿子</div>
            <child :house="house" />
         `
    })

    app.component('child',{
        props:['house'],
        template:`
            <div>我是子组件,我要把房子再传给我儿子。</div>
            <div>儿子接收{{house}}</div>
            <child-child :house="house" />
        `
    })

    app.component('child-child',{
        props:['house'],
        inject: ['newHouse'],
        template:`
            <div>我是孙子,等待接收房子</div>
            <div>孙子接收{{house}}, {{newHouse}}</div>
        `
    })
    const vm = app.mount("#app")
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 JavaScript 编写的记忆游戏(附源代码)   项目:JavaScript 记忆游戏(附源代码) 记忆检查游戏是一个使用 HTML5、CSS 和 JavaScript 开发的简单项目。这个游戏是关于测试你的短期 记忆技能。玩这个游戏 时,一系列图像会出现在一个盒子形状的区域中 。玩家必须找到两个相同的图像并单击它们以使它们消失。 如何运行游戏? 记忆游戏项目仅包含 HTML、CSS 和 JavaScript。谈到此游戏的功能,用户必须单击两个相同的图像才能使它们消失。 点击卡片或按下键盘键,通过 2 乘 2 旋转来重建鸟儿对,并发现隐藏在下面的图像! 如果翻开的牌面相同(一对),您就赢了,并且该对牌将从游戏中消失! 否则,卡片会自动翻面朝下,您需要重新尝试! 该游戏包含大量的 javascript 以确保游戏正常运行。 如何运行该项目? 要运行此游戏,您不需要任何类型的本地服务器,但需要浏览器。我们建议您使用现代浏览器,如 Google Chrome 和 Mozilla Firefox, 以获得更好、更优化的游戏体验。要玩游戏,首先,通过单击 memorygame-index.html 文件在浏览器中打开游戏。 演示: 该项目为国外大神项目,可以作为毕业设计的项目,也可以作为大作业项目,不用担心代码重复,设计重复等,如果需要对项目进行修改,需要具备一定基础知识。 注意:如果装有360等杀毒软件,可能会出现误报的情况,源码本身并无病毒,使用源码时可以关闭360,或者添加信任。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值