首页 > 其他分享 >vue5

vue5

时间:2023-02-17 22:13:19浏览次数:33  
标签:age var vue5 new 组件 home data

今日内容概要

  • 组件的补充知识
  • 组件间通信之父传子
  • ref属性
  • 动态组件
  • 插槽
  • 计算属性
  • 监听属性
  • node环境搭建

今日内容详细

组件的补充知识

new Vue()对象后 管理的标签 叫做根组件

Vue.component()	创建出来的是全局组件 定义在其内部或vue对象内部的components产生的是局部组件

组件拥有自己的html css js包括各自的数据 事件等
在组件内部 this代指当前组件
父子组件的data是无法共享的
组件的data是一个函数 需要有返回值(return {})

组件间通信之父传子

由于组件间数据不共享 想要进行数据传递 那么需要一些方式

父传子:使用自定义属性的方式 自定义属性名不要使用驼峰体
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="vue/vue.js"></script>
    <script src="axios/axios.js"></script>
</head>
<body>

    <div id="app">

        <h2>我是父组件 有一个子组件child</h2>
        <child :myname="name"></child>
        <!--  注意 自定义属性的时候不要使用驼峰体 并且不要与子组件中的变量名起冲突  -->

<!--        <h1>属性验证  传入的必须是xx类型</h1>-->
        <h2>字符串的age-->age="age"</h2>
<!--        <child myname="彭于晏" age="age"></child>-->
        <h2>:age="19"的形式</h2>
<!--        <child :age="19" myname="彭于晏"></child>-->
        <h2>age="19"的形式</h2>
<!--        <child age="19" myname="彭于晏"></child>-->
        <h2>:age="age"的形式</h2>
<!--        <child :age="age" myname="彭于晏"></child>-->

    </div>

    <script>
        var vm = new Vue({
            el: '#app',
            data:{name: 'lzj', age: 20},
            components:{'child': {
                template: `
                <div>
                    <h1>我是子组件</h1>
                    <h2>姓名:{{myname}}</h2>
                    <h2>年龄:{{age}}</h2>

                </div>
                `,
                    data(){
                    return {age: 18}
                    },
                // props:['myname'] // 需要接收需要的字段 如果父组件给子组件传了相同名字的数据 优先使用父组件的 后台会报错 不影响渲染
                props:{myname: String, age:Number} // 指定数据类型 虽然指定了 但传的时候也可以是其他类型 并且正常渲染 但是后台会报错
                }}
        })
    </script>

</body>
</html>

组件通信之子传父

子传父通过自定义事件的形式
并且自定义事件的名字也不能够使用驼峰体
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="vue/vue.js"></script>
    <script src="axios/axios.js"></script>

</head>
<body>

<div id="app">

    <br>
    <h3>子组件发送的内容----input输入:{{mytext}}  age:{{age}}</h3>
    <br>

    <child @childtxt="MyEvent"></child>

</div>

<script>
    var child = {
        template: `
          <div>
          <h1>我是子组件</h1>
          <input type="text" v-model="mytext">
          <!--     可以通过事件触发发送 也可以在生命周期钩子函数中传递     -->
          <button @click="childClick">点我发送</button>
          </div>
        `,
        data() {
            return {mytext: '', age:18}
        },
        methods: {
            childClick() {
                // 使用$emit触发父组件中的自定义事件 并将要传递父组件的数据传入
                this.$emit('childtxt', this.mytext)
            }
        },
        // 使用生命周期的钩子函数传递
        updated(){
            this.$emit('childtxt', this.mytext, this.age)
        }
    }


    var vm = new Vue({
        el: '#app',
        data: {mytext: '', age: ''},
        methods: {
            // 自定义事件触发执行的函数 子组件发送几个就要接收几个
            MyEvent(mytext, age) {
                this.mytext = mytext
                this.age = age
            }
        },
        components: {
            child
        }
    })
</script>
</body>
</html>

ref属性

自定义属性和自定义事件可以实现父子之间的传值 但还有一种方式可以更加方便的实现父子通信

ref属性
	把ref属性放在普通标签上 
		通过this.$refs.ref属性值 拿到的是原生的dom对象 可以使用它来修改标签
	把ref属性放在组件上
		通过this.$refs.ref属性值 拿到的是组件对象 并且组件对象中的变量 方法等都能够取到
		这样无论是子传父还是父传子 都可以通过组件对象直接使用
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="vue/vue.js"></script>
    <script src="axios/axios.js"></script>

</head>
<body>
    <div id="app">
        <hr>
        <h1>我是父组件</h1>
        <h2>子组件的msg:{{msg}}</h2>
        <hr>
        <!--    给子组件添加ref属性    -->
        <child ref="childtext"></child>
        <button @click="showChild">点我看子组件input</button>
    </div>

    <script>
        var child = {
        template: `
          <div>
          <h1>我是子组件</h1>
          <h2>父组件的name:{{name}}</h2>
          <input type="text" v-model="mytext">
          </div>
        `,
        data() {
            return {mytext: '', msg: '鸡你太美', name:''}
        },
        methods: {
            showText(){
                alert(this.msg)
            }
        },
    }

        var vm = new Vue({
            el: '#app',
            data: {msg: '', name: '蔡徐坤'},
            methods: {
                showChild(){
                    console.log(this.$refs)
                    // 通过this.$refs.childtext拿到该组件对象
                    // 可以取到组件对象的数据
                    alert(this.$refs.childtext.mytext)
                    // 也可以直接调用组件对象的函数
                    this.$refs.childtext.showText()
                    // 子传父
                    this.msg = this.$refs.childtext.msg
                    console.log(this.msg)
                    // 父传子
                    this.$refs.childtext.name = this.name
                    console.log(this.name)
                    // 之后无需关注子传父还是父传子 直接通过对象取值 赋值即可
                }
            },
            components: {
                child
            }
        })
    </script>
</body>
</html>

动态组件

手动实现动态组件

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

</head>
<body>
<div id="app">
    <!--  通过点击事件 将对应组件名传入 并修改data中who的值  -->
    <span @click="pageClick('home')">首页</span>
    <span @click="pageClick('order')">订单</span>
    <span @click="pageClick('goods')">商品</span>
    <!--  判断当前是哪个组件 来展示指定组件  -->
    <home v-if="who === 'home'"></home>
    <order v-else-if="who === 'order'"></order>
    <goods v-else></goods>
</div>

<script>
    // 定义三个局部组件
    var home = {
        template: `
          <div>
          <h1>home页面</h1>
          </div>`
    }

    var order = {
        template: `
          <div>
          <h1>order页面</h1>
          </div>`
    }

    var goods = {
        template: `
          <div>
          <h1>goods页面</h1>
          </div>`
    }

    var vm = new Vue({
        el: '#app',
        data:{
            who: 'home'
        },
        methods:{
            pageClick(who){
                this.who = who
            }
        },
        components:{
            home,
            order,
            goods
        }
    })
</script>
</body>
</html>

使用动态组件

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

</head>
<body>
<div id="app">
    <!--  通过点击事件 将对应组件名传入 并修改data中who的值  -->
    <span @click="pageClick('home')">首页</span>
    <span @click="pageClick('order')">订单</span>
    <span @click="pageClick('goods')">商品</span>
    <!--  通过component标签实现 无需手动写判断 当前的who是谁就展示  -->
    <component :is="who"></component>
</div>

<script>
    // 定义三个局部组件
    var home = {
        template: `
          <div>
          <h1>home页面</h1>
          </div>`
    }

    var order = {
        template: `
          <div>
          <h1>order页面</h1>
          </div>`
    }

    var goods = {
        template: `
          <div>
          <h1>goods页面</h1>
          </div>`
    }

    var vm = new Vue({
        el: '#app',
        data:{
            who: home
        },
        methods:{
            pageClick(who){
                this.who = who
            }
        },
        components:{
            home,
            order,
            goods
        }
    })
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="vue/vue.js"></script>
    <script src="axios/axios.js"></script>

</head>
<body>
<div id="app">
    <!--  通过点击事件 将对应组件名传入 并修改data中who的值  -->
    <span @click="pageClick('home')">首页</span>
    <span @click="pageClick('order')">订单</span>
    <span @click="pageClick('goods')">商品</span>
    <!--  将动态组件包裹在keep-alive标签内 会保持组件的激活 切换动态组件的时候会保持切换前的状态  -->
    <keep-alive>
        <!--  通过component标签实现 无需手动写判断 当前的who是谁就展示  -->
        <component :is="who"></component>
    </keep-alive>

</div>

<script>
    // 定义三个局部组件
    var home = {
        template: `
          <div>
          <h1>home页面</h1>
          </div>`
    }

    var order = {
        template: `
          <div>
          <h1>order页面</h1>
          </div>`
    }

    var goods = {
        template: `
          <div>
          <h1>goods页面</h1>
          <input type="text">
          <button>搜索</button>
          </div>`
    }

    var vm = new Vue({
        el: '#app',
        data:{
            who: home
        },
        methods:{
            pageClick(who){
                this.who = who
            }
        },
        components:{
            home,
            order,
            goods
        }
    })
</script>
</body>
</html>

插槽

一般情况下 编写完一个组件之后 组件的内容都是写死的 如果需要加载数据 那么只能去组件中修改 扩展性很差 

继而出现了插槽的概念 只需要在组件中添加<solt></slot>标签 后续就可以在组件标签内部添加内容
与 django中的extend相似

匿名插槽

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

</head>
<body>
<div id="app">

    <home>
        <!-- 当前是匿名插槽 所以如果组件内部有多个匿名的slot 那么都会展示组件标签内扩展的所有内容 -->
        <img src="333.jpeg" alt="">
    </home>
</div>


<script>
    var home = {
        template: `
        <div >
            <h1>home组件</h1>
            <!--      添加slot标签 后续添加的内容在这块区域      -->
            <slot></slot>
            <hr>

            <slot></slot>
            <h1>home组件结束</h1>
        </div>
        `
    }

    var vm = new Vue({
        el: '#app',
        data:{},
        components:{
            home
        }
    })
</script>
</body>
</html>

具名插槽

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

</head>
<body>
<div id="app">

    <home>
        <!-- 在对应标签中添加slot属性那么就会在指定插槽中展示 通常使用div包裹 这样无需添加多次该属性 -->
        <div slot="a">
            <img src="333.jpeg" alt="">
        </div>
        <!--  多个标签使用并不会覆盖 而是会按照顺序依次往下  -->
        <div slot="a">
            <img src="222.jpeg" alt="">
        </div>
        
    </home>
</div>


<script>
    var home = {
        template: `
        <div >
            <h1>home组件</h1>
            <!-- 给slot添加name属性 就变成了具名插槽 -->
            <slot name="a"></slot>
            <hr>

            <slot name="b"></slot>
            <h1>home组件结束</h1>
        </div>
        `
    }

    var vm = new Vue({
        el: '#app',
        data:{},
        components:{
            home
        }
    })
</script>
</body>
</html>

计算属性

计算属性只有使用的变量发生了变化时才会重新运算
和python中的property类似 可以把方法 函数 伪装成属性
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="vue/vue.js"></script>
    <script src="axios/axios.js"></script>

</head>
<body>
<div id="app">
    体重:
    <input type="text" v-model="weight">
    身高:
    <input type="text" v-model="height">

    BMI:{{BMI}}
</div>

<script>
    var vm = new Vue({
        el: '#app',
        data: {
            weight: '',
            height: '',
        },
        // 计算属性写在computed中 以函数的形式 后续使用使用函数名即可
        computed:{
            BMI(){
                console.log('计算属性执行了')
                if (this.weight && this.height){
                    return (this.weight / Math.pow(this.height, 2)).toFixed(1)
                }else {
                    return 0
                }

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

基于计算属性重写过滤案例

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

</head>
<body>
<div id="app">
    <input type="text" v-model="myText">

    <ul>
        <!-- 直接使用计算属性的返回值 -->
        <li v-for="i in textInput">
            {{i}}
        </li>
    </ul>
</div>

<script>
    var vm = new Vue({
        el: '#app',
        data:{
            myText: '',
            dataList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf'],
        },
        methods: {},
        computed:{
            textInput(){
                // 该计算属性中使用了input框的myText 是双向绑定的数据 会变化 也就会重复调用该方法
                return this.dataList.filter(item => item.indexOf(this.myText) >= 0)
            }
        }
    })
</script>
</body>
</html>

监听属性

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="vue/vue.js"></script>
    <link rel="stylesheet" href="bootstrap-3.4.1-dist/css/bootstrap.min.css">
    <!--    <script src="bootstrap-3.4.1-dist/js/bootstrap.min.js"></script>-->
    <script src="axios/axios.js"></script>

</head>
<body>
<div id="shop">
    <div class="container-fluid">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <h1 class="text-center">购物车</h1>
                <!-- 通过事件冒泡处理切换用户 清空选择列表及全选 -->
                <div @click="new_list=[]" style="width: 110px">
                    <div @click="all=false">
                        <!-- 给按钮绑定点击事件 点击不同按钮user_id是不同的值 -->
                        <button @click="user_id=i.car" v-for="i in all_user">{{i.name}}</button>
                    </div>
                </div>
                <div v-if="user_id">
                    <table class="table table-hover" >
                    <thead>
                    <tr>
                        <th>商品编号:</th>
                        <th>商品名:</th>
                        <th>数量:</th>
                        <th>单价:</th>
                        <th><span v-if="all">取消全选</span>
                            <span v-else>全选</span>
                            <input type="checkbox" v-model="all" @click="allClick">
                        </th>
                    </tr>
                    </thead>
                    <tbody>
                    <tr v-for="(goods, index) in goods_list">
                        <th scope="row">{{index + 1}}</th>
                        <td>{{goods.name}}</td>
                        <td>
                            <button @click="clickDown(goods, index)">-</button>
                            {{goods.num}}
                            <button @click="clickUp(goods)">+</button>
                        </td>
                        <td>{{goods.price}}</td>
                        <td>
                            选择<input type="checkbox" v-model="new_list" :value="goods" @change="goodsClick">
                        </td>
                    </tr>

                    </tbody>

                </table>
                    <h2>总价{{allMoney}}</h2>
                </div>


            </div>
        </div>
    </div>


</div>
<script>
    var vm = new Vue({
        el: '#shop',
        data: {
            goods_list: [{name: '保时捷', num: 2, price: 999, stock: 10}, {
                name: '法拉利',
                num: 3,
                price: 1000,
                stock: 8
            }, {
                name: '兰博基尼',
                num: 1,
                price: 1000,
                stock: 12
            }],
            new_list: [],
            all: false,
            user_id: ''
        },
        methods: {
            clickUp(good) {
                if (good.num < good.stock) {
                    good.num++
                } else {
                    alert(`库存不足` + good.stock)
                }
            },
            clickDown(good, index) {
                if (good.num > 1) {
                    good.num--
                } else {
                    var yes = confirm('再减就删除了 确定吗')
                    if (yes) {
                        for (i in this.new_list) {
                            if (this.new_list[i] === good) {
                                this.new_list.splice(i, 1)
                            }
                        }
                        this.goods_list.splice(index, 1)
                    }

                }
            },
            goodsClick() {
                if (this.new_list.length === this.goods_list.length) {
                    this.all = true
                } else {
                    this.all = false
                }

            },
            // 全选
            allClick() {
                if (this.all) {
                    this.new_list = []
                } else {
                    this.new_list = this.goods_list
                }

            },
            // 从后端获取数据函数
            getData(a) {
                // 判断用户id是否有值 有值再去后端取数据
                if (this.user_id) {
                    axios.get('http://127.0.0.1:8000/shop_car/' + a + '/').then(res => {
                        this.goods_list = res.data.shop_car
                    })
                }
            }
        },
        // 计算属性
        computed:{
            allMoney(){
                var all = 0
                for (i of this.new_list) {
                    all += i.price * i.num
                }
                return all
            }
        },
        // 监听属性 内部填写以被监听属性为名字的函数 一旦对应属性被修改 就会执行对应函数
        watch:{
            user_id(){
                // 传进去的是要查看用户的购物车id
                this.getData(this.user_id)
            }
        },
        // 生命周期钩子函数
        created() {
            axios.get('http://127.0.0.1:8000/user/').then(res => {
                this.all_user = res.data
        }
    })
</script>
</body>
</html>

node环境搭建

# Vue-CLI 项目搭建
	-vue 脚手架  可以创建vue项目
    
    
# vue脚手架必须要按照 node js   解释型语言
	-node js是一门后端语言
    -JavaScript只能运行在浏览器中,因为浏览器中有他的解释器环境
    -基于谷歌浏览器的v8引擎(js解释器),使它能够运行在操作系统上
    	-文件操作
        -网络操作
        -数据库操作  模块
        
        
        
   -nodejs 解释器环境
	-http://nodejs.cn/  下载对应平台的nodejs解释器
    -一路下一步安装
    -安装完成会有两个可执行问题
    	python    node 
        pip       npm
        
    -打开cmd
     node  进入到了node环境
     npm install 装模块

标签:age,var,vue5,new,组件,home,data
From: https://www.cnblogs.com/lzjjjj/p/17131612.html

相关文章