15、电脑相关、移动端基础(术语|长度单位|设备像素|倍图)、vant-ui相关、微信公众平台、微信小程序-目录说明|WXML语法|WXS语法|事件系统|组件|自定义组件|API、uniapp跨端框架-简介|教程|组件|全局文件、postcss.config.js(2750行)
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 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 | 附、电脑相关 (1)查看命令行:win+r; cmd; 确定 (2)查看电脑配置:win+r; msinfo32; 确定 (3)windows10系统输入法切换的快捷键设置步骤:至少有2种输入法同时备用 A、开始-齿轮-时间和语言-语言-中文(简体中国)-选项-(添加键盘-微软拼音-)微软拼音-选项-按键-模式切换 (4)搜狗输入法的快捷键界面:S图标-更多设置-属性设置-按键 A、中英切换 B、系统功能快捷键-系统功能快捷键设置 (5)广告屏保的位置与删除 A、重启 B、此电脑-(上方中间的)查看-显示-隐藏的项目 C、打开,C:\Users\制造商(NINGMEI)\AppData\Local\Temp D、删除该位置下的所有文件 (6)谷歌截全屏的步骤 A、F12 B、ctrl+shift+p C、输入full D、点击Capture full size screenshot 另,免费在线网页转图片,https: //www.url2pic.com/url2pic/index.html (7)postcss-pxtorem,px转rem 一、移动端基础 1、移动端的常用术语 (1)Uni,统一的,读you ni (2)IDE,集成开发环境(Integrated Development Environment),如vscode (3)SDK,软件开发工具包(Software Development Kit),软件开发时,开发工具的集合,通常由编译器、调试器和应用编程接口组成 (4)uniCloud,基于serverless的云开发平台,为开发者提供免费服务器,由DCloud(数字天堂)、阿里云、腾讯云三者联合实现 2、移动端的长度单位(vw、vh、vmin、vmax、%、em、rem、dp、pt、rpx、dot、dpi、ppi、Retina) 附、px,通用长度单位,像素,pixel,/ˈpɪksl/ (1)通用 A、vw,viewpoint width,视窗宽度,1vw等于视窗宽度的1%,如width: calc(100vw - 260px);font-size: 5vw; B、vh,viewpoint height,视窗高度,1vh等于视窗高度的1%,如height: calc(100vh - 260px);font-size: 5vh; C、vmin,vw和vh中较小的那个,font-size: vw,文字在横、竖屏下,大小不一致 D、vmax,vw和vh中较大的那个,font-size: vmax,文字在横、竖屏下,大小一致 E、%,相对于父元素的尺寸 F、em,相对于父字体大小 G、rem,相对于根字体大小 (2)专用 A、dp,Android长度单位, 'ppi/160' px;sp,Android字体大小单位 B、pt,IOS长度单位, 'ppi/163' px;自然界的长度单位,1/72英寸,0.35毫米 C、rpx,微信长度单位,1rpx=1/750的屏宽 (3)其它 A、dot,点,印刷品的最小单位 B、dpi,点密度,每英寸屏幕所包含的点数,Dots per inch C、ppi,像素密度,每英寸屏幕所包含的像素数,Pixels per inch D、retina display技术,视网膜显示技术,就是像素密度大一些而已 iPhone6将一个像素点分拆为四个像素进行显示,像素密度提高4倍,达到326ppi,超过人眼能区分的最大像素密度300ppi //简单说就是,一个物理像素占位面积小一点,单位面积物理像素多一点;用pxtorem后,字体占位面积不变,但因包含像素多,因而更清晰=====文字、图片===== 附、rem,示例 <style> //根字体定义一 html { font-size: 20px; } //根字体定义二 :root { font-size: 20px; } </style> <script> //根字体定义三 var designWidth = 1000 ; document.documentElement.style.fontSize = document.documentElement.clientWidth/designWidth+ "px" ; //代码尺寸为1rem,对应设计稿尺寸为1px </script> //postcss.config.js里的相关配置 require( 'postcss-pxtorem' )({ //px转rem rootValue: 37.5, //对应设计图宽度375px propList: [ '*' ], //将哪些属性的px值转换 }) 3、物理像素比 (1)像素,显示屏图像或CSS图像的最小单位,单位是px,包含 A、物理像素 B、逻辑像素 (2)物理像素,也叫设备像素,显示屏的最小可控制单元 附、分辨率,纵横方向的物理像素点数 A、1K显示屏(分辨率,1920*1080) B、2K显示屏(分辨率,2560*1440) C、4K显示屏(分辨率,3840*2160) (3)逻辑像素,也叫CSS像素,CSS的最小可控制单元,正常情况下,1个物理像素显示1个逻辑像素 (4)物理像素比,也叫设备像素比(window.devicePixelRatio),物理像素/逻辑像素,含义是几个物理像素显示1个逻辑像素 A、公司4K、21.5寸屏幕,1个物理像素小,缩放设为200%,2个物理像素显示1个逻辑像素;媒体查询2k,左300,右970,中间剩余像素 B、住处4K、43.0寸屏幕,1个物理像素大,缩放设为100%,1个物理像素显示1个逻辑像素;媒体查询4k,左200,右485,中间剩余像素 C、综合分辨率、尺寸、缩放后,上面两者字体大小一样 D、console.log(window.devicePixelRatio) 4、倍图(是正常像素密度的几倍,就用几倍图) (1)正常情况下的对应关系 A、一倍图:设计稿1,宽度750*1px;分辨率1,x*y B、二倍图:设计稿2,宽度750*2px;分辨率2,2x*2y C、三倍图:设计稿3,宽度750*3px;分辨率3,3x*3y D、四倍图:设计稿4,宽度750*4px;分辨率4,4x*4y,如iPhone6,其物理像素比为1, (2)真实项目:一张设计稿3,适配分辨率1、分辨率2、分辨率3、的显示屏, A、处理方案1,给1种分辨率写1套代码,先判断屏幕分辨率,再导入代码 分辨率1显示屏的div宽高用设计稿尺寸的1/3,背景图片用设计稿原图片尺寸的100%填充 分辨率2显示屏的div宽高用设计稿尺寸的2/3,背景图片用设计稿原图片尺寸的100%填充 分辨率3显示屏的div宽高用设计稿尺寸的3/3,背景图片用设计稿原图片尺寸的100%填充 B、处理方案2,以px为单位,用postcss-pxtorem把px转换成rem,使各种分辨率,如安卓、IOS的屏幕,显示相同效果 div宽高用设计稿尺寸的1/3,背景图片用设计稿原图片尺寸的100%填充 附、代码,背景图片用设计稿原图片尺寸的100%填充, //=====文字、图片===== //下面,设计稿1的图片放在分辨率1的显示屏上,效果是1个逻辑像素被放到1个物理像素里显示;像素密度不变,正常显示 //下面,设计稿2的图片放在分辨率1的显示屏上,效果是4个逻辑像素被压缩到1个物理像素里显示;像素密度不变,正常显示 //下面,设计稿2的图片放在分辨率2的显示屏上,效果是1个逻辑像素被放到1个物理像素里显示;像素密度变大,高清显示 background-image: url(example@2x.png) no-repeat; background-size: 100% auto; 5、特别注意 (1)移动端项目 A、各个页面的跳转关系 B、数据临时存储与清除 C、静态数据的来源(设计稿或后台) (2)存储临时数据,以备后退时使用 A、确定时,用localStorage存储数据 B、后退时,用localStorage获取数据 C、提交后,用localStorage删除数据 D、也可以用vuex存储、获取、删除数据 (3)iPhone12pro max,跳到新网页,新网页的位置没到顶 A、原因:跳转前的网页没到顶,浏览器把前网页的位置用在后网页上 B、解决:document.body.scrollTop=0; document.documentElement.scrollTop=0; 二、vant-ui相关 1、<input type= "value" > (1)button,定义可点击按钮(多数情况下,用于通过 JavaScript 启动脚本) (2)checkbox,定义复选框 (3)file,定义输入字段和 "浏览" 按钮,供文件上传 (4)hidden,定义隐藏的输入字段,发送表单的时候,隐藏域的信息也被一起发送到服务器, https: //blog.csdn.net/weixin_38098192/article/details/90265302 (5)image,定义图像形式的提交按钮 (6)password,定义密码字段,该字段中的字符被掩码 (7)radio,定义单选按钮 (8)reset,定义重置按钮,重置按钮会清除表单中的所有数据 (9)submit,定义提交按钮,提交按钮会把表单数据发送到服务器 (10)text,定义单行的输入字段,用户可在其中输入文本,默认宽度为20个字符 2、深度选择器 当<style scoped>只作用于当前组件中的元素,可采用下列方式影响到子组件 附、全局样式 <style> .wrap .child { color: red; } </style> (1)本页样式 >>> ,原生css支持,sass/less可能无法识别 <style scoped> .wrap >>> .child { color: red; } </style> (2)本页样式 /deep/ ,sass/less可识别,在vue 3.0会报错 <style scoped> .wrap /deep/ .child { color: red; } </style> (3)本页样式 ::v-deep ,vue 3.0支持,编译速度快 <style scoped> .wrap ::v-deep .child { color: red; } </style> 3、vant-ui动态内容 (1)notify 消息提示,没有遮罩,页面顶部显示,有样式变化,3秒后自动消失 (2)toast 轻提示,没有遮罩,页面居中显示,无样式变化,3秒后自动消失 (3)NoticeBar 通知栏,没有遮罩,固定位置显示,有样式变化,不消失 (4)Popover 气泡弹出框,没有遮罩,点击处显示,会基于reference插槽的内容进行定位,常用于下拉选项, (5)overlay 遮罩层,全屏罩住 (6)popup 弹出层,有遮罩,常用触底显示,确认后消失,常用于省市县、日期选择 (7)dialog 弹出框,有遮罩,常用居中显示,确认后消失 4、van-field (1)输入框,正常 (2)文本框,type= "textarea" (3)下拉框的逻辑 输入框禁用,右侧添加三角, 点击事件让下方气泡popup出现、传出序号、计算-从总数据中找出的相关数据-成下拉选项, 点击事件从自身数据中找出的相关数据-成为下拉选项,气泡popup出现 点击确定时,给对应的v-model赋值,气泡消失 (4)其它,用input插槽, 自定义输入框,使用此插槽后,与输入框相关的属性和事件将失效 在Form组件进行表单校验时,会使用input插槽中子组件的value,而不是Field组件的value (5)<van-uploader/>的部分属性 capture,图片选取模式,可选值为camera,直接调起摄像头 after-read,文件读取完成后的回调函数 before-read,文件读取前的回调函数,返回 false 可终止文件读取,支持返回Promise 4、Rule数据结构,只有一个对象项的数组 (1)required,是否为必选字段,boolean (2)message,错误提示文案 (3)trigger,本项规则的触发时机,可选值为onChange、onBlur (4)formatter,格式化函数,将表单项的值转换后,再用“pattern”或“validator”进行校验 (5)pattern,通过正则表达式进行校验,返回值为 false 时,红色的message出现在输入框的下方 (6)validator,通过函数进行校验,返回值为 false 时,机制让红色的message出现在输入框的下方; 返回值为promise实例时,机制向其注入resolve、reject,在reject里让红色的message出现在输入框的下方 validator:function(rule, val, callback) { return new Promise(function(resolve, reject) { setTimeout(function() { const dataNum = Date.now() if (dataNum % 2 === 0) { resolve( '成功' ) } else { reject( '失败' ) } }, 2000) }) } 5、插槽input示例 (1)html部分 <van-form @submit= "beforeSubmit" ref = "form" > <template v- for = "(item,idx) in formList" > <div class = "sign-form" :key= "idx" v- if = "item.inputType == 0" > <van-field name= "name" :rules= "[{ validator: valiFormData, message: '请输入正确内容',index:idx }]" show-word-limit :label= "item.topicName" v-model= "formData[idx]" :placeholder= "'请输入'+item.topicName" :maxlength= "item.numLimit" /> </div> <div class = "sign-form" :key= "idx" v- if = "item.inputType == 1" > <van-field rows= "4" :rules= "[{ validator: valiFormData, message: '请输入正确内容',index:idx }]" autosize v-model= "formData[idx]" :label= "item.topicName" type= "textarea" show-word-limit /> </div> <div class = "sign-form" :key= "idx" v- if = "item.inputType == 2" > <van-field :label= "item.topicName" v-model= "formData[idx]" right-icon= "arrow-down" readonly placeholder= "请选择" :rules= "[{ validator: valiFormData, message: '请输入正确内容',index:idx }]" @click= "changeCol(idx)" /> </div> <div class = "sign-form" :key= "idx" v- if = "item.inputType == 3 && item.isCheckbox == 0" > <van-field :label= "item.topicName" :rules= "[{ validator: valiFormData, message: '请输入正确内容',index:idx }]" > <template #input> <van-radio- group v-model= "formData[idx]" direction= "horizontal" class = "hor-style" > <van-radio v- for = "(v,k) in JSON.parse(item.optionInfo)" :name= "v.option" :key= "k" >{{v.option}}</van-radio> </van-radio- group > </template> </van-field> </div> <div class = "sign-form" :key= "idx" v- if = "item.inputType == 3 && item.isCheckbox == 1" > <van-field :label= "item.topicName" :rules= "[{ validator: valiFormData, message: '请输入正确内容',index:idx }]" > <template #input> <van-checkbox- group v-model= "formData[idx]" :max= "item.selectLimitMax ? item.selectLimitMax : 0" direction= "horizontal" > <van-checkbox v- for = "(value,key) in JSON.parse(item.optionInfo)" :name= "value.option" shape= "square" :key= "key" >{{value.option}}</van-checkbox> </van-checkbox- group > </template> </van-field> </div> <div class = "sign-form" :key= "idx" v- if = "item.inputType == 4" > <div class = "van-form_card" > <div class = "field__label" >{{item.topicName}}</div> <div class = "field__desc" >支持“图片”扩展名:png、gif、jpeg、pcx、psd、tiff</div> </div> <van-field name= "name" type= "hidden" :rules= "[{ validator: valiFormData, message: '请输入正确内容',index:idx }]" v-model= "formData[idx]" > <template #input> <div class = "upload-preview" > <van-image v- if = "formData[idx]" width= "4rem" height= "3rem" fit= "contain" :src= "formData[idx]" /> <van-uploader :before-read= "uploadFile" accept= "image/png,image/gif,image/jpeg,image/pcx,image/psd,image/tiff" :name= "idx" > <van-icon name= "plus" /> </van-uploader> </div> </template> </van-field> </div> <div class = "sign-form" :key= "idx" v- if = "item.inputType == 5" > <div class = "van-form_card" > <div class = "field__label" >{{item.topicName}}</div> <div class = "field__desc" >支持“视频”扩展名:avi、MP4、rmvb</div> </div> <van-field name= "name" type= "hidden" :rules= "[{ validator: valiFormData, message: '请输入正确内容',index:idx }]" v-model= "formData[idx]" > <template #input> <div class = "flex-col" > <div class = "video-upload" v- if = "showUpload" > <span>视频上传中...</span> <van-progress :show-pivot= "false" :percentage= "videoUploadPercent" /> </div> <span class = "link" v- if = "formData[idx]" @click= "href(idx)" >{{videoName[idx]}}</span> <van-uploader :before-read= "uploadVideo" accept= "*" v- if = "!showUpload" :name= "idx" > <van-button icon= "plus" type= "primary" >上传视频</van-button> </van-uploader> </div> </template> </van-field> </div> <div class = "sign-form" :key= "idx" v- if = "item.inputType == 6" > <div class = "van-form_card" > <div class = "field__label" >{{item.topicName}}</div> <div class = "field__desc" >支持“文件”扩展名:doc、docx、txt、pdf、pptx、ppt、xlsx、xls</div> </div> <van-field name= "name" type= "hidden" :rules= "[{ validator: valiFormData, message: '请选择',index:idx }]" v-model= "formData[idx]" > <template #input> <div class = "flex-col" > <span class = "link" v- if = "formData[idx]" @click= "href(idx)" >{{formData[idx]}}</span> <van-uploader :before-read= "uploadFile" accept= ".doc, .docx, .txt, .pdf, .pptx, .ppt, .xlsx, .xls" :name= "idx" > <van-button icon= "plus" type= "primary" >上传文档</van-button> </van-uploader> </div> </template> </van-field> </div> <div class = "sign-form" :key= "idx" v- if = "item.inputType == 7" > <van-field readonly @click= "clickDatePicker(idx)" name= "name" :rules= "[{ validator: valiFormData, message: '请选择日期',index:idx }]" :label= "item.topicName" v-model= "formData[idx]" :placeholder= "'请选择'+item.topicName" /> <van-popup v-model= "showDatePicker" position= "bottom" > <van-picker show-toolbar title= "选择日期" :columns= "dateCol" @cancel= "showDatePicker = false" @confirm= "dateConfirm" /> </van-popup> <!-- van-popup默认在兄级加蒙层van-overlay,若没有出现,可能有人在项目的全局给清除了 --> </div> </template> <div class = "vt-foot " > <van-button :loading= "loading" loading-text= "保存中..." native-type= "submit" block color= "#fdb235" >提交</van-button> <!-- native-type,原生button标签的type属性,表单内点击此按钮,自动触发表单的onsubmit事件 --> <!-- loading,设置按钮为加载状态,加载状态下默认会隐藏按钮文字 --> <!-- loading-text,设置加载状态下的文字 --> </div> </van-form> (2)js部分 A、上传图片 uploadFile(file, detail) { let formData = new FormData(); formData.append( 'file' , file); axios.post( this .$upload, formData, { 'Content-Type' : 'multipart/form-data' }) .then(res => { if (res.data && res.data.code === 10000) { this .formData[detail.name] = res.data.data; let temp = res.data.data; this .formData.splice(detail.name, 1, temp); } else { this .$dialog.alert({ title: '提示' , message: '上传文件失败' , theme: 'round-button' , }) .then(() => { //on close }); } }) }, B、上传视频 来源,https: //help.aliyun.com/document_detail/383952.html import OSS from "ali-oss" ; //开放存储服务(OpenStorageService,简称OSS),是阿里云对外提供的海量,安全,低成本,高可靠的云存储服务。 //用户可以通过简单的API(REST方式的接口),在任何时间、任何地点、任何互联网设备上进行数据上传和下载。 <van-uploader accept= "*" v- if = "!showUpload" :name= "idx" :before-read= "uploadVideo" > <van-button icon= "plus" type= "primary" >上传视频</van-button> </van-uploader> uploadVideo(file, detail) { let type = file.name.substring(file.name.lastIndexOf( "." ) + 1) .toLowerCase() if ( this .videoType.indexOf(type) < 0 || file.type.indexOf( "video" ) < 0) { this .$dialog.alert({ title: '提示' , message: '仅支持 .avi, .mp4, .rmvb, .mov 格式的视频' , theme: 'round-button' , }); return ; } let max = 1024 * 1024 * 1024; if (file.size > max) { this .$dialog.alert({ title: '提示' , message: '上传视频大小不能超过 1G!' , theme: 'round-button' , }) .then(() => {}); return ; } myRequest({ tokenName: "ios" , }) .then(data => { let client = new OSS({ region: "oss-cn-beijing" , accessKeyId: data.data.data.accessKeyId, accessKeySecret: data.data.data.accessKeySecret, bucket: data.data.data.bucketName, stsToken: data.data.data.securityToken, }); const suffix = file.name.substr(file.name.indexOf( "." )); let fileUrl = `test/${ new Date().getTime()}${suffix}`; client .multipartUpload(fileUrl, file, { progress: (p) => { this .videoUploadPercent = Math.round(p * 100); this .showUpload = true ; }, partSize: 102400, }) .then((res) => { this .showUpload = false ; this .videoName[detail.name] = res.name; let url = res.res.requestUrls[0]; this .formData[detail.name] = url.substring(0, url.indexOf( "?" )); let temp = this .formData[detail.name]; this .formData.splice(detail.name, 1, temp); }) . catch ((err) => { this .showUpload = false ; console.log(err); this .$dialog.alert({ title: '提示' , message: '上传失败' , theme: 'round-button' , }) }); }) } 三、微信公众平台账号 附、简称 A、“微信账号”简称“微信号” B、“微信公众平台账号”简称“平台号” 1、重要网址 (1)开发 A、开发文档,https: //developers.weixin.qq.com/miniprogram/dev/framework/ B、开发者工具,https: //developers.weixin.qq.com/miniprogram/dev/devtools/devtools.html C、开通微信开发者.代码管理,https: //developers.weixin.qq.com/miniprogram/dev/devtools/wechatvcs.html (2)注册、登录、git仓库 A、注册网址,https: //mp.weixin.qq.com/ 微信十种产品,https: //developers.weixin.qq.com/doc/ 四种微信公众号,https: //mp.weixin.qq.com/cgi-bin/registermidpage?action=index&lang=zh_CN, 小程序发布流程,https: //mp.weixin.qq.com/wxamp/home/guide?token=1509394140 B、登录网址,https: //mp.weixin.qq.com/ 管理后台,https: //mp.weixin.qq.com/wxamp/home/guide 开发版本,https: //mp.weixin.qq.com/wxamp/wacodepage/getcodepage C、git仓库网址,https: //git.weixin.qq.com/ 四种微信公众号的任意1种账号注册成功,都会生成该仓库网址,该仓库与微信号关联,不会随公众号注销而注销 2、四种微信公众号 附、四种微信公众号网址,https: //mp.weixin.qq.com/cgi-bin/registermidpage?action=index&lang=zh_CN, (1)订阅号 (2)服务号 (3)小程序(微信小程序-后面详细介绍) (4)企业微信(原企业号) 3、微信公众号账号注册 附、注册网址,https: //mp.weixin.qq.com/ (1)点击“立即注册” (2)点击“4种类型中的1种” (3)如果点击的是“小程序”,那么还需要在跳转后的页面点击“前往注册” (4)填写邮箱、密码、验证码、勾选同意、点击注册, A、每个邮箱仅能申请一个小程序==========非常重要=========== B、作为登录账号,请填写未被微信公众平台注册,未被微信开放平台注册,未被个人微信号绑定的邮箱 (5)点击登录邮箱、登录邮箱、点击邮箱里的链接 A、注册国家/地区:中国大陆;主体类型:个人; B、身份证姓名、身份证号码、管理员手机号码、短信验证码、管理员身份验证(微信扫一扫)、继续,其中微信扫一扫 把微信号与微信小程序号关联起来 1个微信号能关联5个公众号==========非常重要=========== C、请确认以下提交的主体信息、确定 D、信息提交成功,前往小程序(管理后台),见7 4、小程序账号注销 附、登录网址,https: //mp.weixin.qq.com/ (1)登录小程序的管理员账号 (2)如果提示该账号已冻结,则根据提示进行解冻 (3)如果尚无AppID(小程序ID),则需要先进行“AppID生成” (4)管理后台-点击(左下方)“设置”-点击(页面中间)“账号信息”里的“账号注销”按钮,(微信号的)公众平台安全助手-收到注销信息 (5)0-6*24小时内,可以电脑登录,取消注销 (6)6*24--14*24小时之间,可以电脑登录,取消注销或确认注销,逾期不确认账号将恢复正常, (7)如果不取消注销或确认注销,那么从 7*24小时开始,每隔24小时,在-微信号的公众平台安全助手,都会收到注销确认信息,直到取消注销或确认注销或达到7次 (8)确认注销后,微信扫一扫登录,不再出现该账号 5、小程序账号的作用 (1)生成(小程序)管理后台 A、管理项目版本,管理开发者 B、1个小程序账号,其管理后台只能存储1个小程序项目的3个版本,供发布 (2)生成存储仓库 A、存储项目代码 B、1个小程序账号,其git仓库能存储多个小程序项目的代码,供开发 6、小程序开发者工具的作用 (1)把小程序体验版-存储到管理后台 (2)把小程序代码-存储到git仓库 附、开发小程序 A、搜索,点击放大镜图标或者ctrl+shift+f B、编辑,点击文件图标 7、小程序管理后台-目录 附、登录网址,https: //mp.weixin.qq.com/ 附、管理后台网址,https: //mp.weixin.qq.com/wxamp/home/guide (1)小程序账号登录,下面两种登录任选一种 A、使用账号登录,邮箱/微信号 B、微信扫一扫登录,扫后会出现该微信号关联的所有公众号,点击其中一个(登录) (2)登录成功,前往小程序(管理后台),其导航如下 (3)首页 A、小程序信息 未填写 //1/3,此处可生成AppID(小程序ID) 补充小程序的基本信息,如名称、图标、描述等 B、小程序类目 未补充 补充小程序的服务类目,设置主营类目 C、小程序备案 未备案 需先填写小程序信息和类目 补充小程序的备案信息,检测是否满足备案条件 D、微信认证 未完善 完成微信认证后,账号可获得“被搜索”和“被分享”能力。未完成微信认证不影响后续版本发布 E、小程序开发与管理 自己开发 开发工具 添加开发者==========非常重要=========== 找服务商开发 立即前往(按钮) (4)管理 A、版本管理 线上版本:尚未提交线上版本 审核版本:你暂无提交审核的版本或者版本已发布上线 开发版本:你尚未上传任何开发版本,可前往开发者工具上传代码。查看介绍, 开发版本:版本号;版本信息;提交审核,下拉(选为体验版本,删除);点击“提交审核/选为体验版本/删除” B、成员管理==========非常重要=========== (5)开发 A、开发管理 开发设置 开发者ID 开发者ID,操作 AppID(小程序ID),wxd9d363f25a //2/3,此处可生成AppID(小程序ID) AppSecret(小程序密钥),生成 小程序代码上传,开发者可基于配置信息调用微信开发者工具提供的代码上传模块。查看详情 配置信息,操作 小程序代码上传密钥,生成 IP白名单,暂无IP白名单,编辑 服务器域名(以下略) 接口设置 B、开发工具 (6)设置 A、基本设置 基本信息 账号信息 AppID(小程序ID),wxd9d363f25a //3/3,此处可生成AppID(小程序ID) 登录邮箱 B、第三方设置 8、小程序管理后台-小程序项目-从创建到保存 //以下操作位置:微信开发者工具 (1)创建 A、首次创建,点击(左上方)项目-扫描二维码-确认登录 B、再次创建,点击(左上方)项目-新建项目/导入项目 (2)填写AppID, 附、以下是AppID生成与获取步骤,任选其一 A、小程序管理后台-首页-小程序信息 B、小程序管理后台-开发-开发管理-开发设置-开发者ID C、小程序管理后台-设置-基本设置-账号信息 (3)勾选用户协议 (4)其它默认 (5)确定 (6)编辑文件 (7)保存(ctrl+s) 9、小程序管理后台-小程序项目-生成版本 //以下操作位置:微信开发者工具 (1)上传项目 A、首次,点击(右上方)上传按钮。上传成功后,需要联系管理员在小程序管理后台将本次上传“设置为体验版本”。确定 B、再次,点击(右上方)上传按钮。上次提交已被选为体验版,本次上传将会覆盖体验版,是否继续?确定 (2)填写版本号、项目备注 (3)点击上传 (4)上传成功、确定 //以下操作位置:管理后台。管理-管理版本-开发版本 附、管理后台网址,https: //mp.weixin.qq.com/wxamp/home/guide (5)设置为体验版本 A、左,版本号 B、中,版本信息 C、右,提交审核,选为体验版本、删除 D、点击选为体验版本,体验版设置,点击提交,(点击下载二维码)扫描二维码体验体验版,前往体验,手动关闭弹窗 10、存储仓库-目录 附、git仓库网址,https: //git.weixin.qq.com/ (1)项目 A、您的项目 B、关注的项目 C、标星的项目 D、受邀请项目 (2)动态 (3)项目组 (4)里程碑 (5)缺陷 (6)合并请求 (7)代码评审 (8)个人设置 11、存储仓库-存储小程序代码 附、git仓库网址,https: //git.weixin.qq.com/ //以下操作位置:代码仓库 (1)进入git仓库 (2)点击创建项目,填写信息,点击创建项目 //以下操作位置:微信开发者工具/本地磁盘的文件夹 (3)配置-Git全局设置。首次创建项目,需执行下列命令。以后创建项目,也会出现下列提示,且配置都相同,但无需执行 git config --global user.name "Z_码农_钱成" git config --global user.email "oncw7ZtkhVxE@git.weixin.qq.com" (4)拉取-别人正在开发的项目代码,协助别人开发。创建一个新的版本库 git clone https: //git.weixin.qq.com/13718/xiangmuzu1.git cd xiangmuzu1 touch README.md git add README.md git commit -m "add README" git push -u origin master (5)推送-自己正在开发的项目代码,让别人协助开发。现有的文件夹或Git版本库 cd existing_folder git init git remote add origin https: //git.weixin.qq.com/13718/xiangmuzu1.git git add . git commit -m '自定义' git push -u origin master //以下操作位置:微信开发者工具 (6)推送-拉取别人后推送/再次推送自己 A、点击(顶部中间左侧)V形符号 B、点击(顶部中间右侧)...符号 C、点击commit D、点击push 12、存储仓库-删除小程序代码 附、git仓库网址,https: //git.weixin.qq.com/ //以下操作位置:代码仓库 (1)进入git仓库 (2)点击“您的项目/关注的项目/标星的项目/受邀请项目” (3)点击某一项目 (4)点击(左下方)设置 (5)点击(右中间)去更改可见性级别 (6)下拉(至最下方),点击删除项目 (7)输入url,点击确定 四、微信小程序-目录说明 来源,https: //developers.weixin.qq.com/miniprogram/dev/reference/configuration/app.html 来源,https: //developers.weixin.qq.com/miniprogram/dev/framework/structure.html 附、目录结构 ├── app.js ├── app.json ├── app.wxss ├── pages │ │── index │ │ ├── index.wxml │ │ ├── index.js │ │ ├── index.json │ │ └── index.wxss │ └── logs │ ├── logs.wxml │ └── logs.js └── utils 1、 全局配置,一个小程序主体由三个文件组成,必须放在项目的根目录 (1)app.js,小程序全局逻辑 App({ //注册小程序。接受一个 Object 参数,其指定小程序的生命周期回调等 onLaunch: function () {}, //生命周期回调——监听小程序初始化 onShow: function () {}, //生命周期回调——监听小程序启动或切前台 onHide: function () {}, //生命周期回调——监听小程序切后台。 onError: function () {}, //错误监听函数。 onPageNotFound: function () {}, //页面不存在监听函数。 onUnhandledRejection: function () {}, //未处理的 Promise 拒绝事件监听函数。 onThemeChange: function () {}, //监听系统主题变化 其他: 任意类型,开发者可以添加任意的函数或数据变量到参数中,用 this 可以访问 }) 附、其它页面,获取实例 // other.js var appInstance = getApp() console.log(appInstance.globalData) // I am global data (2)app.json,小程序全局配置 { "pages" : [ "pages/index/index" , "pages/logs/index" ], //小程序的所有页面 "requiredBackgroundModes" : [ "audio" , "location" ], "requiredPrivateInfos" : [ "getLocation" , "onLocationChange" , "startLocationUpdateBackground" "chooseAddress" ], "permission" : { "scope.userLocation" : { "desc" : "你的位置信息将用于小程序位置接口的效果展示" //高速公路行驶持续后台定位 } }, "window" : { "navigationBarTitleText" : "Demo" }, "tabBar" : { "height" : "50px" , "fontSize" : "10px" , "list" : [ { "pagePath" : "pages/index/index" , "text" : "首页" }, { "pagePath" : "pages/logs/logs" , "text" : "日志" } ] }, "networkTimeout" : { "request" : 10000, "downloadFile" : 10000 }, "plugins" : { //在app.json中声明需要使用的插件 "myPlugin" : { "version" : "1.0.0" , "provider" : "wxidxxxxxxxxxxxxxxxx" } }, "debug" : true , "resizable" : true , //iPad上启用屏幕旋转支持 } (3)app.wxss,小程序全局样式表 2、页面配置,一个小程序页面由四个文件组成 (1)index.js,页面逻辑 page({ //组件逻辑用Component({}) data: {}, options: {}, behaviors: String/Array,类似于mixins和traits的组件间代码复用机制, onLoad: function () {}, onShow: function () {}, onReady: function () {}, onHide: function () {}, onUnload: function () {}, onRouteDone: function () {}, onPullDownRefresh: function () {}, onReachBottom: function () {}, onShareAppMessage: function () {}, onShareTimeline: function () {}, onAddToFavorites: function () {}, onPageScroll: function () {}, onResize(res) { //屏幕旋转事件 res.size.windowWidth //新的显示区域宽度 res.size.windowHeight //新的显示区域高度 }, onTabItemTap: function () {}, onSaweexitState: function () {}, onShow: function () {}, //其他: 任意类型,开发者可以添加任意的函数或数据变量到参数中, //在页面的函数中用this可以访问,这部分属性会在页面实例创建时进行一次深拷贝 tapName: function( event ) { console.log( event ) } }) 附、getCurrentPages,获取当前页面栈,数组中第一个元素为首页,最后一个元素为当前页面 附、Router,页面路由器对象,可以通过 this .pageRouter或 this .router获得当前页面或自定义组件的路由器对象 (2)index.json,页面配置 { "navigationBarBackgroundColor" : "#ffffff" , "navigationBarTextStyle" : "black" , "navigationBarTitleText" : "微信接口功能演示" , "backgroundColor" : "#eeeeee" , "backgroundTextStyle" : "light" "pageOrientation" : "auto" , //手机单页面启用屏幕旋转支持 } (3)index.wxss,页面样式表 (4)index.wxml,页面结构 五、微信小程序-WXML语法参考 附、是一套标签语言,结合基础组件、事件系统,可以构建出页面的结构 1、数据绑定,使用Mustache语法(双大括号)将变量包起来 (1)简单绑定 <view> {{ message }} </view> (2)组件属性 <view id= "item-{{id}}" > </view> (3)控制属性 <view wx: if = "{{condition}}" > </view> (4)关键字 <checkbox checked = "{{false}}" > </checkbox> (5)三元运算 <view hidden= "{{flag ? true : false}}" > Hidden </view> (6)算数运算 <view> {{a + b}} + {{c}} + d </view> (7)逻辑判断 <view wx: if = "{{length > 5}}" > </view> (8)字符串运算 <view>{{ "hello" + name}}</view> (9)数据路径运算 <view>{{ object .key}} {{array[0]}}</view> (10)组合数组 <view wx: for = "{{[zero, 1, 2, 3, 4]}}" > {{item}} </view> (11)组合对象 <template is = "objectCombine" data= "{{for: a, bar: b}}" ></template> (12)组合对象,后面覆盖前面 <template is = "objectCombine" data= "{{...obj1, ...obj2, a: 5}}" ></template> (13)组合对象 <template is = "objectCombine" data= "{{foo, bar}}" ></template> (14)花括号和引号之间如果有空格,将最终被解析成为字符串 <view wx: for = "{{[1,2,3]}} " > {{item}} </view> //等同于 <view wx: for = "{{[1,2,3] + ' '}}" > {{item}} </view> (15)当wx: for 的值为字符串时,会将字符串解析成字符串数组 <view wx: for = "array" > {{item}} </view> //等同于 <view wx: for = "{{['a','r','r','a','y']}}" > {{item}} </view> (16)data Page({ data: { message: 'Hello MINA!' , id: 0, condition: true , a: 1, b: 2, c: 3, name: 'MINA' , object : { key: 'Hello ' }, array: [ 'MINA' ], zero: 0, obj1: { a: 1, b: 2 }, obj2: { c: 3, d: 4 }, foo: 'my-foo' , bar: 'my-bar' , } }) 2、列表渲染, (1)默认数组的当前项的下标变量名默认为index,数组当前项的变量名默认为item <view wx: for = "{{array}}" > {{index}}: {{item.message}} </view> (2)使用wx: for -item可以指定数组当前元素的变量名,使用wx: for -index可以指定数组当前下标的变量名: <view wx: for = "{{array}}" wx: for -index= "idx" wx: for -item= "itemName" > {{idx}}: {{itemName.message}} </view> (3)wx: for 也可以嵌套,下边是一个九九乘法表 <view wx: for = "{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx: for -item= "i" > <view wx: for = "{{[1, 2, 3, 4, 5, 6, 7, 8, 9]}}" wx: for -item= "j" > <view wx: if = "{{i <= j}}" > {{i}} * {{j}} = {{i * j}} </view> </view> </view> (4)block wx: for ,渲染一个包含多节点的结构块 <block wx: for = "{{[1, 2, 3]}}" > <view> {{index}}: </view> <view> {{item}} </view> </block> (5)数据 Page({ data: { array: [{ message: 'foo' , }, { message: 'bar' }] } }) (6)wx:key的值以两种形式提供 A、字符串,代表在 for 循环的array中item的某个property,该property的值需要是列表中唯一的字符串或数字,且不能动态改变 B、保留关键字* this ,代表在 for 循环中的item本身,这种表示需要item本身是一个唯一的字符串或者数字 < switch wx: for = "{{objectArray}}" wx:key= "unique" style= "display: block;" > {{item.id}} </ switch > <button bindtap= "switch" > Switch </button> <button bindtap= "addToFront" > Add to the front </button> < switch wx: for = "{{numberArray}}" wx:key= "*this" style= "display: block;" > {{item}} </ switch > <button bindtap= "addNumberToFront" > Add to the front </button> Page({ data: { objectArray: [ {id: 5, unique: 'unique_5' }, {id: 4, unique: 'unique_4' }, {id: 3, unique: 'unique_3' }, {id: 2, unique: 'unique_2' }, {id: 1, unique: 'unique_1' }, {id: 0, unique: 'unique_0' }, ], numberArray: [1, 2, 3, 4] }, switch : function(e) { const length = this .data.objectArray.length for ( let i = 0; i < length; ++i) { const x = Math.floor(Math.random() * length) const y = Math.floor(Math.random() * length) const temp = this .data.objectArray[x] this .data.objectArray[x] = this .data.objectArray[y] this .data.objectArray[y] = temp } this .setData({ objectArray: this .data.objectArray }) }, addToFront: function(e) { const length = this .data.objectArray.length this .data.objectArray = [{id: length, unique: 'unique_' + length}].concat( this .data.objectArray) this .setData({ objectArray: this .data.objectArray }) }, addNumberToFront: function(e){ this .data.numberArray = [ this .data.numberArray.length + 1 ].concat( this .data.numberArray) this .setData({ numberArray: this .data.numberArray }) } }) 3、条件渲染 (1)使用 wx: if = "" 来判断是否需要渲染该代码块: <view wx: if = "{{condition}}" > True </view> (2)用 wx:elif 和 wx: else 来添加一个 else 块: <view wx: if = "{{length > 5}}" > 1 </view> <view wx:elif= "{{length > 2}}" > 2 </view> <view wx: else > 3 </view> (3)用一个 <block/> 标签将多个组件包装起来,并在上边使用 wx: if 控制属性 <block wx: if = "{{true}}" > <view> view1 </view> <view> view2 </view> </block> <block/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性 (4) if 与hidden,wx: if 有更高的切换消耗;hidden有更高的初始渲染消耗 4、模板, WXML提供模板(template),可以在模板中定义代码片段,然后在不同的地方调用 (1)定义模板 使用name属性,作为模板的名字。然后在<template/>内定义代码片段,如: <!-- index: int msg: string time: string --> <template name= "msgItem" > <view> <text> {{index}}: {{msg}} </text> <text> Time: {{time}} </text> </view> </template> (2)使用模板 使用 is 属性,声明需要的使用的模板,然后将模板所需要的data传入 <template is = "msgItem" data= "{{...item}}" /> Page({ data: { item: { index: 0, msg: 'this is a template' , time: '2016-09-15' } } }) (3) is 属性可以使用Mustache语法,来动态决定具体需要渲染哪个模板 <template name= "odd" > <view> odd </view> </template> <template name= "even" > <view> even </view> </template> <block wx: for = "{{[1, 2, 3, 4, 5]}}" > <template is = "{{item % 2 == 0 ? 'even' : 'odd'}}" /> </block> (4)模板的作用域 模板拥有自己的作用域,只能使用 data 传入的数据以及模板定义文件中定义的<wxs/>模块 5、引用 WXML提供两种文件引用方式import和include (1)在 item.wxml 中定义了一个叫item的template <template name= "item" > <text>{{text}}</text> </template> (2)在 index.wxml 中引用了 item.wxml,就可以使用item模板 <import src= "item.wxml" /> <template is = "item" data= "{{text: 'forbar'}}" /> (3)import的作用域 import有作用域的概念,只会import目标文件中定义的template,而不会import目标文件import的template <!-- A.wxml --> <template name= "A" > <text> A template </text> </template> <!-- B.wxml --> <import src= "a.wxml" /> <template name= "B" > <text> B template </text> </template> <!-- C.wxml --> <import src= "b.wxml" /> <template is = "A" /> <!-- Error! Can not use tempalte when not import A. --> <template is = "B" /> (4)include include,可以将目标文件除了<template/><wxs/>外的整个代码引入,相当于是拷贝到include位置 <!-- index.wxml --> <include src= "header.wxml" /> <view> body </view> <include src= "footer.wxml" /> <!-- header.wxml --> <view> header </view> <!-- footer.wxml --> <view> footer </view> 六、微信小程序-WXS语法参考 1、说明 (1)WXS是小程序的一套脚本语言,与JavaScript是不同的语言,有自己的语法 (2)WXS代码可以编写在wxml文件中的<wxs>标签内,或以.wxs为后缀名的文件内 (3)变量、注释、运算符、语句、数据类型、基础类库,与js类似 2、模块 (1)每一个.wxs文件和<wxs>标签都是一个单独的模块 (2)每个模块都有自己独立的作用域,即在一个模块里面定义的变量与函数,默认为私有的,对其他模块不可见 (3)一个模块要想对外暴露其内部的私有变量与函数,只能通过module.exports实现 (4)在微信开发者工具里面,右键可以直接创建.wxs文件,在其中直接编写WXS脚本 3、.wxs文件 (1)module模块 A、module对象,每个wxs模块均有一个内置的module对象 B、exports属性,通过该属性,可以对外共享本模块的私有变量与函数 /pages/tools.wxs var foo = "'hello world' from tools.wxs" ; var bar = function (d) { return d; } module.exports = { FOO: foo, bar: bar, }; module.exports.msg = "some msg" ; page/index/index.wxml <wxs src= "./../tools.wxs" module= "tools" /> <view> {{tools.msg}} </view> <view> {{tools.bar(tools.FOO)}} </view> 页面输出 some msg 'hello world' from tools.wxs (2)require函数 在.wxs模块中引用其他wxs文件模块,可以使用require函数,引用的时候,要注意如下几点 A、只能引用.wxs文件模块,且必须使用相对路径 B、wxs模块均为单例,wxs模块在第一次被引用时,会自动初始化为单例对象;多个页面,多个地方,多次引用,使用的都是同一个wxs模块对象 C、如果一个wxs模块在定义之后,一直没有被引用,则该模块不会被解析与运行 /pages/tools.wxs var foo = "'hello world' from tools.wxs" ; var bar = function (d) { return d; } module.exports = { FOO: foo, bar: bar, }; module.exports.msg = "some msg" ; /pages/logic.wxs var tools = require( "./tools.wxs" ); console.log(tools.FOO); console.log(tools.bar( "logic.wxs" )); console.log(tools.msg); /page/index/index.wxml --> <wxs src= "./../logic.wxs" module= "logic" /> (3)<wxs>标签的属性 A、module属性,是当前<wxs>标签的模块名, B、src属性,可以用来引用其他的wxs文件模块,引用的时候,要注意如下几点 只能引用.wxs文件模块,且必须使用相对路径 wxs模块均为单例,wxs模块在第一次被引用时,会自动初始化为单例对象;多个页面,多个地方,多次引用,使用的都是同一个wxs模块对象 /pages/index/index.js Page({ data: { msg: "'hello wrold' from js" , } }) /pages/index/index.wxml --> <wxs src= "./../comm.wxs" module= "some_comms" ></wxs> 也可以直接使用单标签闭合的写法 <wxs src= "./../comm.wxs" module= "some_comms" /> 调用some_comms模块里面的bar函数,且参数为some_comms模块里面的 foo <view>{{some_comms.bar(some_comms.foo)}}</view> 调用 some_comms 模块里面的bar函数,且参数为page/index/index.js里面的msg <view>{{some_comms.bar(msg)}}</view> 页面输出: 'hello world' from comm.wxs 'hello wrold' from js 上述例子在文件/page/index/index.wxml中通过<wxs>标签引用了/page/comm.wxs 模块 (4)注意事项 A、<wxs>模块只能在定义模块的WXML文件中被访问到,使用<include>或<import>时,<wxs>模块不会被引入到对应的WXML文件中 B、<template>标签中,只能使用定义该<template>的WXML文件中定义的<wxs>模块 4、引入插件 var myPluginInterface = requirePlugin( 'myPlugin' ); myPluginInterface.hello(); 七、微信小程序-事件系统 来源,https: //developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/event.html 1、什么是事件 (1)事件是视图层到逻辑层的通讯方式,(由用户决定执行逻辑和执行时机) (2)事件可以将用户的行为反馈到逻辑层进行处理 (3)事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数 (4)事件对象可以携带额外信息,如id,dataset,touches 2、事件的使用方式,在组件中绑定一个事件处理函数 (1)JS绑定 以下,在index.wxml中,触发点击事件 <view id= "tapTest" data-hi= "Weixin" bindtap= "tapName" > Click me! </view> 以下,在index.js中,定义点击函数 Page({ tapName: function( event ) { console.log( event ) } }) (2)WXS绑定 以下,在index.wxml中,引入test.wxs脚本,触发点击事件 <wxs module= "wxs" src= "./test.wxs" ></wxs> <view id= "tapTest" data-hi= "Weixin" bindtap= "{{wxs.tapName}}" >绑定的WXS函数必须用{{Mustache语法,Mustache胡子}}括起来</view> 以下,在test.wxs中,定义点击函数 function tapName( event , ownerInstance) { console.log( 'tap Weixin' , JSON.stringify( event )) } module.exports = { tapName: tapName } 3、事件详解 (1)冒泡从里向外,先捕获后冒泡 bind,绑定事件,向上冒泡,后可以紧跟一个冒号,其含义不变,如bind:tap mut-bind,绑定事件,向上冒泡,与上级mut-bind“互斥”的,上级mut-bind不会被触发,上级的其它绑定依然会触发 catch ,绑定事件,阻止向上冒泡 (2)冒泡与阻止冒泡,bindtap与catchtap,点击“inner view”会先后调用handleTap3和handleTap2 <view id= "outer" bindtap= "handleTap1" > “outer view” <view id= "middle" catchtap= "handleTap2" > “middle view” <view id= "inner" bindtap= "handleTap3" > “inner view” </view> </view> </view> (3)互斥事件,mut-bind,点击“inner view”会先后调用handleTap3和handleTap2,点击“middle view”会调用handleTap2和handleTap1 <view id= "outer" mut-bind:tap= "handleTap1" > “outer view” <view id= "middle" bindtap= "handleTap2" > “middle view” <view id= "inner" mut-bind:tap= "handleTap3" > “inner view” </view> </view> </view> (4)捕获从外向里,先捕获后冒泡 capture-bind,捕获 capture- catch ,中断捕获、取消冒泡 (5)事件的捕获阶段,点击“inner view”会先后调用handleTap2、handleTap4、handleTap3、handleTap1 <view id= "outer" bind:touchstart= "handleTap1" capture-bind:touchstart= "handleTap2" > “outer view” <view id= "inner" bind:touchstart= "handleTap3" capture-bind:touchstart= "handleTap4" > “inner view” </view> </view> 如果将上面代码中的第一个capture-bind改为capture- catch ,将只触发handleTap2 (6)事件对象,如无特殊说明,当组件触发事件时,逻辑层绑定该事件的处理函数会收到一个事件对象 A、BaseEvent 基础事件对象属性列表 type,代表事件的类型 timeStamp,页面打开到触发事件所经过的毫秒数 target,触发事件的源组件 id,事件源组件的id dataset,事件源组件上由data-开头的自定义属性组成的集合 currentTarget,事件绑定的当前组件 id,当前组件的id dataset,当前组件上由data-开头的自定义属性组成的集合 mark,识别具体触发事件的target节点,承载一些自定义数据,类似于dataset <view mark:myMark= "last" bindtap= "bindViewTap" > <button mark:anotherMark= "leaf" bindtap= "bindButtonTap" >按钮</button> </view> 在上述WXML中,如果按钮被点击,将触发bindViewTap和bindButtonTap两个事件,事件携带的 event .mark将包含myMark和anotherMark两项 Page({ bindViewTap: function(e) { e.mark.myMark === "last" //true e.mark.anotherMark === "leaf" //true } }) //mark,会包含从触发事件的节点到根节点上所有的mark属性值 //dataset,仅包含一个节点的data-属性值 B、CustomEvent 自定义事件对象属性列表(继承 BaseEvent) detail,额外的信息 C、TouchEvent 触摸事件对象属性列表(继承 BaseEvent) touches,触摸事件,当前停留在屏幕中的触摸点信息的数组,每个元素为一个Touch对象,表示当前停留在屏幕上的触摸点 identifier,触摸点的标识符 pageX/pageY,距离文档左上角的距离,文档的左上角为原点 ,横向为X轴,纵向为Y轴 clientX/clientY,距离页面可显示区域(屏幕除去导航条)左上角距离,横向为X轴,纵向为Y轴 changedTouches,触摸事件,当前变化的触摸点信息的数组 4、WXS响应事件 (1)以下test.wxml <wxs module= "test" src= "./test.wxs" ></wxs> <view bindtouchmove= "{{test.touchmove}}" change:prop= "{{test.propObserver}}" prop= "{{propValue}}" class = "movable" ></view> //以上,WXS函数必须用{{}}括起来 //以上,change:prop(标签上的监听--自悟),属性前面带“change:”前缀,是在prop属性被设置的时候触发WXS函数,类似Component定义的properties里面的observer属性 //以上,在setData({propValue: newValue})调用之后会触发,而不只是值发生改变,所以在页面初始化的时候会调用一次WxsPropObserver的函数 //以上,在JS里,可以自动调用WXS,因page()而执行 (2)以下test.wxs module.exports = { touchmove: function( event , ownerInstance) { //event.instance,表示触发事件的组件的ComponentDescriptor实例 //ownerInstance,表示的是触发事件的组件所在的组件的ComponentDescriptor实例,如果触发事件的组件是在页面内的,ownerInstance表示的是页面实例 }, propObserver: function(newValue, oldValue, ownerInstance, instance) { //ownerInstance,表示的是触发事件的组件所在的组件的ComponentDescriptor实例,如果触发事件的组件是在页面内的,ownerInstance表示的是页面实例 //instance,表示触发事件的组件的ComponentDescriptor实例 } } //以上,instance.callMethod(funcName:string, args:object),WXS调用当前-组件-在逻辑层(App Service)定义的函数 //以上,ownerInstance.callMethod(funcName:string, args:object),WXS调用当前-页面-在逻辑层(App Service)定义的函数 //以上,在WXS里,可以手动调用JS 八、微信小程序-组件,基础组件 来源,https: //developers.weixin.qq.com/miniprogram/dev/component/ 附、<block><block/>,不是组件,只是一个包装元素,不会在页面中做任何的渲染,它能够设置 if 、 for 这些控制属性,设置 class 、id不会生效 1、视图容器 (1)cover-view,覆盖在原生组件之上的文本视图 <view class = "page-section page-section-gap" > <map style= "width: 100%; height: 300px;" latitude= "{{latitude}}" longitude= "{{longitude}}" > <cover-view class = "cover-view" > <cover-view class = "container" > <cover-view class = "flex-wrp" style= "flex-direction:row;" > <cover-view class = "flex-item demo-text-1" ></cover-view> <cover-view class = "flex-item demo-text-2" ></cover-view> <cover-view class = "flex-item demo-text-3" ></cover-view> </cover-view> </cover-view> </cover-view> </map> </view> (2)match-media,匹配检测节点 <match-media min-width= "300" max-width= "600" > <view>当页面宽度在 300 ~ 500 px 之间时展示这里</view> </match-media> (3)movable-area,可移动的视图容器,在页面中可以拖拽滑动 <movable-area> <movable-view x= "{{x}}" y= "{{y}}" direction= "all" >text</movable-view> </movable-area> (4)scroll-view,可滚动视图区域。类似于轮播图,像素级滑动 <scroll-view scroll-y= "true" style= "height: 300rpx;" bindscrolltoupper= "upper" bindscrolltolower= "lower" bindscroll= "scroll" scroll- into -view= "{{toView}}" scroll-top= "{{scrollTop}}" > <view id= "demo1" class = "scroll-view-item demo-text-1" ></view> <view id= "demo2" class = "scroll-view-item demo-text-2" ></view> <view id= "demo3" class = "scroll-view-item demo-text-3" ></view> </scroll-view> (5)swiper,滑块视图容器,swiper-item,仅可放置在swiper组件中,宽高自动设置为100%。类似于轮播图,块级滑动 <swiper indicator-dots= "{{indicatorDots}}" autoplay= "{{autoplay}}" interval= "{{interval}}" duration= "{{duration}}" > <block wx: for = "{{background}}" wx:key= "*this" > <swiper-item> <view class = "swiper-item {{item}}" ></view> </swiper-item> </block> </swiper> (6)view,视图容器 <view class = "container" > <view class = "page-body" > <view class = "page-section" > <view class = "page-section-title" > <text>flex-direction: row\n横向布局</text> </view> <view class = "page-section-spacing" > <view class = "flex-wrp" style= "flex-direction:row;" > <view class = "flex-item demo-text-1" ></view> <view class = "flex-item demo-text-2" ></view> <view class = "flex-item demo-text-3" ></view> </view> </view> </view> <view class = "page-section" > <view class = "page-section-title" > <text>flex-direction: column\n纵向布局</text> </view> <view class = "flex-wrp" style= "flex-direction:column;" > <view class = "flex-item flex-item-V demo-text-1" ></view> <view class = "flex-item flex-item-V demo-text-2" ></view> <view class = "flex-item flex-item-V demo-text-3" ></view> </view> </view> </view> </view> 2、基础内容 (1)icon,图标组件 <view class = "icon-box" > <icon class = "icon-box-img" type= "success" size= "93" ></icon> <view class = "icon-box-ctn" > <view class = "icon-box-title" >成功</view> <view class = "icon-box-desc" >用于表示操作顺利完成</view> </view> </view> (2)progress,进度条 <view class = "progress-box" > <progress percent= "20" show-info stroke-width= "3" /> </view> (3)rich-text,富文本 <block wx: if = "{{renderedByHtml}}" > <rich-text nodes= "{{htmlSnip}}" ></rich-text> </block> const htmlSnip = `<div class = "div_class" > <h1>Title</h1> <p class = "p" > Life is <i>like</i> a box of <b> chocolates</b>. </p> </div> ` (4)text,文本 <view class = "page-section page-section-spacing" > <view class = "text-box" scroll-y= "true" scroll-top= "{{scrollTop}}" > <text>{{text}}</text> </view> <button disabled= "{{!canAdd}}" bindtap= "add" >add line</button> <button disabled= "{{!canRemove}}" bindtap= "remove" >remove line</button> </view> const texts = [ '2011年1月,微信1.0发布' , '同年5月,微信2.0语音对讲发布' , '10月,微信3.0新增摇一摇功能' , '2012年3月,微信用户突破1亿' , '4月份,微信4.0朋友圈发布' , '同年7月,微信4.2发布公众平台' , '2013年8月,微信5.0发布微信支付' , '2014年9月,企业号发布' , '同月,发布微信卡包' , '2015年1月,微信第一条朋友圈广告' , '2016年1月,企业微信发布' , '2017年1月,小程序发布' , '......' ] 3、表单组件 (1)button,按钮 <view class = "button-sp-area" > <button type= "primary" plain= "true" >按钮</button> <button type= "primary" disabled= "true" plain= "true" >不可点击的按钮</button> </view> (2)checkbox,多选项目 <label class = "checkbox" > <checkbox value= "cb" />未选中 </label> <checkbox- group bindchange= "checkboxChange" > <label class = "weui-cell weui-check__label" wx: for = "{{items}}" wx:key= "{{item.value}}" > <view class = "weui-cell__hd" > <checkbox value= "{{item.value}}" checked = "{{item.checked}}" /> </view> <view class = "weui-cell__bd" >{{item.name}}</view> </label> </checkbox- group > (3)checkbox- group ,多项选择器,内部由多个checkbox组成,示例见(2) (4)editor,富文本编辑器,可以对图片、文字进行编辑 <editor id= "editor" read-only= "{{false}}" /> //自写 (5)form,表单 <form catchsubmit= "formSubmit" catchreset= "formReset" > <view class = "page-section page-section-gap" > <view class = "page-section-title" > switch </view> < switch name= "switch" /> </view> <view class = "btn-area" > <button style= "margin: 30rpx 0" type= "primary" formType= "submit" >Submit</button> <button style= "margin: 30rpx 0" formType= "reset" >Reset</button> </view> </form> (6)input,输入框 <view class = "weui-cell weui-cell_input" > <input class = "weui-input" auto-focus placeholder= "将会获取焦点" /> </view> (7)keyboard-accessory,设置input/textarea聚焦时,键盘上方cover-view/cover-image工具栏视图 <textarea hold-keyboard= "{{true}}" > <keyboard-accessory class = "container" style= "height: 50px;" > <cover-view bindtap= "tap" style= "flex: 1; background: green;" >1</cover-view> <cover-view bindtap= "tap" style= "flex: 1; background: red;" >2</cover-view> </keyboard-accessory> </textarea> (8)label,用来改进表单组件的可用性 <checkbox- group class = "group" bindchange= "checkboxChange" > <view class = "label-1" wx: for = "{{checkboxItems}}" > <label> <checkbox value= "{{item.name}}" checked = "{{item.checked}}" ></checkbox> <text class = "label-1-text" >{{item.value}}</text> </label> </view> </checkbox- group > (9)picker,从底部弹起的滚动选择器 <picker mode= "multiSelector" bindchange= "bindMultiPickerChange" bindcolumnchange= "bindMultiPickerColumnChange" value= "{{multiIndex}}" range= "{{multiArray}}" > <view class = "picker" > 当前选择:{{multiArray[0][multiIndex[0]]}},{{multiArray[1][multiIndex[1]]}},{{multiArray[2][multiIndex[2]]}} </view> </picker> (10)picker-view,嵌入页面的滚动选择器 <picker-view indicator-style= "height: 50px;" style= "width: 100%; height: 300px;" value= "{{value}}" bindchange= "bindChange" > <picker-view-column> <view wx: for = "{{years}}" wx:key= "{{years}}" style= "line-height: 50px; text-align: center;" >{{item}}年</view> </picker-view-column> <picker-view-column> <view wx: for = "{{months}}" wx:key= "{{months}}" style= "line-height: 50px; text-align: center;" >{{item}}月</view> </picker-view-column> </picker-view> (11)picker-view-column,滚动选择器子项 (12)radio,单选项目 <radio- group bindchange= "radioChange" > <label class = "weui-cell weui-check__label" wx: for = "{{items}}" wx:key= "{{item.value}}" > <view class = "weui-cell__hd" > <radio value= "{{item.value}}" checked = "true" /> </view> <view class = "weui-cell__bd" >{{item.name}}</view> </label> </radio- group > (13)radio- group ,单项选择器,内部由多个radio组成,示例见(12) (14)slider,滑动选择器 <view class = "body-view" > <slider bindchange= "slider1change" left-icon= "cancel" right-icon= "success_no_circle" /> </view> (15) switch ,开关选择器 <view class = "body-view" > < switch checked = "{{switch1Checked}}" bindchange= "switch1Change" /> </view> (16)textarea,多行输入框 <view class = "section" > <textarea bindblur= "bindTextAreaBlur" auto-height placeholder= "自动变高" /> </view> 4、导航 (1)functional-page-navigator,仅在插件中有效,用于跳转到插件功能页 <functional-page-navigator name= "loginAndGetUserInfo" bind:success= "loginSuccess" > <button>登录到插件</button> </functional-page-navigator> (2)navigator,页面链接 <view class = "btn-area" > <navigator url= "/page/navigate/navigate?title=navigate" hover- class = "navigator-hover" >跳转到新页面</navigator> <navigator url= "../../redirect/redirect/redirect?title=redirect" open-type= "redirect" hover- class = "other-navigator-hover" >在当前页打开</navigator> <navigator url= "/page/index/index" open-type= "switchTab" hover- class = "other-navigator-hover" >切换 Tab</navigator> <navigator target= "miniProgram" open-type= "navigate" app-id= "" path= "" extra-data= "" version= "release" >打开绑定的小程序</navigator> </view> 5、媒体组件 (1)camera,系统相机。点击相机图标,调出下面页面。出现人像-拍照人像-预览人像-存储人像 <camera device-position= "back" flash= "off" binderror= "error" style= "width: 100%; height: 300px;" ></camera> <button type= "primary" bindtap= "takePhoto" >拍照</button> <view>预览</view> <image mode= "widthFix" src= "{{src}}" ></image> Page({ takePhoto() { const ctx = wx.createCameraContext() ctx.takePhoto({ quality: 'high' , success: (res) => { this .setData({ src: res.tempImagePath }) } }) }, error(e) { console.log(e.detail) } }) (2)image,图片。mode,图片裁剪、缩放的模式 <view class = "section section_gap" wx: for = "{{array}}" wx: for -item= "item" > <view class = "section__title" >{{item.text}}</view> <view class = "section__ctn" > <image style= "width: 200px; height: 200px; background-color: #eeeeee;" mode= "{{item.mode}}" src= "{{src}}" ></image> </view> </view> (3)live-player,实时音视频播放 <live-player src= "https://domain/pull_stream" mode= "RTC" autoplay bindstatechange= "statechange" binderror= "error" style= "width: 300px; height: 225px;" /> (4)live-pusher,实时音视频录制 <live-pusher url= "https://domain/push_stream" mode= "RTC" autopush bindstatechange= "statechange" style= "width: 300px; height: 225px;" /> (5)video,视频 <video id= "myVideo" src= "http://wxsnsdy.tc.qq.com/105/20210/snsdyvideodownload?filekey=30280201010421301f0201690402534804102ca905ce620b1241b726bc41dcff44e00204012882540400&bizid=1023&hy=SH&fileparam=302c020101042530230204136ffd93020457e3c4ff02024ef202031e8d7f02030f42400204045a320a0201000400" binderror= "videoErrorCallback" danmu-list= "{{danmuList}}" enable-danmu danmu-btn show-center-play-btn= '{{false}}' show-play-btn= "{{true}}" controls picture- in -picture-mode= "{{['push', 'pop']}}" bindenterpictureinpicture= 'bindVideoEnterPictureInPicture' bindleavepictureinpicture= 'bindVideoLeavePictureInPicture' ></video> (6)voip-room,多人音视频对话 <block wx: for = "{{openIdList}}" wx:key= "*this" > <voip-room openid= "{{item}}" mode= "{{selfOpenId === item ? 'camera' : 'video'}}" > </voip-room> </block> 6、地图,https: //developers.weixin.qq.com/miniprogram/dev/component/map.html 九、微信小程序-自定义组件 来源,开发-指南-自定义组件 来源,https: //developers.weixin.qq.com/miniprogram/dev/framework/custom-component/ 1、一个小程序自定义组件由四个文件组成,类似于页面Page (1).js,自定义组件逻辑 // page-common-behavior.js // module.exports = Behavior({ //https://developers.weixin.qq.com/miniprogram/dev/reference/api/Behavior.html // properties: {}, //组件的对外属性 // data: {}, //组件的内部数据 // }) var pageCommonBehavior = require( './page-common-behavior' ) Component({ //来源,https://developers.weixin.qq.com/miniprogram/dev/reference/api/Component.html //properties,组件的对外属性,是属性名到属性设置的映射表 properties: { //properties,组件的对外属性,是属性名到属性设置的映射表 innerText: { type: String, value: 'default value' , } }, //data,组件的内部数据,和properties一同用于组件的模板渲染 data: { someData: {} }, //observers,组件数据字段监听器,用于监听properties和data的变化 observers: { //组件数据字段监听器,用于监听properties和data的变化;普通监听 'numberA, numberB' : function(numberA, numberB) { //在 numberA或者numberB被设置时,执行这个函数 this .setData({ sum: numberA + numberB }) } }, observers: { //监听子数据字段 'some.subfield' : function(subfield) { //使用 setData 设置 this.data.some.subfield 时触发 //(除此以外,使用 setData 设置 this.data.some 也会触发) subfield === this .data.some.subfield }, 'arr[12]' : function(arr12) { //使用 setData 设置 this.data.arr[12] 时触发 //(除此以外,使用 setData 设置 this.data.arr 也会触发) arr12 === this .data.arr[12] }, }, observers: { //监听所有子数据字段的变化,可以使用通配符 ** 'some.field.**' : function(field) { //使用 setData 设置 this.data.some.field 本身或其下任何子数据字段时触发 //(除此以外,使用 setData 设置 this.data.some 也会触发) field === this .data.some.field }, }, observers: { //仅使用通配符 ** 可以监听全部 setData '**' : function() { //每次 setData 都触发 }, }, //methods,组件的方法,包括事件响应函数和任意的自定义方法 methods: { customMethod: function(){ this .setData({ //设置data并执行视图层渲染 s: false }) this .hasBehavior() //检查组件是否具有behavior(检查时会递归检查被直接或间接引入的所有behavior) this .triggerEvent() //触发事件 } }, //behaviors,组件间可共享的部分,组件间代码复用机制,类似于mixins和traits //behaviors,组件引用它时,它的properties、data、method会被合并到组件对应的配置中,生命周期函数也会在对应时机被调用 behaviors: [pageCommonBehavior], behaviors: [ 'wx://form-field' ], //它使得这个自定义组件有类似于表单控件的行为 //lifetimes,组件生命周期-声明对象,里面的生命周期可以写到外面,但写在这里优先级更高 lifetimes: { //生命周期函数,可以为函数,或一个在methods段中定义的方法名 //created,在组件实例刚刚被创建时执行,此时不能调用setData created: function() {}, //attached,在组件实例进入页面节点树时执行,声明的字段会被lifetimes声明的字段覆盖 attached: function() { this .setData({ numberA: 1, numberB: 2, }) this .setData({ //这样会触发上面的 observer 'some.field' : { /* ... */ } }) this .setData({ //这样也会触发上面的 observer 'some.field.xxx' : { /* ... */ } }) this .setData({ //这样还是会触发上面的 observer 'some' : { /* ... */ } }) }, //ready,组件布局完成后执行 ready: function() { }, //moved,组件实例被移动到节点树另一个位置时执行 moved: function() { }, //detached,组件实例被从页面节点树移除时执行 detached: function() { }, }, pageLifetimes: { // 组件所在页面的生命周期函数 show: function () { }, //组件所在的页面被展示时执行 hide: function () { }, //组件所在的页面被隐藏时执行 resize(res) { //屏幕旋转事件 res.size.windowWidth //新的显示区域宽度 res.size.windowHeight //新的显示区域高度 } routeDone: function () { }, //组件所在页面路由动画完成时执行 }, // 组件实例的属性和方法可以在组件的方法、生命周期函数和属性observer中通过this访问 // 属性名 // is,组件的文件路径 // id,节点id // dataset,节点dataset // data,组件数据,包括内部数据和属性值 // properties,组件数据,包括内部数据和属性值(与data一致) // router,相对于当前自定义组件的Router对象 // pageRouter,相对于当前自定义组件所在页面的Router对象 // renderer,渲染当前组件的渲染后端 // 方法名 // setData,设置data并执行视图层渲染 // hasBehavior,检查组件是否具有behavior(检查时会递归检查被直接或间接引入的所有behavior) // triggerEvent,触发事件,参见,组件间通信与事件, // https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/events.html }) (2).json,自定义组件配置 { "component" : true //这一组文件为自定义组件 } (3).wxss,自定义组件样式表 .inner { color: red; } (4).wxml,自定义组件结构 <view class = "inner" > <view>这里是组件的内部节点</view> <slot></slot> </view> (5)自定义组件使用 以下,在页面的.json文件中声明引用 { "usingComponents" : { "component-tag-name" : "path/to/the/custom/component" } } 以下,在页面的.wxml文件中使用 <view> <component-tag-name inner-text= "Some text" >这是插槽内容</component-tag-name> </view> (6)自定义组件扩展 //提供了修改自定义组件定义段的能力,下面例子就是修改了自定义组件中的data定义段里的内容 //behavior.js module.exports = Behavior({ definitionFilter(defFields) { defFields.data. from = 'behavior' }, }) //component.js Component({ data: { from : 'component' }, behaviors: [require( 'behavior.js' )], ready() { console.log( this .data. from ) //此处会发现输出 behavior 而不是 component } }) (7)简易双向绑定,自定义组件将自身的myValue属性双向绑定到了组件内输入框的value属性上 custom-component定义,<input model:value= "{{myValue}}" /> custom-component使用,<custom-component model:my-value= "{{pageValue}}" /> 2、抽象节点, 有默认渲染内容,使用者决定渲染内容,与插槽相似 (1)自定义组件 <!-- selectable- group .json --> { "componentGenerics" : { //generic,通用 "selectable" : true } } { "componentGenerics" : { "selectable" : { /* 默认抽象节点 */ "default" : "path/to/default/component" } } } <!-- selectable- group .wxml 渲染抽象节点 --> <view wx: for = "{{labels}}" > <label> <selectable disabled= "{{false}}" ></selectable> {{item}} </label> </view> (2)父组件 <!-- parent.json 定义抽象节点 --> { "usingComponents" : { "custom-radio" : "path/to/custom/radio" , "custom-checkbox" : "path/to/custom/checkbox" } } <!-- parent.wxml 选择抽象节点 --> <selectable- group generic:selectable= "custom-radio" /> 3、组件间通信与事件 (1)父级 <!-- 当自定义组件触发“myevent”事件时,调用“onMyEvent”方法 --> <component-tag-name bindmyevent= "onMyEvent" /> <!-- 或者可以写成 --> <component-tag-name bind:myevent= "onMyEvent" /> Page({ onMyEvent: function(e){ e.detail //自定义组件触发事件时提供的detail对象 } }) (2)自身 <button bindtap= "onTap" >点击这个按钮将触发“myevent”事件</button> Component({ properties: {}, methods: { onTap: function(){ var myEventDetail = {} //detail对象,提供给事件监听函数 var myEventOption = {} //触发事件的选项 this .triggerEvent( 'myevent' , myEventDetail, myEventOption) //trigger,触发 } } }) 十、微信小程序-API 1、基础 (1)系统 A、wx.getWindowInfo() //获取窗口信息 B、wx.getSystemInfo(Object object ) // 获取系统信息。是异步的调用格式,但是是同步返回 C、wx.getDeviceInfo() //获取设备基础信息 D、wx.getAppBaseInfo() //获取微信APP基础信息 (2)更新 A、wx.updateWeChatApp(Object object ) //更新客户端版本 B、wx.getUpdateManager() //获取全局唯一的版本更新管理器,用于管理小程序更新 (3)小程序 A、wx.getApiCategory() //获取当前API类别 B、wx.onThemeChange(function listener) //监听系统主题改变事件。该事件与App.onThemeChange的回调时机一致 C、wx.onAppShow(function listener) //监听小程序切前台事件。该事件与App.onShow的回调参数一致 (4)调试 A、console.log() //向调试面板中打印log日志 B、console.warn() //向调试面板中打印warn日志 (5)性能 A、wx.preloadWebview(Object object ) //预加载下个页面的WebView B、wx.getPerformance() //获取当前小程序性能相关的信息 C、wx.preloadAssets(Object object ) //为视图层预加载媒体资源文件 2、路由 (1)wx.switchTab(Object object ) //跳转到tabBar页面,并关闭其他所有非tabBar页面 (2)wx.reLaunch(Object object ) //关闭所有页面,打开到应用内的某个页面 (3)wx.redirectTo(Object object ) //关闭当前页面,跳转到应用内的某个页面,但是不允许跳转到tabbar页面 (4)wx.navigateTo(Object object ) //保留当前页面,跳转到应用内的某个页面,但是不能跳到tabbar页面,使用wx.navigateBack可以返回到原页面 (5)wx.navigateBack(Object object ) //关闭当前页面,返回上一页面或多级页面。可通过getCurrentPages获取当前的页面栈,决定需要返回几层。 (6)自定义路由 A、wx.router //获取router对象 B、router.addRouteBuilder( string routeType, function routeBuilder) //添加自定义路由配置 wx.router.addRouteBuilder( 'slide' , slideRouteBuilder) //路由类型,路由动画定义函数 C、router.getRouteContext(Object this ) //获取页面对应的自定义路由上下文对象 D、router.removeRouteBuilder( string routeType) //移除自定义路由配置 wx.router.removeRouteBuilder( 'slide' ) 3、跳转 (1)wx.restartMiniProgram(Object object ) //重启当前小程序 (2)wx.openEmbeddedMiniProgram(Object object ) //打开半屏小程序 (3)wx.navigateToMiniProgram(Object object ) //打开另一个小程序 (4)wx.exitMiniProgram(Object object ) //退出当前小程序。必须有点击行为才能调用成功 4、转发 (1)wx.updateShareMenu(Object object ) //更新转发属性 (2)wx.showShareMenu(Object object ) //显示当前页面的转发按钮 (3)wx.shareVideoMessage(Object object ) //转发视频到聊天 (4)wx.shareFileMessage(Object object ) //转发文件到聊天 5、界面 (1)交互 A、wx.showToast(Object object ) //显示消息提示框 B、wx.showModal(Object object ) //显示模态对话框 C、wx.showLoading(Object object ) //显示loading提示框。需主动调用wx.hideLoading才能关闭提示框 D、wx.showActionSheet(Object object ) //显示操作菜单 E、wx.hideToast(Object object ) //隐藏消息提示框 F、wx.hideLoading(Object object ) //隐藏loading提示框 (2)导航栏 A、wx.showNavigationBarLoading(Object object ) //在当前页面显示导航条加载动画 B、wx.setNavigationBarTitle(Object object ) //动态设置当前页面的标题 C、wx.setNavigationBarColor(Object object ) //设置页面导航条颜色 D、wx.hideNavigationBarLoading(Object object ) //在当前页面隐藏导航条加载动画 E、wx.hideHomeButton(Object object ) //隐藏返回首页按钮 (3)背景 A、wx.setBackgroundTextStyle(Object object ) //动态设置下拉背景字体、loading图的样式 B、wx.setBackgroundColor(Object object ) //动态设置窗口的背景色 (4)Tab Bar,位于小程序底部的导航栏菜单 A、wx.showTabBarRedDot(Object object ) //显示tabBar某一项的右上角的红点 B、wx.showTabBar(Object object ) //显示tabBar C、wx.setTabBarStyle(Object object ) //动态设置tabBar的整体样式 D、wx.setTabBarItem(Object object ) //动态设置tabBar某一项的内容 E、wx.setTabBarBadge(Object object ) //为tabBar某一项的右上角添加文本 F、wx.removeTabBarBadge(Object object ) //移除tabBar某一项右上角的文本 G、wx.hideTabBarRedDot(Object object ) //隐藏tabBar某一项的右上角的红点 H、wx.hideTabBar(Object object ) //隐藏tabBar (5)字体 A、wx.loadFontFace(Object object ) //动态加载网络字体,文件地址需为下载类型。需在app.js中调用 (6)下拉刷新 A、wx.stopPullDownRefresh(Object object ) //停止当前页面下拉刷新 B、wx.startPullDownRefresh(Object object ) //开始下拉刷新。调用后触发下拉刷新动画,效果与用户手动下拉刷新一致。 (7)滚动 A、wx.pageScrollTo(Object object ) //将页面滚动到目标位置,支持选择器和滚动距离两种方式定位 (8)动画 A、wx.createAnimation(Object object ) //创建一个动画实例animation (9)置顶 A、wx.setTopBarText(Object object ) //动态设置置顶栏文字内容 (10)自定义组件 A、wx.nextTick(Object object ) //延迟一部分操作到下一个时间片再执行。(类似于setTimeout) (11)菜单 A、wx.getMenuButtonBoundingClientRect(Object object ) //获取菜单按钮(右上角胶囊按钮)的布局位置信息。坐标信息以屏幕左上角为原点。 (12)窗口 A、wx.setWindowSize(Object object ) //设置窗口大小,该接口仅适用于PC平台 B、wx.onWindowResize(Object object ) //窗口尺寸变化事件的监听函数 C、wx.offWindowResize(Object object ) //移除窗口尺寸变化事件的监听函数 D、wx.checkIsPictureInPictureActive(Object object ) //返回当前是否存在小窗播放(小窗在video/live-player/live-pusher下可用) (13)worklet 动画 A、wx.worklet(Object object ) //获取worklet对象 6、网络 (1)发起请求,wx.request(Object object ) //发起HTTPS网络请求 wx.request({ url: 'example.php' , data: { x: '' , y: '' }, header: { 'content-type' : 'application/json' // 默认值 }, timeout: 60000, //默认值 method: 'get' , //默认值 dataType: 'text' , //默认值。返回的数据格式,即res.data,返回的数据为JSON时,返回后会对返回的数据进行一次 JSON.parse responseType: 'text' , //默认值。响应的数据类型,即res, enableProfil: true , //是否开启profile,默认开启 success (res) { console.log(res.profile) //网络连接过程中关键时间点的耗时信息 }, false (res) { console.log(res.errMsg) } }) (2)wx.downloadFile(Object object ) //下载文件资源到本地 const DownloadTask = wx.downloadFile({ url: 'https://example.com/audio/123' , filePath: '指定文件下载后存储的路径(本地路径)' , enableProfil: true , //是否开启profile,默认开启 success (res) { //只要服务器有响应数据,就会把响应内容写入文件并进入success回调,业务需要自行判断是否下载到了想要的内容 console.log(res.profile) //网络连接过程中关键时间点的耗时信息 if (res.statusCode === 200) { wx.playVoice({ filePath: res.tempFilePath }) } }, }) //DownloadTask.onProgressUpdate(function listener),监听下载进度变化事件 (3)wx.uploadFile(Object object ) //将本地资源上传到服务器 wx.chooseImage({ success (res) { const tempFilePaths = res.tempFilePaths const UploadTask = wx.uploadFile({ url: 'https://example.weixin.qq.com/upload' , //仅为示例,非真实的接口地址 filePath: tempFilePaths[0], name: 'file' , formData: { 'user' : 'test' }, enableProfil: true , //是否开启profile,默认开启 success (res){ const data = res.data //do something } }) //UploadTask.onProgressUpdate(function listener),监听上传进度变化事件 } }) (4)WebSocket //通过WebSocket连接发送数据 let socketOpen = false let socketMsgQueue = [] wx.connectSocket({ url: 'test.php' }) wx.onSocketOpen(function(res) { socketOpen = true for ( let i = 0; i < socketMsgQueue.length; i++){ sendSocketMessage(socketMsgQueue[i]) } socketMsgQueue = [] }) function sendSocketMessage(msg) { if (socketOpen) { wx.sendSocketMessage({ data:msg }) } else { socketMsgQueue.push(msg) } } 7、支付 (1)wx.requestVirtualPayment(Object object ),发起米大师虚拟支付 (2)wx.requestPluginPayment(Object object ),插件中发起支付 (3)wx.requestPayment(Object object ),发起微信支付 (4)wx.requestMerchantTransfer(Object object ),商家转账用户确认模式下,在微信客户端通过小程序拉起页面请求用户确认收款 //调用前需在微信支付商户平台/合作伙伴平台-产品中心,申请开通商家转账 (5)wx.requestCommonPayment(Object object ),发起通用支付 8、数据缓存 (1)wx.setStorageSync( string key, any data) //将数据存储在本地缓存中指定的key中,数据都一直可用 wx.setStorageSync( 'key' , 'value' ) (2)wx.setStorage(Object object ) //将数据存储在本地缓存中指定的key中,数据都一直可用 wx.setStorage({ key: "key" , data: "value" }) wx.setStorage({ //开启加密存储 key: "key" , data: "value" , encrypt: true , //若开启加密存储,setStorage和getStorage需要同时声明encrypt的值为true success() { wx.getStorage({ key: "key" , encrypt: true , //若开启加密存储,setStorage和getStorage需要同时声明encrypt的值为true success(res) { console.log(res.data) } }) } }) (3)wx.getStorageSync( string key) //从本地缓存中同步获取指定key的内容 (4)wx.getStorage(Object object ) //从本地缓存中异步获取指定key的内容 9、数据分析 10、XR-FRAME 11、画布 12、媒体 (1)地图 A、wx.createMapContext( string mapId, Object this ) //创建map上下文MapContext对象。 //建议使用“wx.createSelectorQuery”-1,获取context对象。 (2)图片 A、wx.saveImageToPhotosAlbum(Object object ) //保存图片到系统相册 B、wx.previewMedia(Object object ) //预览图片和视频 C、wx.previewImage(Object object ) //在新页面中全屏预览图片。预览的过程中用户可以进行保存图片、发送给朋友等操作 D、wx.getImageInfo(Object object ) //获取图片信息。网络图片需先配置download域名才能生效 E、wx.editImage(Object object ) //编辑图片接口 F、wx.cropImage(Object object ) //裁剪图片接口 G、wx.compressImage(Object object ) //压缩图片接口,可选压缩质量 H、wx.chooseMessageFile(Object object ) //从客户端会话选择文件 I、wx.chooseImage(Object object ) //从本地相册选择图片或使用相机拍照,请使用wx.chooseMedia代替 (3)视频 A、wx.saveVideoToPhotosAlbum(Object object ) //保存视频到系统相册。支持mp4视频格式 B、wx.openVideoEditor(Object object ) //打开视频编辑器 C、wx.getVideoInfo(Object object ) //获取视频详细信息 D、wx.createVideoContext( string id, Object this ) //创建video上下文VideoContext对象。 //建议使用“wx.createSelectorQuery”-1,获取context对象。 E、wx.compressVideo(Object object ) //压缩视频接口 F、wx.chooseVideo(Object object ) //拍摄视频或从手机相册中选视频,请使用wx.chooseMedia代替 G、wx.chooseMedia(Object object ) //拍摄或从手机相册中选择图片或视频 (4)音频 A、wx.stopVoice(Object object ) //结束播放语音,请使用wx.createInnerAudioContext代替 B、wx.setInnerAudioOption(Object object ) //设置InnerAudioContext的播放选项。设置之后对当前小程序全局生效。 C、wx.playVoice(Object object ) //开始播放语音,请使用wx.createInnerAudioContext代替 D、wx.pauseVoice(Object object ) //暂停正在播放的语音,请使用wx.createInnerAudioContext代替 E、wx.getAvailableAudioSources(Object object ) //获取当前支持的音频输入源 F、wx.createWebAudioContext() //创建WebAudio上下文 G、wx.createMediaAudioPlayer() //创建媒体音频播放器对象MediaAudioPlayer对象,可用于播放视频解码器VideoDecoder输出的音频 H、wx.createInnerAudioContext(Object object ) //创建内部audio上下文InnerAudioContext对象 I、wx.createAudioContext( string id, Object this ) //创建audio上下文AudioContext对象,请使用wx.createInnerAudioContext代替 (5)背景音频 A、wx.stopBackgroundAudio(Object object ) //停止播放音乐,请使用wx.getBackgroundAudioManager代替 B、wx.seekBackgroundAudio(Object object ) //控制音乐播放进度,请使用wx.getBackgroundAudioManager代替 C、wx.playBackgroundAudio(Object object ) //使用后台播放器播放音乐,请使用wx.getBackgroundAudioManager代替 D、wx.pauseBackgroundAudio(Object object ) //暂停播放音乐,请使用wx.getBackgroundAudioManager代替 E、wx.onBackgroundAudioStop(function listener) //监听音乐停止事件,请使用wx.getBackgroundAudioManager代替 F、wx.onBackgroundAudioPlay(function listener) //监听音乐播放事件,请使用wx.getBackgroundAudioManager代替 G、wx.onBackgroundAudioPause(function listener) //监听音乐暂停事件,请使用wx.getBackgroundAudioManager代替 H、wx.getBackgroundAudioPlayerState(Object object ) //获取后台音乐播放状态,请使用wx.getBackgroundAudioManager代替 I、wx.getBackgroundAudioManager() //获取全局唯一的背景音频管理器 (6)实时音视频 A、wx.createLivePusherContext() //创建live-pusher上下文LivePusherContext对象 B、wx.createLivePlayerContext( string id, Object this ) //创建live-player上下文LivePlayerContext对象 //建议使用“wx.createSelectorQuery”-1,获取context对象 (7)录音 A、wx.stopRecord(Object object ) //停止录音,请使用wx.getRecorderManager代替 B、wx.startRecord(Object object ) //开始录音,请使用wx.getRecorderManager代替 C、wx.getRecorderManager() //获取全局唯一的录音管理器RecorderManager (8)相机 A、wx.createCameraContext() //创建camera上下文CameraContext对象 (9)富文本 <editor id= "editor" /> //自写 const EditorContext = wx.createSelectorQuery() EditorContext. select ( '#editor' ) A、EditorContext.blur(Object object ) //编辑器失焦,同时收起键盘 B、EditorContext.clear(Object object ) //清空编辑器内容 C、EditorContext.format( string name, string value) //修改样式 D、EditorContext.getContents(Object object ) //获取编辑器内容 E、EditorContext.getSelectionText(Object object ) //获取编辑器已选区域内的纯文本内容 F、EditorContext.insertDivider(Object object ) //插入分割线 G、EditorContext.insertImage(Object object ) //插入图片 H、EditorContext.insertText(Object object ) //覆盖当前选区,设置一段文本 I、EditorContext.redo(Object object ) //恢复 J、EditorContext.removeFormat(Object object ) //清除当前选区的样式 K、EditorContext.scrollIntoView() //使得编辑器光标处滚动到窗口可视区域内 L、EditorContext.setContents(Object object ) //初始化编辑器内容,html和delta同时存在时仅delta生效 M、EditorContext.undo(Object object ) //撤销 N、 (10)音视频合成 A、wx.createMediaContainer() //创建音视频处理容器,最终可将容器中的轨道合成一个视频 (11)实时语音,下面接口不完整 A、wx.updateVoIPChatMuteConfig(Object object ) //更新实时语音静音设置 B、wx.subscribeVoIPVideoMembers(Object object ) //订阅视频画面成员 (12)画面录制器 A、wx.createMediaRecorder(Object canvas, Object options) //创建WebGL画面录制器,可逐帧录制在WebGL上渲染的画面并导出视频文件 (13)视频解码器 A、wx.createVideoDecoder() //创建视频解码器,可逐帧获取解码后的数据 13、位置,下面接口不完整 (1)wx.stopLocationUpdate(Object object ) //关闭监听实时位置变化,前后台都停止消息接收 (2)wx.startLocationUpdate(Object object ) //开启小程序进入前台时接收位置消息 (3)wx.openLocation(Object object ) //使用微信内置地图查看位置 (4)wx.getLocation(Object object ) //获取当前的地理位置、速度 14、文件 (1)wx.saveFileToDisk(Object object ) //保存文件系统的文件到用户磁盘,仅在PC端支持 (2)wx.openDocument(Object object ) //新开页面打开文档 (3)wx.getFileSystemManager() //获取全局唯一的文件管理器 15、开放接口 (1)登录 A、wx.pluginLogin(Object args) //该接口仅在小程序插件中可调用,调用接口获得插件用户标志凭证(code) B、wx.login(Object object ) //调用接口获取登录凭证(code) C、wx.checkSession(Object object ) //检查登录态是否过期 (2)账号信息 A、wx.getAccountInfoSync() //获取当前账号信息 (3)用户信息 A、wx.getUserProfile(Object object ) //获取用户信息 B、wx.getUserInfo(Object object ) //获取用户信息 (4)授权 A、wx.authorizeForMiniProgram //仅小程序插件中能调用该接口,用法同wx.authorize。目前仅支持三种scope wx.authorizeForMiniProgram({ scope: 'scope.record' , //scope.record、scope.writePhotosAlbum、scope.camera success () { //用户已经同意小程序使用录音功能,后续调用 wx.startRecord 接口不会弹窗询问 wx.startRecord() } }) B、wx.authorize //提前向用户发起授权请求 //可以通过 wx.getSetting 先查询一下用户是否授权了 "scope.record" 这个 scope wx.getSetting({ success(res) { if (!res.authSetting[ 'scope.record' ]) { wx.authorize({ scope: 'scope.record' , success () { // 用户已经同意小程序使用录音功能,后续调用 wx.startRecord 接口不会弹窗询问 wx.startRecord() } }) } } }) (5)设置 A、wx.openSetting //功能描述,调起客户端小程序设置界面,返回用户设置的操作结果 wx.openSetting({ success (res) { console.log(res.authSetting) // res.authSetting = { // "scope.userInfo": true, // "scope.userLocation": true // } } }) B、wx.getSetting //获取用户的当前设置 (6)收货地址 A、wx.chooseAddress(Object object ) //获取用户收货地址 (7)卡券 A、wx.openCard(Object object ) //查看微信卡包中的卡券 B、wx.addCard(Object object ) // (8)发票 A、wx.chooseInvoiceTitle(Object object ) //选择用户的发票抬头 B、wx.chooseInvoice(Object object ) //选择用户已有的发票 (9)生物认证 A、wx.startSoterAuthentication(Object object ) //开始SOTER生物认证 B、wx.checkIsSupportSoterAuthentication(Object object ) //获取本机支持的SOTER生物认证方式 C、wx.checkIsSoterEnrolledInDevice(Object object ) //获取设备内是否录入如指纹等生物信息的接口 (10)微信运动 A、wx.shareToWeRun(Object object ) //分享数据到微信运动 B、wx.getWeRunData(Object object ) //获取用户过去三十一天微信运动步数 (11)订阅消息 A、wx.requestSubscribeMessage(Object object ) //调起客户端小程序订阅消息界面,返回用户订阅消息的操作结果 B、wx.requestSubscribeDeviceMessage(Object object ) //订阅设备消息接口,调用后弹出授权框,用户同意后会允许开发者给用户发送订阅模版消息 (12)微信红包 A、wx.showRedPackage(Object object ) //拉取h5领取红包封面页 (13)收藏 A、wx.addVideoToFavorites(Object object ) //收藏视频 B、wx.addFileToFavorites(Object object ) //收藏文件 (14)我的小程序 A、wx.checkIsAddedToMyMiniProgram(Object object ) //检查小程序是否被添加至 「我的小程序」 (15)车牌 A、wx.chooseLicensePlate(Object object ) //选择车牌号 (16)视频号 A、wx.reserveChannelsLive(Object object ) //预约视频号直播 B、wx.openChannelsUserProfile(Object object ) //打开视频号主页 C、wx.openChannelsLive(Object object ) //打开视频号直播 D、wx.openChannelsEvent(Object object ) //打开视频号活动页 E、wx.openChannelsActivity(Object object ) //打开视频号视频 F、wx.getChannelsShareKey(Object object ) //获取视频号直播卡片/视频卡片的分享来源 G、wx.getChannelsLiveNoticeInfo(Object object ) //获取视频号直播预告信息 H、wx.getChannelsLiveInfo(Object object ) //获取视频号直播信息 (17)音视频通话 A、wx.requestDeviceVoIP(Object object ) //请求用户授权与设备(组)间进行音视频通话 B、wx.getDeviceVoIPList(Object object ) //查询当前用户授权的音视频通话设备(组)信息 (18)微信群 A、wx.getGroupEnterInfo(Object object ) //获取微信群聊场景下的小程序启动信息 (19)隐私信息授权 A、wx.requirePrivacyAuthorize(Object object ) //模拟隐私接口调用,并触发隐私弹窗逻辑 B、wx.openPrivacyContract(Object object ) //跳转至隐私协议页面 C、wx.onNeedPrivacyAuthorization(function listener) //监听隐私接口需要用户授权事件 D、wx.getPrivacySetting(Object object ) //查询隐私授权情况 (20)微信客服 A、wx.openCustomerServiceChat(Object object ) //打开微信客服,页面产生点击事件(例如 button 上 bindtap 的回调中)后才可调用 (21)微信表情 A、wx.openStickerSetView(Object object ) //打开表情专辑 B、wx.openStickerIPView(Object object ) //打开表情IP合辑 C、wx.openSingleStickerView(Object object ) //打开单个表情 16、设备 (1)蓝牙-通用 (2)蓝牙-低功耗中心设备 (3)蓝牙-低功耗外围设备 (4)蓝牙-信标(Beacon) (5)NFC读写 A、wx.getNFCAdapter() //获取NFC实例 (6)Wi-Fi(wifi),无线保真(Wireless Fidelity),下面接口不完整 A、wx.stopWifi(Object object ) //关闭wifi模块 B、wx.startWifi(Object object ) //初始化wifi模块 C、wx.setWifiList(Object object ) //设置wifiList中 AP 的相关信息,iOS特有接口 D、wx.getWifiList(Object object ) //请求获取wifi列表 E、wx.getConnectedWifi(Object object ) //获取已连接中的wifi信息 (7)日历 (8)联系人 A、wx.chooseContact(Object object ) //拉起手机通讯录,选择联系人 B、wx.addPhoneContact(Object object ) //添加手机通讯录联系人 (9)无障碍 A、wx.checkIsOpenAccessibility(Object object ) //检测是否开启视觉无障碍功能 (10)电量 A、wx.getBatteryInfoSync() //同步获取设备电量 B、wx.getBatteryInfo(Object object ) //获取设备电量 (11)剪贴板 A、wx.setClipboardData(Object object ) //设置系统剪贴板的内容 B、wx.getClipboardData(Object object ) //获取系统剪贴板的内容 (12)NFC主机卡模拟 (13)网络 A、wx.onNetworkWeakChange(function listener) //监听弱网状态变化事件 B、wx.onNetworkStatusChange(function listener) //监听网络状态变化事件 C、wx.offNetworkWeakChange(function listener) //移除弱网状态变化事件的监听函数 D、wx.offNetworkStatusChange(function listener) //移除网络状态变化事件的监听函数 E、wx.getNetworkType(Object object ) //获取网络类型 F、wx.getLocalIPAddress(Object object ) // (14)加密 A、wx.getRandomValues(Object object ) //获取密码学安全随机数 (15)屏幕 A、wx.setVisualEffectOnCapture(Object object ) //wx.setVisualEffectOnCapture(Object object) B、wx.setScreenBrightness(Object object ) //设置屏幕亮度 C、wx.setKeepScreenOn(Object object ) //设置是否保持常亮状态 D、wx.onUserCaptureScreen(function listener) //监听用户主动截屏事件 E、wx.onScreenRecordingStateChanged(function listener) //监听用户录屏事件 F、wx.offUserCaptureScreen(function callback) //取消监听用户主动截屏事件 G、wx.offScreenRecordingStateChanged(function listener) //移除用户录屏事件的监听函数 H、wx.getScreenRecordingState(Object object ) //查询用户是否在录屏 I、wx.getScreenBrightness(Object object ) //获取屏幕亮度 (16)键盘 A、wx.onKeyboardHeightChange(function listener) //监听键盘高度变化事件 B、wx.offKeyboardHeightChange(function listener) //移除键盘高度变化事件的监听函数 C、wx.hideKeyboard(Object object ) //在input、textarea等focus拉起键盘之后,手动调用此接口收起键盘 D、wx.getSelectedTextRange(Object object ) //在input、textarea等focus之后,获取输入框的光标位置 (17)电话 A、wx.makePhoneCall(Object object ) //拨打电话 (18)加速计,例如摇一摇 A、wx.stopAccelerometer(Object object ) //停止监听加速度数据 B、wx.startAccelerometer(Object object ) //开始监听加速度数据 C、wx.onAccelerometerChange(function listener) //监听加速度数据事件 D、wx.offAccelerometerChange(function listener) //移除加速度数据事件的监听函数 (19)罗盘 A、wx.stopCompass(Object object ) //停止监听罗盘数据 B、wx.startCompass(Object object ) //开始监听罗盘数据 C、wx.onCompassChange(function listener) //罗盘数据变化事件的监听函数 D、wx.offCompassChange(function listener) //移除罗盘数据变化事件的监听函数 (20)设备方向 A、wx.stopDeviceMotionListening(Object object ) //停止监听设备方向的变化 B、wx.startDeviceMotionListening(Object object ) //开始监听设备方向的变化 C、wx.onDeviceMotionChange(function listener) //监听设备方向变化事件 D、wx.offDeviceMotionChange(function listener) //移除设备方向变化事件的监听函数 (21)陀螺仪,测量偏转、倾斜时的转动角速度 A、wx.stopGyroscope(Object object ) //停止监听陀螺仪数据 B、wx.startGyroscope(Object object ) //开始监听陀螺仪数据 C、wx.onGyroscopeChange(function listener) //监听陀螺仪数据变化事件 D、wx.offGyroscopeChange(function listener) //移除陀螺仪数据变化事件的监听函数 (22)内存 A、wx.onMemoryWarning(function listener) //监听内存不足告警事件 B、wx.offMemoryWarning(function listener) //移除内存不足告警事件的监听函数 (23)扫码 A、wx.scanCode(Object object ) //调起客户端扫码界面进行扫码 (24)短信 A、wx.sendSms(Object object ) //拉起手机发送短信界面 (25)振动 A、wx.vibrateShort(Object object ) //使手机发生较短时间的振动(15 ms) B、wx.vibrateLong(Object object ) //使手机发生较长时间的振动(400 ms) 17、AI (1)AI推理 A、wx.getInferenceEnvInfo(Object object ) //获取通用AI推理引擎版本 B、wx.createInferenceSession(Object object ) //创建AI推理Session (2)视觉算法 A、wx.isVKSupport( string version) //判断支持版本 B、wx.createVKSession(Object object ) //创建vision kit会话对象 (3)人脸检测 A、wx.stopFaceDetect(Object object ) //停止人脸检测。本接口不再维护,请使用wx.createVKSession接口代替 B、wx.initFaceDetect(Object object ) //初始化人脸检测。本接口不再维护,请使用wx.createVKSession接口代替 C、wx.faceDetect(Object object ) //人脸检测。本接口不再维护,请使用wx.createVKSession接口代替 18、Worker function createNewWorker() { const worker = wx.createWorker( 'workers/index.js' , { //创建一个Worker线程 useExperimentalWorker: true }) //监听worker被系统回收事件 worker.onProcessKilled(() => { //重新创建一个worker createNewWorker() }) } //创建实验worker createNewWorker() 19、WXML const query = wx.createSelectorQuery() //返回一个SelectorQuery对象实例。在自定义组件或包含自定义组件的页面中,应使用this.createSelectorQuery()来代替 query. select ( '#the-id' ).boundingClientRect() query.selectViewport().scrollOffset() query.exec(function(res){ res[0].top //#the-id节点的上边界坐标 res[1].scrollTop //显示区域的竖直滚动位置 }) 20、第三方平台 21、广告 22、Skyline 十一、uniapp跨端框架-简介 来源,https: //gitee.com/dcloud/uni-app/tags?page=60 来源,https: //uniapp.dcloud.net.cn/history.html 来源,https: //uniapp.dcloud.net.cn/tutorial/ 1、uni-app的产生背景 注、Dcloud一般指数字天堂(北京)网络技术有限公司,2012年04月登记成立,法定代表人王安;来源,百度百科“Dcloud” (1)2011年1月,微信1.0发布 (2)2012年,DCloud开始研发小程序技术,推出了HBuilder开发工具 (3)2015年,DCloud商用了小程序技术,命名“流应用”,并将该技术标准捐给工信部,同时推进各家流量巨头接入该标准, 众多开发者用该标准为“流应用”平台提供应用,供用户下载 (4)2015年9月,DCloud推进微信团队开展小程序业务 (5)2016年初,微信团队决定上线微信小程序业务,订制了自己的标准,随后包括手机厂商在内的各大流量巨头, 陆续上线类似微信小程序的业务 (6)2017年1月,微信小程序发布,微信开发工具开发的微信小程序只能在微信上运行, 来源,https: //developers.weixin.qq.com/miniprogram/dev/component/text.html (7)2018年8月,DCloud发布uni-app1.0,为开发者抹平各平台的差异,让一套代码在各APP(应用)上运行, 开发工具为HBuilder,js框架为vue,DCloud由标准的提供者转为标准的汇总者 2、uni-app的版本发布 (1)2018年8月,uni-app1.0.0 版本发布, (2)2021年9月,uni-app2.0.0 版本发布, (3)2023年1月,uni-app3.0.0 版本发布, 3、uni-app与weex[wi:ks]、mpvue功能类似,通过单一代码库构建iOS、Android、Web(H5)和小程序等多个平台的应用 (1)2016年4月,阿里巴巴发布跨平台移动开发工具weex,开发者将Weex的SDK嵌入自己的APP,解决了频繁发版和多端研发两大问题 (2)uni-app的vue页面,用“WebKit的”webview渲染,WebKit是一个开源的浏览器引擎 (3)uni-app的nvue页面,用“基于weex改进的”原生渲染引擎渲染,nvue是“native vue”的缩写,意为“原生vue” (4)原生渲染引擎,不是封装别人现成的渲染引擎,而是自己开发的渲染引擎 (5)自悟,浏览器与APP,前者可以浏览所有网站,后者只能浏览一个网站 4、Hybrid,混合开发 (1)Native App,一般指原生应用,是一个完整的应用,依托于操作系统,交互性强,拓展性强,需要用户下载安装使用 (2)Web App,一般指H5应用,使用Web技术(如HTML、CSS和JavaScript)来创建应用程序的用户界面 (3)Hybrid App,一般是指混合型App,带有原生应用外壳的Web应用,是最多的移动端开发方式 A、底层依赖于Native提供的容器(WebView),上层使用html&css&JS做业务开发 B、既有前者良好用户体验的优势,又有后者使用HTML5跨平台开发低成本的优势 5、uni-app与hybrid的区别 (1)uni-app,用于移动端,后出现,负责-前后端分离-的前端 (2)hybrid,用于移动端,先出现,负责-前后端混合-的全部 十二、uniapp跨端框架-教程 1、uni-app的开发规范 (1)页面文件遵循Vue单文件组件(SFC)规范,即每个页面是一个.vue文件 (2)组件标签靠近小程序规范, (3)接口能力靠近小程序规范,但需将前缀wx、my等替换为uni (4)数据绑定及事件处理同Vue.js规范,同时补充了应用生命周期及页面的生命周期 (5)如需兼容app-nvue平台,建议使用flex布局进行开发 (6)uni-app分编译器和运行时(runtime),都内置在HBuilderX中,编译器在开发环境编译代码并生成输出物, 在各终端上,各运行时(runtime)解析各输出物 2、uni-app的编译器 (1)编译器,运行在电脑开发环境 (2)开发者按uni-app规范编写代码,由编译器将开发者的统一代码编译生成每个平台支持的特有代码 在web平台,将.vue文件编译为js代码 在微信小程序平台,编译器将.vue文件拆分生成wxml、wxss、js等代码 在app平台,将.vue文件编译为js代码 在Android平台,将.uts文件编译为kotlin代码 在iOS平台,将.uts文件编译为swift代码 (3)uni-app项目根据所依赖的Vue版本不同,编译器的实现也不同 vue2版,基于webpack实现 vue3版,基于Vite实现,性能更快 (4)支持条件编译 (5)编译到任意平台时, static 目录下满足编译条件的文件,会直接复制到最终的打包目录 非 static 目录下的文件(vue、js、css等)只有被引用时,才会被打包编译 (6).uts,意为统一类型脚本,全称为“uni type script” 3、uni-app的运行时(runtime) (1)runtime,运行在终端上,动态处理数据绑定、事件代理,保证Vue和平台宿主数据的一致性,这是一个比较庞大的工程 在小程序端,uni-app的runtime,主要是一个小程序版的vue runtime,页面路由、组件、api等方面基本都是转义 在web端,uni-app的runtime相比普通的vue项目,多了一套ui库、页面路由框架、和uni对象(即常见API封装) 在App端,uni-app的runtime更复杂,DCloud也有一套小程序引擎,打包app时将开发者的代码和DCloud的小程序打包成了apk或ipa (2)uni-app的runtime包括3部分,基础框架、组件、API 4、uni-app处理各终端的逻辑层和视图层分离 (1)在web平台,逻辑层(js)和视图层(html、css),都运行在统一的webview里 (2)在小程序和app端,逻辑层和视图层被分离了,原因为基于webview的app因js运算和界面渲染抢资源导致卡顿而性能不佳 逻辑层都独立成单独的js引擎,不支持浏览器专用的window、dom等API, 视图层仍然是webview,能视图层操作window、dom 5、uni-app的工程,一个uni-app工程,就是一个“Vue项目”(非常重要),可以通过HBuilderX或cli快速创建 6、页面 (1)一个页面就是一个符合Vue SFC规范的.vue文件或.nvue文件 (2)页面保存在工程根目录下的pages目录下 (3)每次新建页面,均需在工程根目录下的pages.json中配置pages列表 (4)删除页面时,需删除.vue文件或.nvue文件,删除pages.json中pages列表项中的配置 (5)uni-app会将pages.json中pages配置项中的第一个页面,作为当前工程的首页(启动页) (6)uni-app页面除支持Vue组件生命周期外还支持页面生命周期函数onInit、onLoad、onShow、onReady、onHide、onUnload、onResize、......... (7)uni-app组件支持的生命周期,与vue标准组件的生命周期相同beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed (8)页面调用接口 getApp,函数用于获取当前应用实例,一般用于获取全局数据 const app = getApp() console.log(app.globalData) getCurrentPages,函数用于获取当前页面栈的实例,以数组形式按栈的顺序给出,第一个元素为首页,最后一个元素为当前页面 const page = getCurrentPages() page.$getAppWebview(),获取当前页面的webview对象实例 page.route,获取当前页面的路由 $getAppWebview(),在getCurrentPages()获得的页面里内置了一个方法$getAppWebview(),获取当前页面的webview对象实例 var pages = getCurrentPages(); var page = pages[pages.length - 1]; var currentWebview = page.$getAppWebview(); console.log(currentWebview.id); //获得当前webview的id console.log(currentWebview.isVisible()); //查询当前webview是否可见 (9)页面通讯 uni.$emit(eventName,OBJECT),触发全局的自定义事件,附加参数都会传给监听器回调 uni.$ on (eventName,callback),监听全局的自定义事件,事件可以由 uni.$emit 触发,回调函数会接收所有传入事件触发函数的额外参数 uni.$once(eventName,callback),监听全局的自定义事件,事件可以由 uni.$emit 触发,但是只触发一次,在第一次触发之后移除监听器 uni.$off([eventName,callback]),移除全局自定义事件监听器 (10)uni-app框架统一管理页面路由,开发者需要在pages.json里配置每个路由页面的路径及页面样式,使用navigator组件跳转、调用API跳转 (11)框架以栈的形式管理当前所有页面 (12)支持在template模板中嵌套<template/>和<block/> (13)nvue开发与vue开发的常见区别 7、组件 (1)uni-app组件 视图容器 基础内容 表单组件 路由与页面跳转 媒体组件 (2)Vue组件 (3)NVUE组件 (4)小程序组件 (5)扩展组件(uni-ui) 8、引用组件 (1)传统vue项目开发,引用组件需要导入-注册-使用三个步骤,如下: <template> <view> <!-- 3.使用组件 --> <uni-rate text= "1" ></uni-rate> </view> </template> <script> //1. 导入组件 import uniRate from '@/components/uni-rate/uni-rate.vue' ; export default { components: { uniRate } //2. 注册组件 } </script> (2)Vue 3.x增加了script setup特性,将三步优化为两步,无需注册步骤,更为简洁: <template> <view> <!-- 2.使用组件 --> <uni-rate text= "1" ></uni-rate> </view> </template> <script setup> //1. 导入组件 import uniRate from '@/components/uni-rate/uni-rate.vue' ; </script> (3)uni-app的easycom机制,将组件引用进一步优化,开发者只管使用,无需考虑导入和注册,更为高效: 在 uni-app 项目中,页面引用组件和组件引用组件的方式都是一样的(可以理解为:页面是一种特殊的组件),均支持通过 easycom 方式直接引用。 <template> <view> <!-- 1.使用组件 --> <uni-rate text= "1" ></uni-rate> </view> </template> <script> </script> 9、引用JS (1)绝对路径,@指向项目根目录,在cli项目中@指向src目录 import add from '@/common/add.js' ; (2)相对路径 import add from '../../common/add.js' ; (3)js中引入npm包 import package from 'packageName' const package = require( 'packageName' ) 10、引用CSS <style> @import "../../common/uni.css" ; .uni-card { box-shadow: none; } </style> 11、引用静态资源,https: //uniapp.dcloud.net.cn/tutorial/page-static-assets.html (1)#模板内引入静态资源 template内引入静态资源,如image、video等标签的src属性时,可以使用相对路径或者绝对路径 <!-- 绝对路径,/ static 指根目录下的 static 目录,在cli项目中/ static 指src目录下的 static 目录 --> <image class = "logo" src= "/static/logo.png" ></image> <image class = "logo" src= "@/static/logo.png" ></image> <!-- 相对路径 --> <image class = "logo" src= "../../static/logo.png" ></image> (2)css 引入静态资源 css文件或style标签内引入css文件时(scss、less 文件同理),可以使用相对路径或绝对路径 /* 绝对路径 */ @import url( '/common/uni.css' ); @import url( '@/common/uni.css' ); /* 相对路径 */ @import url( '../../common/uni.css' ); 12、JS语法 (1)uni-app的js API由标准ES的js API和uni扩展API这两部分组成 标准ECMAScript的js仅是最基础的js 浏览器扩展了window、document、navigator等对象 小程序扩展了各种wx.xx、my.xx、swan.xx的API node扩展了fs等模块 uni-app扩展了uni对象,并且API命名与小程序保持兼容 (2)标准js和浏览器js的区别 h5端,JS运行于浏览器中 非h5端(包含小程序和App),Android平台JS运行在v8引擎中,iOS平台JS运行在iOS自带的jscore引擎中,都没有运行在浏览器或webview里 非H5端,虽然不支持window、document、navigator等浏览器的js API,但也支持标准ECMAScript (3)支持绝大部分ES6 API的同时,也支持了ES7的 await/async 13、CSS语法 (1)uni-app的css与web的css基本一致 (2)nvue页面里的样式比web页面里的样式限制更多 (3)支持的通用css单位包括px、rpx 14、vue语法,仅以“组合式API”为例 (1)目前uni-app基于Vue2.6,组合式API由@vue/composition-api支持,setup由unplugin-vue2-script-setup支持 (2)在main.js或main.ts文件内增加安装@vue/composition-api插件 (3)在每个nvue页面安装@vue/composition-api插件 15、vue3组合式API(Composition API),按照逻辑关注点,对部分代码进行分组 注,来自于文章10,https: //www.cnblogs.com/gushixianqiancheng/p/13392540.html (1)vue2中,通过配置项(data、computed、methods、watch)将相关逻辑拆散,不便于组件阅读和维护 (2)vue3中,通过组合式API(setup、 ref 、reactive、watchEffect、watch、computed、toRefs、生命周期的hooks),将相关逻辑写在一起,便于组件阅读和维护 (3)setup函数接受两个参数:(props、context) props参数是响应式数据,解构props的操作必须通过toRefs完成,toRefs将对象的多个属性变成响应式数据,如 var {title} = toRefs(props) context参数不是响应式数据,可以直接解构,包含attrs、slots、emit,其中attrs是组件的props配置中没有声明的属性 (4)setup执行时,组件实例尚未被创建, this 修改成undefined (5)setup之 ref 和reactive的区别 ref 定义基本类型数据,使用Object.defineProperty实现数据代理,使用refData.value.name获取数据(template模板中不需要.value) reactive定义引用类型数据,使用Proxy实现数据代理,使用reactData.username获取数据 (6)setup通过 ref 、reactive、computed生成组件所需值;通过方法,改变组件值、全局值 以下,组合式API之computed,来源,https: //blog.csdn.net/ct5211314/article/details/125874348 <template> <div> <div>姓:<input type= "text" v-model= "per.surname" ></div> <div>名:<input type= "text" v-model= "per.name" ></div> <div>姓名:<input type= "text" v-model= "per.fullName" ></div> </div> </template> <script> import { computed, reactive } from 'vue' export default { setup(){ let per = reactive({ surname: '勇敢' , name: '小陈' }) per.fullName = computed(()=>{ return per.surname+ '~' +per.name }) return { per } } } </script> 以下,组合式API之watchEffect,来源,https: //blog.csdn.net/ZYS10000/article/details/124535467 watchEffect,是一个帧听器,是一个副作用函数,它会监听引用数据类型的所有属性,不需要具体到某个属性,一旦运行就会立即监听,组件卸载的时候会停止监听。 import { reactive, watchEffect } from 'vue' ; export default { setup(){ let obj = reactive({ name: 'zs' }); watchEffect(() => { console.log( 'name:' ,obj.name) }) return { obj } } } 16、ts语法 <script lang= "ts" > //这里编写ts代码 let s: string = "123" console.log(s) </script> 17、uts语法 (1)uts,全称uni type script,是一门跨平台的、高性能的、强类型的现代编程语言, (2)uts采用了与ts基本一致的语法规范,支持绝大部分ES6 API (3)uts可以被编译为不同平台的编程语言 web平台,编译为JavaScript Android平台,编译为Kotlin iOS平台,编译Swift 十三、uniapp跨端框架-全局文件 1、pages.json 页面路由,对uni-app进行全局配置,决定页面文件的路径、窗口样式、原生的导航栏、底部的原生tabbar 等 { "pages" : [{ "path" : "pages/component/index" , "style" : { "navigationBarTitleText" : "组件" } }, { "path" : "pages/API/index" , "style" : { "navigationBarTitleText" : "接口" } }, { "path" : "pages/component/view/index" , "style" : { "navigationBarTitleText" : "view" } }], "condition" : { //模式配置,仅开发期间生效 "current" : 0, //当前激活的模式(list 的索引项) "list" : [{ "name" : "test" , //模式名称 "path" : "pages/component/view/index" //启动页面,必选 }] }, "globalStyle" : { "navigationBarTextStyle" : "black" , "navigationBarTitleText" : "演示" , "navigationBarBackgroundColor" : "#F8F8F8" , "backgroundColor" : "#F8F8F8" , "usingComponents" :{ "collapse-tree-item" : "/components/collapse-tree-item" }, "renderingMode" : "seperated" , //仅微信小程序,webrtc 无法正常时尝试强制关闭同层渲染 "pageOrientation" : "portrait" , //横屏配置,全局屏幕旋转设置(仅 APP/微信/QQ小程序),支持 auto / portrait / landscape "rpxCalcMaxDeviceWidth" : 960, "rpxCalcBaseDeviceWidth" : 375, "rpxCalcIncludeWidth" : 750 }, "tabBar" : { "color" : "#7A7E83" , "selectedColor" : "#3cc51f" , "borderStyle" : "black" , "backgroundColor" : "#ffffff" , "height" : "50px" , "fontSize" : "10px" , "iconWidth" : "24px" , "spacing" : "3px" , "iconfontSrc" : "static/iconfont.ttf" , //app tabbar 字体.ttf文件路径 app 3.4.4+ "list" : [{ "pagePath" : "pages/component/index" , "iconPath" : "static/image/icon_component.png" , "selectedIconPath" : "static/image/icon_component_HL.png" , "text" : "组件" , "iconfont" : { //优先级高于 iconPath,该属性依赖 tabbar 根节点的 iconfontSrc "text" : "\ue102" , "selectedText" : "\ue103" , "fontSize" : "17px" , "color" : "#000000" , "selectedColor" : "#0000ff" } }, { "pagePath" : "pages/API/index" , "iconPath" : "static/image/icon_API.png" , "selectedIconPath" : "static/image/icon_API_HL.png" , "text" : "接口" }], "midButton" : { "width" : "80px" , "height" : "50px" , "text" : "文字" , "iconPath" : "static/image/midButton_iconPath.png" , "iconWidth" : "24px" , "backgroundImage" : "static/image/midButton_backgroundImage.png" } }, "easycom" : { "autoscan" : true , //是否自动扫描组件 "custom" : { //自定义扫描规则 "^uni-(.*)" : "@/components/uni-$1.vue" } }, "topWindow" : { "path" : "responsive/top-window.vue" , "style" : { "height" : "44px" } }, "leftWindow" : { "path" : "responsive/left-window.vue" , "style" : { "width" : "300px" } }, "rightWindow" : { "path" : "responsive/right-window.vue" , "style" : { "width" : "300px" }, "matchMedia" : { "minWidth" : 768 } } } 2、manifest.json配置,文件是应用的配置文件,用于指定应用的名称、图标、权限等 { "quickapp-webview" : { //快应用通用配置 "icon" : "/static/logo.png" , "package" : "com.example.demo" , "versionName" : "1.0.0" , "versionCode" : 100 }, "quickapp-webview-union" : { //快应用联盟,目前仅支持 vivo、oppo "minPlatformVersion" : 1063 //最小平台支持 }, "quickapp-webview-huawei" : { //快应用华为 "minPlatformVersion" : 1070 //最小平台支持 } } 3、package.json扩展配置 { /** * package.json其它原有配置 * 拷贝代码后请去掉注释! */ "uni-app" : { //扩展配置 "scripts" : { "custom-platform" : { //自定义编译平台配置,可通过cli方式调用 "title" : "自定义扩展名称" , //在HBuilderX中会显示在 运行/发行 菜单中 "browser" : "" , //运行到的目标浏览器,仅当UNI_PLATFORM为h5时有效 "env" : { //环境变量 "UNI_PLATFORM" : "" , //基准平台 "MY_TEST" : "" , //... 其他自定义环境变量 }, "define" : { //自定义条件编译 "CUSTOM-CONST" : true //自定义条件编译常量,建议为大写 } } } } } 4、vue.config.js,是一个可选的配置文件,如果项目的根目录中存在这个文件,那么它会被自动加载,一般用于配置webpack等编译选项 const path = require( 'path' ) const webpack = require( 'webpack' ) const CopyWebpackPlugin = require( 'copy-webpack-plugin' ) //最新版本copy-webpack-plugin插件暂不兼容,推荐v5.0.0 module.exports = { configureWebpack: { plugins: [ new CopyWebpackPlugin([ { from : path. join (__dirname, 'src/images' ), to: path. join (__dirname, 'dist' , process.env.NODE_ENV === 'production' ? 'build' : 'dev' , process.env.UNI_PLATFORM, 'images' ) } ]) ] }, chainWebpack: config => { config .plugin( 'define' ) .tap(args => { args[0][ 'process.env' ].VUE_APP_TEST = '"test"' return args }) } } 5、vite.config.js,是一个可选的配置文件,如果项目的根目录中存在这个文件,那么它会被自动加载,一般用于配置vite的编译选项, 必须引用 '@dcloudio/vite-plugin-uni' 并且添加到 plugins 中 示例一、自定义静态资源目录 import path from 'path' ; import fs from 'fs-extra' ; import { defineConfig } from 'vite' ; import uni from '@dcloudio/vite-plugin-uni' ; function copyFile() { return { enforce: 'post' , async writeBundle() { await fs.copy( path.resolve(__dirname, 'images' ), path. join ( __dirname, 'unpackage/dist' , process.env.NODE_ENV === 'production' ? 'build' : 'dev' , process.env.UNI_PLATFORM, 'images' ) ); }, }; } export default defineConfig({ plugins: [uni(), copyFile()], }); 示例二、注入全局依赖 //示例从插件市场下载 mp-storage import path from 'path' ; import { defineConfig } from 'vite' ; import uni from '@dcloudio/vite-plugin-uni' ; import inject from '@rollup/plugin-inject' ; const mpStoragePath = path.resolve(__dirname, './js_sdk/mp-storage/mp-storage' ); export default defineConfig({ plugins: [ uni(), inject({ localStorage: [mpStoragePath, 'localStorage' ], 'window.localStorage' : [mpStoragePath, 'localStorage' ], }), ], define: { 'process.env.VUE_APP_TEST' : JSON.stringify( 'test' ), }, }); 示例三、配置环境变量 import { defineConfig } from 'vite' ; import uni from '@dcloudio/vite-plugin-uni' ; export default defineConfig({ plugins: [uni()], define: { 'process.env.VUE_APP_TEST' : JSON.stringify( 'test' ), }, }); 6、uni.scss文件的用途是为了方便整体控制应用的风格。比如按钮颜色、边框风格,uni.scss文件里预置了一批scss变量预置 <style lang= "scss" > </style> 以下是uni.scss的相关变量 $uni-color-primary: #007aff; $uni-color-success: #4cd964; $uni-color-warning: #f0ad4e; $uni-color-error: #dd524d; 7、App.vue是uni-app的主组件,所有页面都是在App.vue下进行切换的,是页面的入口文件 (1)App.vue本身不是页面,这里不能编写视图元素,也就是没有<template> (2)这个文件的作用包括:调用应用生命周期函数、配置全局样式、配置全局的存储globalData (3)应用生命周期仅可在App.vue中监听,在页面监听无效 (4)js中操作globalData的方式如下:getApp().globalData.text = 'test' (5)示例代码 <script> //只能在App.vue里监听应用的生命周期 export default { globalData: { text: 'text' } onLaunch: function() { console.log( 'App Launch' ) }, onShow: function() { console.log( 'App Show' ) }, onHide: function() { console.log( 'App Hide' ) } } </script> 8、main.js是uni-app的入口文件,主要作用是初始化vue实例、定义全局组件、使用需要的插件如vuex (1)vue2代码示例 import Vue from 'vue' import App from './App' import pageHead from './components/page-head.vue' //全局引用 page-head 组件 Vue.config.productionTip = false Vue.component( 'page-head' , pageHead) //全局注册 page-head 组件,每个页面将可以直接使用该组件 App.mpType = 'app' const app = new Vue({ ...App }) app.$mount() //挂载 Vue 实例 (2)vue3代码示例 import App from './App' import { createSSRApp } from 'vue' export function createApp() { const app = createSSRApp(App) return { app } } 十四、postcss.config.js 来源,https: //www.fke6.com/html/110797.html 来源,https: //blog.csdn.net/Jensen_Yao/article/details/103203490 注、通过gulp、webpack、grunt等构建工具来使用,用于配置PostCSS的插件和选项,处理CSS 1、示例一,插件排序与插件参数 module.exports = { plugins: [ //插件排序 require( 'postcss-import' ), require( 'postcss-url' )({ //插件参数 url: 'inline' }), require( 'precss' ), require( 'autoprefixer' )({ //插件参数 browsers: [ 'last 2 versions' ] }) ] } 2、示例二,px转rem,rootValue*10=设计稿的宽 module.exports = () => ({ plugins: [ require( 'autoprefixer' )(), //require('postcss-px2rem')({ remUnit: 75 }) require( 'postcss-pxtorem' )({ rootValue: 37.5, //对应设计图宽度375px propList: [ '*' ], //将哪些属性的px值转换,['*']将所有属性的px值转换,['*', '!border*']含border的属性的px值不转换,其余的都转换 }) ] }); 3、示例三,px转vw module.exports = { plugins: { autoprefixer: {}, 'postcss-px-to-viewport' : { exclude: undefined, //忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件 fontViewportUnit: 'vw' , //字体使用的视口单位 include: undefined, //如果设置了include,那将只有匹配到的文件才会被转换 landscape: false , //是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape) landscapeUnit: 'vw' , //横屏时使用的单位 landscapeWidth: 1920, //横屏时使用的视口宽度 mediaQuery: false , //媒体查询里的单位`px`是否需要转换,false为默认值 minPixelValue: 1, //设置最小的转换数值,只有大于`1px`的值转换为视窗单位 propList: [ '*' ], //能转化为vw的属性列表 replace: true , //是否直接更换属性值,而不添加备用属性 selectorBlackList: [ 'p' , '.hairlines' ], //需要忽略的CSS选择器,不会转为视口单位,使用原有的px等单位 unitPrecision: 5, //转换后保留的小数位数,precision精确 unitToConvert: 'px' , //需要转换的单位,默认为"px" viewportWidth: 375, //设计稿的视口宽度,375px=100vw viewportHeight: 1334, //视窗的高度,1334px=100vh viewportUnit: 'vw' , //指定转换后的视窗单位,建议使用vw }, 'postcss-viewport-units' : { //排除会产生警告的部份 filterRule: rule => rule.nodes.findIndex(i => i.prop === 'content' ) === -1 }, cssnano: { //集成了部分PostCSS插件,用false禁用其中的某个插件,nano毫微 preset: 'advanced' , //预设: 高级(转换) autoprefixer: false , //禁用autoprefixer,和上面的autoprefixer: {}具有相同效果 'postcss-zindex' : false } } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具