如果在插值语法中直接填入函数:{{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>
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>
监听一个属性的变化,只要他发生变化就触发一个函数的执行
函数需要接收一个参数,参数是修改后的值
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>
扩展HTML元素,封装需要重复使用的代码
例如:有一个轮播,可以在很多页面中使用,一个轮播有js,css,html
组件把js,css,html放到一起,有逻辑,有样式,有html
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>
组件与组件之间,数据、方法等都是独立的,其他组件无法直接使用
使用自定义变量实现
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>
使用自定义事件实现
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>
# ref属性,vue定义的
-可以放在普通标签上,通过this.$refs.自定义的名字取到的是 原生的dom对象
-使用原生dom操作(不推荐)
-可以放在组件上:通过this.$refs.自定义的名字取到的是 vc对象(组件对象),
-可以之间使用组件对象上的方法和属性---》子的数据给了父亲
-父组件有个方法执行,需要传参数,传入子组件的数据---》子的数据给了父亲
-拿到子对象之间使用父中的数据修改----》父传子
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>
案例:点击不同标签,显示不同组件
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>
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>
在组件标签中插入标签,在组件模板中接收
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>
# 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
"""
# 获取所有图书接口drf写,处理跨域(响应头)
# 前端vue项目首页,只要加载好就获取所有图书v-for循环显示在页面上
"""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
<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>