• Vue-(4)


    内容概览

    • 计算属性(computed)
    • 监听属性(watch)
    • 组件介绍与定义
    • 父子通信
    • ref属性
    • 动态组件
    • 插槽
    • vue-cli

    计算属性(computed)

    如果在插值语法中直接填入函数:{{func()}},那么每次页面刷新,函数都会重新执行
    计算属性将函数当做属性来使用,缓存了数据;当数据发生改变才执行函数更新数据

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Titletitle>
        <script src="./js/vue.js">script>
    head>
    <body>
    <div id="app">
        <input type="text" v-model="name1">--{{handleUpper()}}
        <hr>
        <input type="text" v-model="name2">--{{upper}}
    div>
    body>
    <script>
        let vm = new Vue({
            el: "#app",
            data: {
                name1: '',
                name2: '',
            },
            methods: {
                handleUpper() {
                    // 页面每次刷新都会变化
                    console.log('函数执行')
                    return this.name1.slice(0, 1).toUpperCase() + this.name1.slice(1).toLowerCase()
                }
            },
            computed: {
                upper() {
                    // 只有计算属性中使用的变量发生变化,函数参会重新运算
                    console.log('计算属性执行')
                    return this.name2.slice(0, 1).toUpperCase() + this.name2.slice(1).toLowerCase()
                }
            }
        })
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    根据计算属性重写过滤案例
    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Titletitle>
        <script src="./js/vue.js">script>
    head>
    <body>
    <div id="app">
        <h1>过滤案例h1>
        <p><input type="text" v-model="search" placeholder="请输入要搜索的内容">p>
        <ul>
            <li v-for="item in newdataList">{{item}}li>
        ul>
    div>
    body>
    <script>
        let vm = new Vue({
            el: "#app",
            data: {
                search: '',
                dataList: ['a', 'at', 'atom', 'be', 'beyond', 'cs', 'csrf', 'd', 'dddd',],
            },
            computed: {
                newdataList() {
                    return this.dataList.filter(item => item.indexOf(this.search) >= 0)
                }
            }
        })
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    监听属性(watch)

    监听一个属性的变化,只要他发生变化就触发一个函数的执行
    函数需要接收一个参数,参数是修改后的值

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Titletitle>
        <script src="./js/vue.js">script>
    head>
    <body>
    <div id="app">
        <span>
            <button @click="type='语文'">语文button>
            <button @click="type='数学'">数学button>
            <button @click="type='英语'">英语button>
        span>
        <hr>
        {{type}}
    div>
    body>
    <script>
        let vm = new Vue({
            el: "#app",
            data: {
                type: ''
            },
            watch: {
                type(item) {
                    console.log('监听属性执行了,修改值为:', item)
                }
            }
        })
    script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    组件介绍和定义

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

    • 定义组件:
      1. 全局组件:全局都可以使用,可以用在任意其他组件中
      2. 局部组件:只能在定义的组件中使用
    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Titletitle>
        <script src="./js/vue.js">script>
    head>
    <body>
    <div id="app">
        <h1>全局组件h1>
        <child>child>
        <hr>
        <h1>局部组件h1>
        <child1>child1>
    div>
    body>
    <script>
        // 定义一个全局组件(必须在一个标签中),组件有自己的数据,方法,生命周期
        let obj = {
            template: `
              
    {{ title }}
    `
    , data() { return { title: '全局组件child' } }, methods: { handleClick() { alert('xxx') } } } Vue.component('child', obj) // obj可以写在外边也可以写在括号内 // 定义局部组件 let child1 = { template: `
    {{ msg }}
    `
    , data() { return { msg: 'vm中的组件' } }, components: { child2: { template: `
    {{ msg }}
    `
    , data() { return { msg: 'vm的组件child1中的组件' } } } } } let vm = new Vue({ el: "#app", data: { type: '' }, components: { child1 // 'child1':child1 --简化--> child1:child1 --简化--> child // es6的对象写法 } })
    script> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77

    父子通信

    组件与组件之间,数据、方法等都是独立的,其他组件无法直接使用

    父传子

    使用自定义变量实现

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Titletitle>
        <script src="./js/vue.js">script>
    head>
    <body>
    <div id="app">
        <h1>自定义属性实现父传子h1>
        {{msg}}
        <child :message="msg">child>
    div>
    body>
    <script>
        let child = {
            template: `
              

    vm中的child组件

    {{ message }}
    `
    , // props: ['message'] // 接收自定义变量,可以传入多个变量 props: { message: String, // props写成对象,可以指定数据类型 } } let vm = new Vue({ el: "#app", data: { msg: 'vm中的msg变量' }, components: { child } })
    script> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    子传父

    使用自定义事件实现

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Titletitle>
        <script src="./js/vue.js">script>
    head>
    <body>
    <div id="app">
        <h1>自定义事件实现子传父h1>
        父组件中的msg值=={{msg}}
        <hr>
        <child @myevent="handleEvent">child>
        <hr>
    div>
    body>
    <script>
        let child = {
            template: `
              

    vm中的child组件

    name ----{{ name }}
    `
    , data() { return { name: '' } }, methods: { handleSend() { // 在这里触发父组件中的自定义事件执行,并将参数传入 this.$emit('myevent', this.name) // 第一个值为自定义事件的名字,然后传入参数 } } } let vm = new Vue({ el: "#app", data: { msg: 'vm中的msg变量' }, components: { child }, methods: { handleEvent(name) { this.msg = name } } })
    script> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    ref属性

    # ref属性,vue定义的
    	-可以放在普通标签上,通过this.$refs.自定义的名字取到的是 原生的dom对象
    		-使用原生dom操作(不推荐)
        -可以放在组件上:通过this.$refs.自定义的名字取到的是 vc对象(组件对象)-可以之间使用组件对象上的方法和属性---》子的数据给了父亲
            -父组件有个方法执行,需要传参数,传入子组件的数据---》子的数据给了父亲
            -拿到子对象之间使用父中的数据修改----》父传子
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Titletitle>
        <script src="./js/vue.js">script>
    head>
    <body>
    <div id="app">
        <h1>ref属性放在普通标签上h1>
        <input type="text" ref="myinput" v-model="name"> ----> {{name}}
        <button @click="handlePrint">点击button>
        <hr>
        <h1>ref属性放在组件上h1>
        <child ref="mychild">child>
    
    div>
    body>
    <script>
        let child = {
            template: `
              
    {{ name }}
    `
    , data() { return { name: 'child的name' } }, methods: { handleAlert(name) { alert(name) } } } let vm = new Vue({ el: "#app", data: { name: '' }, components: { child }, methods: { handlePrint() { // console.log(this.$refs.myinput) // 原生dom对象 // this.$refs.myinput.value='xxx' // 通过dom修改input框的value值 console.log(this.$refs) console.log(this.$refs.mychild) // Vc对象 // this.$refs.mychild.name = 'xxx' // 修改组件中的变量 // this.name = this.$refs.mychild.name // 获取组件中的值 this.$refs.mychild.handleAlert(this.name) // 执行组件中的函数 } } })
    script> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    动态组件

    案例:点击不同标签,显示不同组件

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Titletitle>
        <script src="./js/vue.js">script>
    head>
    <body>
    <div id="app">
        <div>
            <span @click="type='home'">首页span>
            <span @click="type='goods'">商品span>
            <span @click="type='order'">订单span>
        div>
        <div>
        
            <component :is="type">component>
        div>
    div>
    body>
    <script>
        // 定义第三个全局组件
        Vue.component('home', {
            template: `
              

    首页

    `
    , }) Vue.component('goods', { template: `

    商品

    `
    , }) Vue.component('order', { template: `

    订单

    `
    , }) let vm = new Vue({ el: "#app", data: { type: 'home' }, })
    script> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    keep-alive
    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Titletitle>
        <script src="./js/vue.js">script>
    head>
    <body>
    <div id="app">
        <div>
            <span @click="type='home'">首页span>
            <span @click="type='goods'">商品span>
            <span @click="type='order'">订单span>
        div>
        <div>
            <keep-alive>  
                <component :is="type">component>
            keep-alive>
        div>
    div>
    body>
    <script>
        // 定义第三个全局组件
        Vue.component('home', {
            template: `
              

    首页

    `
    , }) Vue.component('goods', { template: `

    商品

    `
    , }) Vue.component('order', { template: `

    订单

    `
    , }) let vm = new Vue({ el: "#app", data: { type: 'home' }, })
    script> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    插槽

    在组件标签中插入标签,在组件模板中接收

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Titletitle>
        <script src="./js/vue.js">script>
    head>
    <body>
    <div id="app">
        <h1>插槽的使用h1>
        <home>
            <img src="https://img0.baidu.com/it/u=3947432154,2892596664&fm=253&fmt=auto&app=138&f=JPEG?w=658&h=404"
                 alt="">
        home>
        <goods>
            <div slot="bottom">底部div>
            <div v-slot=top>顶部div>  
        goods>
    div>
    body>
    <script>
        Vue.component('home', {
            template: `
              

    首页

    `
    , // 在slot的位置上插入组件标签中的内容 }) Vue.component('goods', { template: `

    商品

    `
    , // 有多个标签也可以使用name来选择位置插入 }) let vm = new Vue({ el: "#app", })
    script> html>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    vue-cli

    # vue的脚手架:快速帮我们创建出vue的项目
    # vue2 和 vue3 
    	-vue-cli可以创建vue2和vue3的项目    webpack构建工具
        -Vite:新一代构建工具
        -vue3上,推荐使用ts写  js
        
        
    # 先安装nodejs 后端语言---》语法就是js的语法
    	-js运行在浏览器中,浏览器中有它的解释器环境
        -不能运行在操作系统之上,把chrom浏览器的v8引擎,把它安装在操作系统上
        	-c语言写了内置库:文件操作,网络操作
            
        -官网:https://nodejs.org/zh-cn/download/ ,下载,一路下一步
        -安装完会释放两个命令(在环境变量中,任意路径都能敲这俩命令)
        	-node      python3
            -npm        pip
            -cnpm      等同于pip ,只是下模块,直接取淘宝镜像站下载,速度快
        
     # npm 下载时候,去国外,速度慢,使用国内镜像
    	-淘宝做了一个cnpm可执行文件,用来替换npm,以后所有使用npm的地方都换成cnpm即可
        -安装cnpm 
        npm install -g cnpm --registry=https://registry.npm.taobao.org
      
            
     # 安装vue-cli ,通过脚手架创建vue项目 (django--->django项目--->django-admin)
     	cnpm install -g @vue/cli
        -只要装成功,又会多出一个可执行文件  vue  
        
     # 创建vue项目
    	vue create myfirstvue
        
        
        
     # ide的选择(vscode,webstorm:jetbrains公司的,跟pycharm一家的,使用习惯一样)
    	-选择使用pycharm+vue插件 开发vue项目
        -使用pycharm打开vue项目
        
     # 运行vue项目
    	-方式一:在命令行中敲:npm run serve
        -方式二:在pycharm中点击绿色箭头运行
        
        
        
     #cnpm install axios
    
    """ cnpm : 无法加载文件 XXX ,因为在此系统上禁止运行脚本。有关详细信息,请参阅 https
    :/go.microsoft.com/fwlink/?LinkID=135170 中的 about_Execution_Policies。
    解决方法:管理员模式打开PowerShell,输入set-executionpolicy remotesigned
    选择y
    """
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    练习

    # 获取所有图书接口drf写,处理跨域(响应头)
    # 前端vue项目首页,只要加载好就获取所有图书v-for循环显示在页面上
    
    • 1
    • 2
    • django:
    """urls"""
    from django.contrib import admin
    from django.urls import path, include
    from rest_framework.routers import SimpleRouter
    from app01 import views
    
    router = SimpleRouter()
    router.register('books', views.BookView, 'books')
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('', include(router.urls))
    ]
    
    """models"""
    from django.db import models
    
    class Books(models.Model):
        title = models.CharField(max_length=32)
        price = models.CharField(max_length=32)
    
    """serializer"""
    from rest_framework import serializers
    from app01.models import Books
    
    class BookSerializer(serializers.ModelSerializer):
        class Meta:
            model = Books
            fields = '__all__'
    
    """views"""
    from rest_framework.viewsets import ReadOnlyModelViewSet
    from app01.models import Books
    from app01.serializers import BookSerializer
    
    
    class BookView(ReadOnlyModelViewSet):
        queryset = Books.objects.all()
        serializer_class = BookSerializer
    
        def list(self, request, *args, **kwargs):
            response = super().list(request, *args, **kwargs)
            response['Access-Control-Allow-Origin'] = '*'
            return response
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • vue
    <template>
      <div class="home">
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
        <div class="container-fluid">
          <div class="row">
            <div class="col-md-6 col-md-offset-3">
              <table class="table table-hover">
                <thead>
                <tr>
                  <th class="text-center">idth>
                  <th class="text-center">书名th>
                  <th class="text-center">价格th>
                tr>
                thead>
                <tbody>
                <tr v-for="book in booksDetail">
                  <th scope="row" class="text-center">{{ book.id }}th>
                  <td>{{ book.title }}td>
                  <td>{{ book.price }}td>
                tr>
                tbody>
              table>
            div>
          div>
        div>
    
      div>
    template>
    
    <script>
    import axios from 'axios'
    
    export default {
      name: 'HomeView',
      data() {
        return {
          booksDetail: []
        }
      },
      created() {
        axios.get('http://127.0.0.1:8000/books/').then(res => {
          this.booksDetail = res.data
          // console.log(res.data)
        })
      }
    }
    script>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
  • 相关阅读:
    手机数据恢复应用程序有哪些?手机数据恢复免费软件排名TOP 9
    HOWTO:在 Tomcat 中抑制服务器身份
    数据图册页面(左边一列图片缩略图,右边展示图片大图)
    SPA项目开发之首页导航+左侧菜单
    【C++ 设计模式】面向对象设计原则 & Template Method 模式 & Strategy 策略模式
    【Vue 开发实战】实战篇 # 45:如何构建可交互的组件文档让代码高亮的显示在页面
    unity图片`fillAmount`填充方法
    2023/9/9总结
    iOS pod repo push 报错 ld: file not found: libarclite_iphoneos.a 问题解决方案
    个人课设---玩家血条(包括攻击掉血,复活重生功能)
  • 原文地址:https://blog.csdn.net/AL_QX/article/details/127578515