首页 > 其他分享 >pytest学习整理

pytest学习整理

时间:2024-02-28 18:55:16浏览次数:30  
标签:__ 函数 fixture 学习 test pytest 整理 def

一、安装及入门

1.安装及使用条件

  • 支持的python版本:python2.6及以上
  • 支持的平台:Unix、Posix、Windows
  • 安装pytest:pip install –U pytest
  • 查看安装的pytest版本:pytest –version

2.入门小栗子

import pytest

# 被测函数
def fun(x):
    return x + 1

# 测试函数
def test_Fun():
    assert fun(3) == 5

if __name__ == '__main__':
    # 执行测试
    pytest.main()

执行结果:

在这里插入图片描述
可以看到返回了一个断言失败的结果

二、用例运行

1.pytest用例的设计原则

  • 文件名格式符合 test_*.py 及 *_test.py

  • 测试函数以 test_ 开头

  • 测试类以 Test 开头且类中的方法以 test_ 开头,并且类中不能有__init__ 方法

  • 所有的 package 必须要有 __init__.py 文件

2.执行用例的方式

  • 直接使用 pytest 命令会执行当前目录及子目录下所有 test_*.py 及 *_test.py 格式的文件

  • 若想执行指定文件中的测试用例,则可使用 pytest test_files,test_files 表示指定的用例目录或用例文件。例: pytest test_mod.py 或 pytest testing/

  • pytest –k “MyClass and not method” 按关键字表达式运行用例。这将运行包含与表达式匹配的名称的测试用例,匹配的名称可以是文件名、类名、函数名,并支持 python运算符 or 和 and 操作。上面的示例将运行TestMyClass.test_something但不运行TestMyClass.test_method_simple。

  • pytest test_mod.py::test_func 按节点ID运行测试。每次执行收集到的测试用例集合都会被分配一个唯一的nodeid,其中包含模块文件名,后跟说明符,如类名、函数名及参数,由:: 字符分隔。该命令表示执行指定模块中某条指定的测试用例。

  • pytest –m 自定义标记 运行指定mark标记的测试用例。如:pytest –m slow 这将会执行所有带@pytest.mark.slow装饰器的用例

  • pytest -pyargs pkg.testing 导入pkg.testing并使用其文件系统位置来查找和运行测试,简单说就是从包中运行测试。

3.pytest 常用命令行参数

  • -v--verbose 显示更详细的测试结果信息;例:pytest -v test_case.py

  • -q--quiet 启用“静默模式”,只在测试结果失败时显示详细信息,正常运行时不显示测试过程的详细信息。

  • -s--Silent:禁用捕获测试用例的标准输出和标准错误流,将这些输出显示在控制台上,便于调试和查看打印信息。

  • -n=NUM:启用多线程或多进程运行测试用例,需要安装pytest-xdist插件模块。

  • -k=VALUE:用例的nodeid包含VALUE值则该用例被执行。可以使用通配符或正则表达式来构建匹配规则。

  • -m=LABELNAME:仅执行被@pytest.mark.LABELNAME标记的用例。

  • -x--xfail:如果任何一个用例执行失败,则停止当前线程的测试执行。

  • --maxfail=NUM:当用例运行时,允许的最大失败次数为NUM,超过则立即停止执行。

  • --reruns=NUM:失败的用例尝试重跑NUM次。

  • -r char:用于在测试会话结束时显示测试结果摘要;例:pytest -rf test_case.py 表示测试运行时显示 fail 测试结果的详细信息。(char:(f)ailed, (e)rror, (s)kipped, (x)failed, (X)passed, (P)assed, a(ll)...其中 a 表示除了通过以外的所有结果)

更多参数的使用方式及作用可通过 pytest -h 查看

4.测试结果的状态

  • passed:测试通过
  • failed:断言失败;预期的失败结果与测试函数返回的失败结果不一致时,测试结果也是该状态
  • error:测试的程序代码报错
  • xfail:预期失败,测试函数或测试类上加了装饰器 @pytest.mark.xfail()

三、pytest常用

1.assert(断言)的使用

1.1.基础断言:

assert expression :表达式为True时,断言成功,测试结果为 passed;表达式为False时,断言失败,测试结果为 failed。例:

import pytest


def fun(x):
    return x ** 2


def test_fun():
    assert fun(3) == 9


def test_fun2():
    assert fun(4) < 10


if __name__ == "__main__":
    pytest.main()

执行结果:

在这里插入图片描述

1.2. 异常断言:

使用 pytest.raises 作为上下文管理器,当测试函数抛出异常时可以获取到对应的异常实例。例:

def test_zero_division():
    with pytest.raises(ZeroDivisionError):
        1 / 0

执行结果(抛出的错误与预期的错误一致,则执行成功):

在这里插入图片描述


若需要访问测试函数抛出的异常信息,那么可以这样:

import pytest


def zero_division():
    with pytest.raises(ZeroDivisionError) as excinfo:
        1 / 0

	# type, traceback, value 是异常实例的主要属性
    print(excinfo.type)
    print(excinfo.traceback)
    print(excinfo.value)


if __name__ == "__main__":
    zero_division()

执行结果:

在这里插入图片描述

注意:断言 value 值时需要将其转换为 str。如:

import pytest


def test_zero_division():
    with pytest.raises(ZeroDivisionError) as excinfo:
        1 / 0		# 这里是函数表达式

        assert 'zero' in str(excinfo.value)  # 从这里获得值


此外,上下文管理还接受 match 关键字参数,用以匹配表达式中的异常,例如:

import pytest


def fun():
    raise ValueError("exception 123 raised")


def test_fun():
    with pytest.raises(ValueError, match=r'.* 123 .*'):
        fun()

执行结果:

在这里插入图片描述

2.fixture函数

包含unittest的setUp() 和 tearDown() 方法,用于对测试用例做初始化或清扫工作,使用时更灵活。

那么,如何使用它呢?首先我们来看看fixture函数的初始化参数列表,并通过以下例子逐步熟悉使用它吧!

@pytest.fixture(scope = "function",params=None,autouse=False,ids=None,name=None)
def test():
	pass

2.1、scope:function、class、module、package、session

  • 值为session时,表示一次会话(一次运行算一次会话)内该fixture函数只调用一次(如果用到该fixture函数)。

  • 值为package时,表示运行测试时每个包前仅调用一次该fixture函数

  • 值为module时,表示运行测试时每个模块前仅调用一次该fixture函数(在conftest.py时有效,否则只在fixture函数所在模块有效)。

  • 值为class时,表示运行测试时每个测试类前仅调用一次该fixture函数

  • 值为function时,表示运行测试时每个测试函数前调用一次该fixture函数。

注意:范围比较大的 fixture 函数将优先被实例化

小栗子:

# test_fixture.py

import pytest


@pytest.fixture(scope="class")
def return_info():
    print('this is fixture !')
    return 'this is example!'


# 调用fixture
class TestClass:
	# 测试方法(非测试方法不能使用该方式)通过在形参中使用fixture函数名来调用fixture函数并获取其返回值
    def test_case(self, return_info):
        assert 'this' in return_info

    def test_case2(self, return_info):
        assert 'is' in return_info


if __name__ == "__main__":
    pytest.main()

执行结果:

在这里插入图片描述

可看到一个测试类里仅执行了一次 fixture 函数。

将 @pytest.fixture(scope="class") 中的 scope 值改为 "function" 再运行一次:
在这里插入图片描述

可看到该fixture函数执行了两次!


2.2、params

  • Fixture函数的可选形参列表(支持列表传入),默认值为None。

  • params的每个元素都会执行调用一次(每个使用到该fixture函数的函数都会被执行一次)

  • 与参数ids一起使用,作为每次每个元素调用的标识。

小栗子:

import pytest


@pytest.fixture(scope="class", params=[10, 20, 30], ids=['one', 'two', 'three'])
def return_num(request):  # request:pytest内建fixture函数,有字段param,通过request.param 获取注解中传入的params值
    return request.param  # 这里获取值的写法为固定写法


def test_num(return_num):
    print('parm的值为:{}'.format(return_num))
    assert return_num >= 5


if __name__ == '__main__':
    pytest.main()

执行结果:

在这里插入图片描述

2.3、autouse

默认False,表示不自动调用 fixture 函数。值为True时,该fixture函数调用效果根据scope的值而定,当scope的值为“function”时,测试方法执行前调用一次该fixture函数,且测试函数中,不需要传入该fixture函数名(fixture函数有返回值时仍需通过使用fixture函数名来获取返回值)。

小栗子:

import pytest


@pytest.fixture(scope="function", autouse=True)
def return_info():
    print('this is fixture !')
    return 'this is example!'


# 调用fixture
class TestClass:
    def test_case(self, return_info):	# 仍需通过fixture函数名来获取其返回值
        assert 'this' in return_info
	
	# 若无需fixture函数的返回值,则可不写fixture函数名,因autouse为True,此时不写fixture函数名仍可调用该fixture函数
    def test_case2(self):
        assert 'is' in 'this is example!'


if __name__ == "__main__":
    pytest.main()

执行结果:

在这里插入图片描述

2.4、ids

搭配 params 使用,有点用但不多。详见上方 params 例子。

2.5、name

用于在调用fixture函数时,重命名fixture函数名,有点用但不多。

小栗子:

import pytest


@pytest.fixture(name='num')
def return_num():
    return 10


def test_num(num):
    assert num == 20

注意:在调用fixture函数时,只能使用重命名后的函数名num, 使用实际函数名将不会生效

2.6、conftest.py——共享 fixture 函数

可以认为是一个专门存放fixture函数的配置文件,且测试文件(即文件命名符合test_*.py 及 *_test.py)中的测试函数可以直接引用fixture函数名来调用该fixture函数而不需要导入。

小栗子:

# conftest.py
import pytest


@pytest.fixture
def return_num():
    print('这是一个conftest.py中的fixture函数!')
    return 10
# test_case.py
import pytest


def test_num(return_num):
    assert return_num < 100


if __name__ == "__main__":
    pytest.main()

运行测试:
在这里插入图片描述


conftest.py 的特性:

  • conftest.py 文件名称固定,不可更改

  • pytest会默认读取conftest.py里面的所有fixture,因此测试文件中引用时无需导入相关 fixture 函数,非测试文件不可直接引入。

  • 生效范围:只对同一个package下的所有测试用例生效,且不同目录下可拥有各自的 conftest.py 文件;同一目录下,若有多个conftest.py,且拥有同名的fixture函数,那么调用时将只调用离测试文件近的 conftest.py 中的相关fixture函数。

tips:最顶层的 conftest.py 一般用于初始化动作,如接口测试中的登录获取token、WebUI自动化测试中的初始化driver等。


2.7、fixture函数的后置处理

前面所举的例子,都是 setUp() 的处理,接下来我们看看如何实现 tearDown() 。

使用 yield

import pytest


@pytest.fixture(autouse=True)
def exercise_yield():
    print('setUp() 部分')
    yield
    print('tearDown() 部分')


def test_num(return_num):
    assert return_num < 100


if __name__ == "__main__":
    pytest.main()

运行测试:

在这里插入图片描述

可看到yield之前的部分将在测试运行前被执行,之后的部分在测试运行完成后被执行。

注意:yield之前的代码若抛出异常或断言失败,那么yield之后的代码将不会被执行,当然,使用了该fixture函数的测试代码也不会执行

通过request上下文对象的 addfinalizer 方法来完成后置作用

import pytest


@pytest.fixture(scope="class", name='num')
def return_num(request):
    print("setUp代码块")

    def print_one():
        print('tearDown代码块 one')

    def print_two():
        print('tearDown代码块 two')

    request.addfinalizer(print_one)
    request.addfinalizer(print_two)


def test_case():
    assert 1


if __name__ == "__main__":
    pytest.main()

运行测试:

在这里插入图片描述
可看到两个addfinalizer 添加的方法都被执行了。

如果 setUp() 部分出现异常,会不会运行addfinalizer() 方法添加的 tearDown() 代码呢,试试看:

import pytest


@pytest.fixture()
def print_info(request):
    print("setUp代码块")
    print(1 / 0)

    def print_one():
        print('tearDown代码块 one')

    request.addfinalizer(print_one)


def test_exercise(print_info):
    assert 1


if __name__ == "__main__":
    pytest.main()

运行测试:
在这里插入图片描述

答案是不会。这里我稍微有点疑惑,很多答案都说,终结函数 addfinalizer() 函数即使 setUp() 代码部分抛出异常或断言失败时仍可执行 tearDown() 部分的代码,但实践来看,和yield并无区别,希望有大佬来解答我的疑惑。

两相比较,使用yield 看起来更简洁,终结函数 addfinalizer() 则可添加多个tearDown() 的处理函数。

3.mark 的使用

3.1、常见内置标记

通过使用 pytest.mark 你可以轻松地在测试用例上设置标记。常用的内置标记如下:

  • skip -始终跳过该测试用例。用法:在测试用例前添加装饰器 @pytest.mark.skip(reason) ,可传入的可选参数 reason 表示自定义的描述(关于为什么跳过的描述)
    当想要跳过整个模块的用例时,在模块代码中可以用:@pytest.skip(reason, allow_module_level=True)

  • skipif -遇到特定情况下跳过该测试用例。
    用法:@pytest.mark.skipif(条件表达式, reason),如果条件表达式为True,那么就会跳过该用例。

  • usefixtures -使用指定的fixture方法
    用法:@pytest.mark.usefixtures(fixture函数名称)
    注意:用此方式使用fixture函数时,无法获取其返回值,必须使用fixture函数名的方式获取其返回值

  • xfail -遇到特定情况,产生一个“期望失败“的输出,直接使用时,测试通过则标记为XPASS,失败则标记为XFAIL。
    用法:@pytest.mark.xfail(condition = None,reason = None,raises = None,run = True,strict = False)
    condition(bool):bool表达式
    reason(str):标记为xfail的原因
    raises(str):期望由测试函数引发的异常,异常若对应则通过测试,不对应无法通过测试
    run(bool):如果值为False,那么被标记的函数将不会被执行,并始终标记为xfail
    strict(bool):值为False,该函数将在终端输出中显示,并且无论被标记的测试是否通过,都不会导致测试套件整体失败;值为True,被标记的函数在终端输出显示中为xfailed,如果意外地通过测试,将使整体测试套件失败。

  • parametrize -在同一个测试用例上运行多次调用(数据驱动/参数化)。

注意:标记仅对测试用例有效。对fixture函数无效


3.2、自定义标记

在测试用例函数上可以打上自定义的标记,运行测试用例时,可以通过标签名来过滤要运行的测试用例:@pytest.mark.标记名
示例:

import pytest


@pytest.mark.smoke
def test_case_01():
    print('mark is smoke')
    assert 1


@pytest.mark.webtest
def test_case_02():
    print('no smoke,this is webtest')
    assert 1

运行测试 pytest -m "smoke" :
在这里插入图片描述

可看到只执行了标记为 “smoke”的测试。测试结果中出现了warnings,这是因为自定义的标记未注册。

注册自定义标记

  • 第一种方法:使用 pytest.ini 文件,该文件须和测试用例在同一个目录,或者在根目录下作用于全局。
# pytest.ini
[pytest]
markers =
    smoke
    webtest

若运行测试时出现错误:UnicodeDecodeError: 'gbk' codec can't decode byte 0xaa in position 48: illegal multibyte sequence 这是解决方法

  • 第二种方法:在 conftest.py 文件中使用如下钩子函数注册自定义标记
def pytest_configure(config):
    marker_list = ["smoke: this is smoke mark", "webtest"]
    # 注册自定义标记
    for marker in marker_list:
        config.addinivalue_line("markers", marker)

执行两个自定义标记的测试用例:

pytest –m "smoke or webtest"

运行结果:
在这里插入图片描述


4.参数化

有时我们需要使用不同的值对一个接口进行重复的测试,这时就需要进行参数化了,接下来让我们看看几种常见的参数化方式。

4.1、标记参数化

@pytest.mark.parametrize
用法:在用例类/方法前加上@pytest.mark.parametrize(‘参数名‘,参数列表/参数字典)

  • 使用列表:
import pytest


@pytest.mark.parametrize('int_type, float_type', [(10, 9.99), (100, 99.9)])  # 第一种传入多组参数的示例
def test_print(int_type, float_type):
    print(int_type)
    print(float_type)
    assert 1


parametrize = [(66, 66.66), (99, 99.99)]


@pytest.mark.parametrize('int_type, float_type', parametrize)  # 第二种传入多组参数的示例
def test_print_02(int_type, float_type):
    print(int_type)
    print(float_type)
    assert 1

使用列表时,还可装饰多个@pytest.mark.parametrize 进行参数间的排列组合测试:
# -*- coding:utf8 -*-
import pytest


@pytest.mark.parametrize('x', [1, 2])
@pytest.mark.parametrize('y', [3, 4])
def test_01(x, y):
    assert x * y % 2 == 0


if __name__ == "__main__":
    pytest.main()

  • 使用字典:
# -*- coding:utf8 -*-
import pytest

test_dict = [{'质数': 2}, {'水仙花数': 153}, {'完全数': 28}]


@pytest.mark.parametrize('case_dict', test_dict)
def test_print(case_dict):
    num_name = [key for key in case_dict.keys()]
    num_value = [value for value in case_dict.values()]
    print('特殊数名:%s, 举例:%s' % (num_name, num_value))
    assert 1

运行测试:
在这里插入图片描述

4.2、使用fixture函数进行参数化

# -*- coding:utf8 -*-
import pytest


@pytest.fixture(params=[33, 99])
def request_params(request):
    return request.param


def test_01(request_params):
    assert request_params ** 2 % 3 == 0

运行测试:
在这里插入图片描述

5.常用的pytest配置(pytest.ini文件的使用)

pytest.ini:pytest的配置文件,一个项目中仅存一个,且固定名字不可更改,若需使其作用于全局,则须将其放在项目根目录下。

5.1、markers

用于注册自定义标记:

[pytest]
markers =
    markers_one: this is markers_one
    markers_two
    markers_three

5.2、addopts

用于设置自定义执行参数,pytest运行时以此设置为默认执行条件

[pytest]
# 表示默认执行pytest时显示详细输出、不捕获标准输出,并且每个用例失败时重跑两次
addopts = -v -s --reruns=2

5.3、testpaths

定义测试文件存放路径。pytest会按照此配置去指定路径下寻找测试文件。

[pytest]
# 表示在当前目录下的test文件夹中查找测试文件
testpaths = ./test

5.4、自定义用例执行规则

[pytest]
# 表示pytest会执行所有以test开头的文件
python_files = test*.py
# 表示pytest会执行所有以Test开头的类
python_classes = Test*
# 表示pytest会执行所有以test开头的函数
python_functions = test*

5.5、xfail_strict

用于设置当预期失败的测试用例实际通过时是否应视为错误。如果设置为True,则预期失败的测试用例如果实际通过,将被视为错误。

[pytest]
# 值可设置为 True, False, 0, 1
xfail_strict = True

5.6、log_cli 和 log_cli_level

用于配置pytest的命令行日志记录。log_cli控制是否启用日志记录,而log_cli_level设置日志级别(如DEBUG, INFO, WARNING, ERROR, CRITICAL)

[pytest]
# 值可设置为 True, False, 0, 1
log_cli = True  
log_cli_level = INFO

平时测试自己写的自动化测试代码时有用,真正批量运行时不建议使用。

5.7、cache_dir

指定pytest缓存的目录,用于在多次运行之间缓存测试结果,加速测试执行。

[pytest]
cache_dir = .pytest_cache



可通过cmd命令 pytest --help 查看更多配置项的使用:

[pytest] ini-options in the first pytest.ini|tox.ini|setup.cfg file found:

  markers (linelist):   markers for test functions
  empty_parameter_set_mark (string):
                        default marker for empty parametersets
  norecursedirs (args): directory patterns to avoid for recursion
  testpaths (args):     directories to search for tests when no files or directories are given in the command line.
  filterwarnings (linelist):
                        Each line specifies a pattern for warnings.filterwarnings. Processed after -W/--pythonwarnings.
  usefixtures (args):   list of default fixtures to be used with this project
  python_files (args):  glob-style file patterns for Python test module discovery
  python_classes (args):
                        prefixes or glob names for Python test class discovery
  python_functions (args):
                        prefixes or glob names for Python test function and method discovery
  disable_test_id_escaping_and_forfeit_all_rights_to_community_support (bool):
                        disable string escape non-ascii characters, might cause unwanted side effects(use at your own
                        risk)
  console_output_style (string):
                        console output: "classic", or with additional progress information ("progress" (percentage) |
                        "count").
  xfail_strict (bool):  default for the strict parameter of xfail markers when not given explicitly (default: False)
  enable_assertion_pass_hook (bool):
                        Enables the pytest_assertion_pass hook.Make sure to delete any previously generated pyc cache
                        files.
  junit_suite_name (string):
                        Test suite name for JUnit report
  junit_logging (string):
                        Write captured log messages to JUnit report: one of no|log|system-out|system-err|out-err|all
  junit_log_passing_tests (bool):
                        Capture log information for passing tests to JUnit report:
  junit_duration_report (string):
                        Duration time to report: one of total|call
  junit_family (string):
                        Emit XML for schema: one of legacy|xunit1|xunit2
  doctest_optionflags (args):
                        option flags for doctests
  doctest_encoding (string):
                        encoding used for doctest files
  cache_dir (string):   cache directory path.
  log_level (string):   default value for --log-level
  log_format (string):  default value for --log-format
  log_date_format (string):
                        default value for --log-date-format
  log_cli (bool):       enable log display during test run (also known as "live logging").
  log_cli_level (string):
                        default value for --log-cli-level
  log_cli_format (string):
                        default value for --log-cli-format
  log_cli_date_format (string):
                        default value for --log-cli-date-format
  log_file (string):    default value for --log-file
  log_file_level (string):
                        default value for --log-file-level
  log_file_format (string):
                        default value for --log-file-format
  log_file_date_format (string):
                        default value for --log-file-date-format
  log_auto_indent (string):
                        default value for --log-auto-indent
  faulthandler_timeout (string):
                        Dump the traceback of all threads if a test takes more than TIMEOUT seconds to finish.
  addopts (args):       extra command line options
  minversion (string):  minimally required pytest version
  required_plugins (args):
                        plugins that must be present for pytest to run

最后,附 pytest官方文档地址pytest中文官方文档地址

标签:__,函数,fixture,学习,test,pytest,整理,def
From: https://www.cnblogs.com/cicadaLuo/p/18041457

相关文章

  • 苹果取消电动汽车项目;英伟达 CEO 黄仁勋寄语:学习编程价值大幅降低丨 RTE 开发者日报 V
      开发者朋友们大家好: 这里是「RTE开发者日报」,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享RTE(RealTimeEngagement)领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「有看点的会议」,但内容仅代表编辑......
  • 假期vue学习笔记13 插槽
     <template>  <divclass="category">    <h3>{{title}}分类</h3>    <slot></slot>  </div></template><script>  exportdefault{    name:'Category',    pr......
  • 假期vue学习笔记14 求和案例vue版本
     <template>  <div>    <h1>当前求和为:{{sum}}</h1>    <selectv-model.number="n">      <optionvalue="1">1</option>      <optionvalue="2">2</option>......
  • 假期vue学习笔记15 求和mapstate_mapgetter
     importVuefrom'vue'importAppfrom'./App.vue'importstorefrom'./store'Vue.config.productionTip=falsenewVue({  el:'#root',  render:h=>h(App),  store,  beforeCreate(){    Vue.......
  • 假期vue学习笔记16 vuex多组数据共享
     <template>  <div>    <h1>当前求和为:{{sum}}</h1>    <h1>十倍的和为:{{bigSum}}</h1>    <h1>{{xuexiao}}</h1>    <h1>{{xueke}}</h1>    <h3>下方总人数为:{{$store.state.personList......
  • 假期vue学习笔记07 todo事件的本地存储
     用本地存储改写前面的todo案例 <template>    <li>      <label>        <inputtype="checkbox":checked="todo.done"@change="handleCheck(todo.id)"/>        <spanv-show="!tod......
  • MATLAB深度学习工具箱的应用
    一、MATLAB深度学习工具箱    MATLAB深度学习工具箱是一个功能强大的工具包,用于构建、训练和部署深度学习模型。它提供了各种深度学习网络和算法,包括卷积神经网络、循环神经网络、自编码器、生成对抗网络等。    MATLAB深度学习工具箱还提供了许多有用的工具和函......
  • 如何让计算机学习
    计算机学习是让计算机自己进行学习,在计算机学习中,我们使用学习程序让计算机读取大量数据并根据数据特诊自己进行学习。本章中,针对手写数字识别问题,我们会使用支持向量机算法,我们会使用scikit-learn这个机械学习库,只需要几行代码就可以体验机器学习。SVM是一种机器学习算法,它的全称......
  • 假期vue学习笔记08 绑定和解绑
     <template>  <divclass="app">    <h1>{{msg}}</h1>    <!--props子给父传递事件-->    <School:getSchoolName="getSchoolName"/>    <!--通过父组件给子组件绑定一个自定义事件实现:子给父传递数据(第一种写法,使用@过v-......
  • 假期vue学习笔记09 全局事件总栈
     <template>  <div class="school">    <h2>学校名称:{{name}}</h2>     <h2>学校地址:{{address}}</h2>  </div></template><script>  exportdefault{    name:'School'......