chore: opensource v1-doc
parent
28325c0507
commit
7c1a14bb5e
|
@ -44,14 +44,6 @@ jobs:
|
|||
with:
|
||||
token: ${{ secrets.ACCESS_TOKEN }}
|
||||
|
||||
- name: Checkout submodules
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: tangjinzhou/antdv-demo
|
||||
token: ${{ secrets.ACCESS_TOKEN }}
|
||||
path: antdv-demo
|
||||
submodules: true
|
||||
|
||||
- name: restore cache from package-lock.json
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
[submodule "antdv-demo"]
|
||||
path = antdv-demo
|
||||
url = git@github.com:tangjinzhou/antdv-demo.git
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"env": {
|
||||
"test": {
|
||||
"presets": [["env", { "targets": { "node": "current" } }]],
|
||||
"plugins": [
|
||||
"transform-vue-jsx",
|
||||
"transform-object-assign",
|
||||
"transform-object-rest-spread",
|
||||
"transform-class-properties",
|
||||
"transform-runtime"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
# 🎨 editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
|
@ -0,0 +1,8 @@
|
|||
node_modules/
|
||||
**/*.spec.*
|
||||
**/style/
|
||||
*.html
|
||||
/components/test/*
|
||||
_site/
|
||||
dist/
|
||||
package.json
|
|
@ -0,0 +1,53 @@
|
|||
{
|
||||
"root": true,
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true,
|
||||
"jasmine": true,
|
||||
"jest": true,
|
||||
"es6": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"parser": "babel-eslint"
|
||||
},
|
||||
"extends": ["plugin:vue/recommended", "prettier"],
|
||||
"plugins": ["markdown"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["**/demo/*.md"],
|
||||
"processor": "markdown/markdown",
|
||||
"rules": {
|
||||
"no-console": "off"
|
||||
}
|
||||
}
|
||||
],
|
||||
"rules": {
|
||||
"comma-dangle": [2, "always-multiline"],
|
||||
"no-var": "error",
|
||||
"no-console": [2, { "allow": ["warn", "error"] }],
|
||||
"object-shorthand": 2,
|
||||
"no-unused-vars": [2, { "ignoreRestSiblings": true, "argsIgnorePattern": "^h$" }],
|
||||
"no-undef": 2,
|
||||
"camelcase": "off",
|
||||
"no-extra-boolean-cast": "off",
|
||||
"semi": ["error", "always"],
|
||||
"vue/require-prop-types": "off",
|
||||
"vue/require-default-prop": "off",
|
||||
"vue/no-reserved-keys": "off",
|
||||
"vue/comment-directive": "off",
|
||||
"vue/prop-name-casing": "off",
|
||||
"vue/max-attributes-per-line": [
|
||||
2,
|
||||
{
|
||||
"singleline": 20,
|
||||
"multiline": {
|
||||
"max": 1,
|
||||
"allowFirstLine": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"globals": {
|
||||
"h": true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# TypeScript v1 declaration files
|
||||
typings/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.test
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
|
||||
# Next.js build output
|
||||
.next
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and *not* Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
site/dev.js
|
||||
_site/
|
||||
package-lock.json
|
||||
testDemo/
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"hooks": {
|
||||
"pre-commit": "pretty-quick --staged",
|
||||
"pre-publish": "npm run lint",
|
||||
"commit-msg": "commitlint -x @commitlint/config-conventional -e $GIT_PARAMS"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
**/*.svg
|
||||
package.json
|
||||
lib/
|
||||
es/
|
||||
dist/
|
||||
_site/
|
||||
coverage/
|
||||
CNAME
|
||||
LICENSE
|
||||
yarn.lock
|
||||
netlify.toml
|
||||
yarn-error.log
|
||||
*.sh
|
||||
*.snap
|
||||
.gitignore
|
||||
.npmignore
|
||||
.prettierignore
|
||||
.DS_Store
|
||||
.editorconfig
|
||||
.eslintignore
|
||||
**/*.yml
|
||||
components/style/color/*.less
|
||||
**/assets
|
||||
.gitattributes
|
||||
.stylelintrc
|
||||
.vcmrc
|
||||
.png
|
||||
.npmrc.template
|
||||
.huskyrc
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"printWidth": 100,
|
||||
"proseWrap": "never",
|
||||
"overrides": [
|
||||
{
|
||||
"files": ".prettierrc",
|
||||
"options": {
|
||||
"parser": "json"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"extends": ["stylelint-config-standard", "stylelint-config-prettier"],
|
||||
"rules": {
|
||||
"comment-empty-line-before": null,
|
||||
"declaration-empty-line-before": null,
|
||||
"function-comma-newline-after": null,
|
||||
"function-name-case": null,
|
||||
"function-parentheses-newline-inside": null,
|
||||
"function-max-empty-lines": null,
|
||||
"function-whitespace-after": null,
|
||||
"indentation": null,
|
||||
"number-leading-zero": null,
|
||||
"number-no-trailing-zeros": null,
|
||||
"rule-empty-line-before": null,
|
||||
"selector-combinator-space-after": null,
|
||||
"selector-list-comma-newline-after": null,
|
||||
"selector-pseudo-element-colon-notation": null,
|
||||
"unit-no-unknown": null,
|
||||
"value-list-max-empty-lines": null,
|
||||
"font-family-no-missing-generic-family-keyword": null,
|
||||
"no-descending-specificity": null
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
...require('./mock/user'),
|
||||
};
|
|
@ -0,0 +1,5 @@
|
|||
#!/usr/bin/env bash
|
||||
rm -rf dist
|
||||
mkdir dist
|
||||
./node_modules/.bin/webpack --config webpack.site.config.js
|
||||
cp dist/index.html index.html
|
|
@ -0,0 +1,5 @@
|
|||
module.exports = {
|
||||
dev: {
|
||||
componentName: 'form', // dev components
|
||||
},
|
||||
};
|
|
@ -0,0 +1,213 @@
|
|||
process.env.ENTRY_INDEX = 'dev';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const chokidar = require('chokidar');
|
||||
const importFresh = require('import-fresh');
|
||||
const replace = require('json-templater/string');
|
||||
const webpack = require('webpack');
|
||||
const WebpackDevServer = require('webpack-dev-server');
|
||||
const devWebpack = require('./webpack.dev.conf');
|
||||
|
||||
const configPath = path.join(__dirname, './config.js');
|
||||
|
||||
/**
|
||||
* a-bc-d --> aBcD
|
||||
* @param {string} s
|
||||
*/
|
||||
const camelize = s => s.replace(/-(\w)/g, ($, $1) => $1.toUpperCase());
|
||||
|
||||
/**
|
||||
* radio-group --> radio
|
||||
* @param {string} s
|
||||
*/
|
||||
const getUpper = s => s.replace(/(-[a-z]*)/g, '');
|
||||
|
||||
let { componentName } = require('./config').dev;
|
||||
|
||||
const componentsInPrototype = ['Modal', 'message', 'notification'];
|
||||
|
||||
const MAIN_TEMPLATE = `import 'babel-polyfill';
|
||||
import Vue from 'vue';
|
||||
import Vuex from 'vuex';
|
||||
import VueI18n from 'vue-i18n';
|
||||
import VueRouter from 'vue-router';
|
||||
import VueClipboard from 'vue-clipboard2';
|
||||
import Md from '../components/md';
|
||||
import Api from '../components/api';
|
||||
import demoBox from '../components/demoBox';
|
||||
import demoSort from '../components/demoSort';
|
||||
import demoContainer from '../components/demoContainer';
|
||||
import { message, notification } from 'ant-design-vue';
|
||||
{{importComponents}}
|
||||
{{importStyles}}
|
||||
import 'ant-design-vue/es/message/style';
|
||||
import 'ant-design-vue/es/notification/style';
|
||||
import Test from '../docs/{{name}}/demo/index.vue';
|
||||
import zhCN from '../theme/zh-CN';
|
||||
import enUS from '../theme/en-US';
|
||||
import './index.less';
|
||||
|
||||
Vue.use(Vuex);
|
||||
Vue.use(VueClipboard);
|
||||
Vue.use(VueRouter);
|
||||
Vue.use(VueI18n);
|
||||
Vue.component(Md.name, Md);
|
||||
Vue.component(Api.name, Api);
|
||||
Vue.component('demo-box', demoBox);
|
||||
Vue.component('demo-sort', demoSort);
|
||||
Vue.component('demo-container', demoContainer);
|
||||
|
||||
Vue.prototype.$message = message;
|
||||
Vue.prototype.$notification = notification;
|
||||
Vue.prototype.$info = Modal.info;
|
||||
Vue.prototype.$success = Modal.success;
|
||||
Vue.prototype.$error = Modal.error;
|
||||
Vue.prototype.$warning = Modal.warning;
|
||||
Vue.prototype.$confirm = Modal.confirm;
|
||||
Vue.prototype.$destroyAll = Modal.destroyAll;
|
||||
Vue.prototype.$form = Form;
|
||||
|
||||
Vue.use(Modal);
|
||||
{{install}}
|
||||
|
||||
const i18n = new VueI18n({
|
||||
locale: enUS.locale,
|
||||
messages: {
|
||||
[enUS.locale]: { message: enUS.messages },
|
||||
[zhCN.locale]: { message: zhCN.messages },
|
||||
},
|
||||
});
|
||||
|
||||
const router = new VueRouter({
|
||||
mode: 'history',
|
||||
routes: [{
|
||||
path: '/test',
|
||||
component: () => import('../testDemo/index.vue'),
|
||||
}, {
|
||||
path: '/*', component: Test
|
||||
}],
|
||||
});
|
||||
|
||||
const store = new Vuex.Store({
|
||||
state: {
|
||||
username: 'zeka',
|
||||
},
|
||||
mutations: {
|
||||
update(state, payload) {
|
||||
state.username = payload.username;
|
||||
},
|
||||
},
|
||||
});
|
||||
new Vue({
|
||||
el: '#app',
|
||||
i18n,
|
||||
router,
|
||||
store,
|
||||
});
|
||||
`;
|
||||
|
||||
const OUTPUT_PATH = path.join(__dirname, '../site/dev.js');
|
||||
|
||||
const generateEntry = components =>
|
||||
Object.keys(components)
|
||||
.map(component => `import ${component} from 'ant-design-vue/es/${components[component]}';`)
|
||||
.join('\n');
|
||||
|
||||
const generateStyles = components =>
|
||||
Object.keys(components)
|
||||
.map(component => `import 'ant-design-vue/es/${components[component]}/style';`)
|
||||
.join('\n');
|
||||
|
||||
const generateInstall = components =>
|
||||
Object.keys(components)
|
||||
.map(component => `Vue.use(${component});`)
|
||||
.join('\n');
|
||||
|
||||
const renderTemplate = name => {
|
||||
const components = {
|
||||
Tooltip: 'tooltip', // for DemoBox
|
||||
Icon: 'icon', // Basic
|
||||
Form: 'form',
|
||||
Modal: 'modal',
|
||||
};
|
||||
|
||||
const demoPaths = fs
|
||||
.readdirSync(path.join(__dirname, `../docs/${name}/demo`))
|
||||
.map(p => `../docs/${name}/demo/${p}`);
|
||||
const testPaths = fs
|
||||
.readdirSync(path.join(__dirname, `../testDemo`))
|
||||
.map(p => `../testDemo/${p}`);
|
||||
[...demoPaths, ...testPaths].forEach(demoPath => {
|
||||
const demo = fs.readFileSync(path.join(__dirname, demoPath)).toString();
|
||||
|
||||
const componentsInDemo = demo.match(/a-(\w+(-\w+)*)/g) || [];
|
||||
componentsInDemo.forEach(name => {
|
||||
const dirName = name.replace(/^a-/, '');
|
||||
const componentName = camelize(name).replace(/^a/, '');
|
||||
const upperComponentDir = getUpper(dirName);
|
||||
const upperComponentName = upperComponentDir.replace(/^[a-z]/, $ => $.toUpperCase());
|
||||
|
||||
const componentPath = path.join(__dirname, `../../components/${dirName}`);
|
||||
if (fs.existsSync(componentPath)) {
|
||||
if (componentsInPrototype.includes(componentName)) {
|
||||
return;
|
||||
}
|
||||
components[componentName] = dirName;
|
||||
} else if (fs.existsSync(path.join(__dirname, `../../components/${upperComponentDir}`))) {
|
||||
components[upperComponentName] = upperComponentDir;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const importComponents = generateEntry(components);
|
||||
const importStyles = generateStyles(components);
|
||||
const install = generateInstall(components);
|
||||
const template = replace(MAIN_TEMPLATE, {
|
||||
importComponents,
|
||||
importStyles,
|
||||
install,
|
||||
name,
|
||||
});
|
||||
fs.writeFileSync(OUTPUT_PATH, template);
|
||||
};
|
||||
|
||||
function fsExistsSync(path) {
|
||||
try {
|
||||
fs.accessSync(path, fs.F_OK);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!fsExistsSync(path.join(__dirname, '../testDemo/index.vue'))) {
|
||||
if (!fsExistsSync(path.join(__dirname, '../testDemo'))) {
|
||||
fs.mkdirSync(path.join(__dirname, '../testDemo'));
|
||||
}
|
||||
fs.writeFileSync(path.join(__dirname, '../testDemo/index.vue'), `<template></template>`);
|
||||
}
|
||||
|
||||
let demoWatcher;
|
||||
|
||||
chokidar.watch(configPath, { ignoreInitial: true }).on('change', async () => {
|
||||
({ componentName } = importFresh(configPath).dev);
|
||||
|
||||
demoWatcher && (await demoWatcher.close());
|
||||
|
||||
demoWatcher = chokidar.watch(path.join(__dirname, `../docs/${componentName}/demo`));
|
||||
demoWatcher.on('change', () => {
|
||||
renderTemplate(componentName);
|
||||
});
|
||||
|
||||
renderTemplate(componentName);
|
||||
});
|
||||
|
||||
renderTemplate(componentName);
|
||||
|
||||
const compiler = webpack(devWebpack);
|
||||
|
||||
const configuration = devWebpack.devServer;
|
||||
|
||||
const server = new WebpackDevServer(compiler, configuration);
|
||||
server.listen(configuration.port);
|
|
@ -0,0 +1,45 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = function(modules) {
|
||||
const plugins = [
|
||||
require.resolve('babel-plugin-transform-vue-jsx'),
|
||||
require.resolve('babel-plugin-inline-import-data-uri'),
|
||||
require.resolve('babel-plugin-transform-es3-member-expression-literals'),
|
||||
require.resolve('babel-plugin-transform-es3-property-literals'),
|
||||
require.resolve('babel-plugin-transform-object-assign'),
|
||||
require.resolve('babel-plugin-transform-object-rest-spread'),
|
||||
require.resolve('babel-plugin-transform-class-properties'),
|
||||
];
|
||||
plugins.push([
|
||||
require.resolve('babel-plugin-transform-runtime'),
|
||||
{
|
||||
polyfill: false,
|
||||
},
|
||||
]);
|
||||
return {
|
||||
presets: [
|
||||
[
|
||||
require.resolve('babel-preset-env'),
|
||||
{
|
||||
modules,
|
||||
targets: {
|
||||
browsers: [
|
||||
'last 2 versions',
|
||||
'Firefox ESR',
|
||||
'> 1%',
|
||||
'ie >= 9',
|
||||
'iOS >= 8',
|
||||
'Android >= 4',
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
plugins,
|
||||
env: {
|
||||
test: {
|
||||
plugins: [require.resolve('babel-plugin-istanbul')],
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
|
@ -0,0 +1,166 @@
|
|||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
module.exports = function(env) {
|
||||
const isDev = env === 'development';
|
||||
return {
|
||||
test: /\.less$/,
|
||||
oneOf: [
|
||||
/* config.module.rule('less').oneOf('vue-modules') */
|
||||
{
|
||||
resourceQuery: /module/,
|
||||
use: [
|
||||
isDev
|
||||
? {
|
||||
loader: 'vue-style-loader',
|
||||
options: {
|
||||
sourceMap: isDev,
|
||||
shadowMode: false,
|
||||
},
|
||||
}
|
||||
: MiniCssExtractPlugin.loader,
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
sourceMap: isDev,
|
||||
importLoaders: 2,
|
||||
modules: {
|
||||
localIdentName: '[name]_[local]_[hash:base64:5]',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
sourceMap: isDev,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'less-loader',
|
||||
options: {
|
||||
lessOptions: {
|
||||
sourceMap: isDev,
|
||||
modifyVars: {},
|
||||
javascriptEnabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
/* config.module.rule('less').oneOf('vue') */
|
||||
{
|
||||
resourceQuery: /\?vue/,
|
||||
use: [
|
||||
isDev
|
||||
? {
|
||||
loader: 'vue-style-loader',
|
||||
options: {
|
||||
sourceMap: isDev,
|
||||
shadowMode: false,
|
||||
},
|
||||
}
|
||||
: MiniCssExtractPlugin.loader,
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
sourceMap: isDev,
|
||||
importLoaders: 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
sourceMap: isDev,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'less-loader',
|
||||
options: {
|
||||
lessOptions: {
|
||||
sourceMap: isDev,
|
||||
modifyVars: {},
|
||||
javascriptEnabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
/* config.module.rule('less').oneOf('normal-modules') */
|
||||
{
|
||||
test: /\.module\.\w+$/,
|
||||
use: [
|
||||
isDev
|
||||
? {
|
||||
loader: 'vue-style-loader',
|
||||
options: {
|
||||
sourceMap: isDev,
|
||||
shadowMode: false,
|
||||
},
|
||||
}
|
||||
: MiniCssExtractPlugin.loader,
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
sourceMap: isDev,
|
||||
importLoaders: 2,
|
||||
modules: {
|
||||
localIdentName: '[name]_[local]_[hash:base64:5]',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
sourceMap: isDev,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'less-loader',
|
||||
options: {
|
||||
lessOptions: {
|
||||
sourceMap: isDev,
|
||||
modifyVars: {},
|
||||
javascriptEnabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
/* config.module.rule('less').oneOf('normal') */
|
||||
{
|
||||
use: [
|
||||
isDev
|
||||
? {
|
||||
loader: 'vue-style-loader',
|
||||
options: {
|
||||
sourceMap: isDev,
|
||||
shadowMode: false,
|
||||
},
|
||||
}
|
||||
: MiniCssExtractPlugin.loader,
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
sourceMap: isDev,
|
||||
importLoaders: 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
sourceMap: isDev,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'less-loader',
|
||||
options: {
|
||||
lessOptions: {
|
||||
sourceMap: isDev,
|
||||
modifyVars: {},
|
||||
javascriptEnabled: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
|
@ -0,0 +1,226 @@
|
|||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const Prism = require('prismjs');
|
||||
require('prismjs/components/prism-jsx.min.js');
|
||||
require('prismjs/components/prism-bash.min.js');
|
||||
require('prismjs/components/prism-json.min.js');
|
||||
require('prismjs/components/prism-diff.min.js');
|
||||
require('prismjs/components/prism-less.min.js');
|
||||
const Token = require('markdown-it/lib/token');
|
||||
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
|
||||
const cheerio = require('cheerio');
|
||||
const WebpackBar = require('webpackbar');
|
||||
const VueLoaderPlugin = require('vue-loader/lib/plugin');
|
||||
const getBabelCommonConfig = require('./getBabelCommonConfig');
|
||||
const babelConfig = getBabelCommonConfig(false);
|
||||
|
||||
babelConfig.plugins.push(require.resolve('babel-plugin-syntax-dynamic-import'));
|
||||
|
||||
const fetch = (str, tag, scoped) => {
|
||||
const $ = cheerio.load(str, {
|
||||
decodeEntities: false,
|
||||
xmlMode: true,
|
||||
});
|
||||
if (!tag) {
|
||||
return str;
|
||||
}
|
||||
if (tag === 'style') {
|
||||
return scoped
|
||||
? $(`${tag}[scoped]`).html()
|
||||
: $(`${tag}`)
|
||||
.not(`${tag}[scoped]`)
|
||||
.html();
|
||||
}
|
||||
return $(tag).html();
|
||||
};
|
||||
|
||||
/**
|
||||
* `{{ }}` => `<span>{{</span> <span>}}</span>`
|
||||
* @param {string} str
|
||||
* @return {string}
|
||||
*/
|
||||
const replaceDelimiters = function(str) {
|
||||
return str.replace(/({{|}})/g, '<span>$1</span>');
|
||||
};
|
||||
|
||||
/**
|
||||
* renderHighlight
|
||||
* @param {string} str
|
||||
* @param {string} lang
|
||||
*/
|
||||
|
||||
const renderHighlight = function(str, lang) {
|
||||
if (!(lang && Prism.languages[lang])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
try {
|
||||
return replaceDelimiters(Prism.highlight(str, Prism.languages[lang], lang));
|
||||
} catch (err) {}
|
||||
};
|
||||
|
||||
const md = require('markdown-it')('default', {
|
||||
html: true,
|
||||
breaks: true,
|
||||
highlight: renderHighlight,
|
||||
}).use(require('markdown-it-anchor'), {
|
||||
level: 2,
|
||||
slugify: string =>
|
||||
string
|
||||
.trim()
|
||||
.split(' ')
|
||||
.join('-'),
|
||||
permalink: true,
|
||||
// renderPermalink: (slug, opts, state, permalink) => {},
|
||||
permalinkClass: 'anchor',
|
||||
permalinkSymbol: '#',
|
||||
permalinkBefore: false,
|
||||
});
|
||||
// md.renderer.rules.fence = wrap(md.renderer.rules.fence)
|
||||
const cnReg = new RegExp('<(cn)(?:[^<]|<)+</\\1>', 'g');
|
||||
const usReg = new RegExp('<(us)(?:[^<]|<)+</\\1>', 'g');
|
||||
md.core.ruler.push('update_template', function replace({ tokens }) {
|
||||
let cn = '';
|
||||
let us = '';
|
||||
let template = '';
|
||||
let script = '';
|
||||
let style = '';
|
||||
let scopedStyle = '';
|
||||
let code = '';
|
||||
let sourceCode = '';
|
||||
tokens.forEach(token => {
|
||||
if (token.type === 'html_block') {
|
||||
if (token.content.match(cnReg)) {
|
||||
cn = fetch(token.content, 'cn');
|
||||
token.content = '';
|
||||
}
|
||||
if (token.content.match(usReg)) {
|
||||
us = fetch(token.content, 'us');
|
||||
token.content = '';
|
||||
}
|
||||
}
|
||||
if (token.type === 'fence' && token.info === 'vue' && token.markup === '```') {
|
||||
sourceCode = token.content;
|
||||
code = '```html\n' + token.content + '```';
|
||||
template = fetch(token.content, 'template');
|
||||
script = fetch(token.content, 'script');
|
||||
style = fetch(token.content, 'style');
|
||||
scopedStyle = fetch(token.content, 'style', true);
|
||||
token.content = '';
|
||||
token.type = 'html_block';
|
||||
}
|
||||
});
|
||||
if (template) {
|
||||
let jsfiddle = {
|
||||
us,
|
||||
cn,
|
||||
sourceCode: Buffer.from(sourceCode).toString('base64'),
|
||||
};
|
||||
jsfiddle = md.utils.escapeHtml(JSON.stringify(jsfiddle));
|
||||
const codeHtml = code ? md.render(code.replace(/@/g, '__at__')).replace(/__at__/g, '@') : '';
|
||||
const cnHtml = cn ? md.render(cn) : '';
|
||||
let newContent = `
|
||||
<template>
|
||||
<demo-box :jsfiddle="${jsfiddle}">
|
||||
<template slot="component">${template}</template>
|
||||
<template slot="description">${cnHtml}</template>
|
||||
<template slot="us-description">${us ? md.render(us) : ''}</template>
|
||||
<template slot="code">${Buffer.from(codeHtml).toString('base64')}</template>
|
||||
</demo-box>
|
||||
</template>`;
|
||||
newContent += script
|
||||
? `
|
||||
<script>
|
||||
${script || ''}
|
||||
</script>
|
||||
`
|
||||
: '';
|
||||
newContent += style ? `<style>${style || ''}</style>` : '';
|
||||
newContent += scopedStyle ? `<style scoped>${scopedStyle || ''}</style>` : '';
|
||||
const t = new Token('html_block', '', 0);
|
||||
t.content = newContent;
|
||||
tokens.push(t);
|
||||
}
|
||||
});
|
||||
const vueLoaderOptions = {
|
||||
loaders: {
|
||||
js: [
|
||||
{
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
presets: ['env'],
|
||||
plugins: ['transform-vue-jsx', 'transform-object-rest-spread'],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
module.exports = {
|
||||
mode: 'production',
|
||||
entry: {
|
||||
index: [`./site/${process.env.ENTRY_INDEX || 'index'}.js`],
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.md$/,
|
||||
use: [
|
||||
{
|
||||
loader: 'vue-loader',
|
||||
options: vueLoaderOptions,
|
||||
},
|
||||
{
|
||||
loader: 'vue-antd-md-loader',
|
||||
options: Object.assign(md, {
|
||||
wrapper: 'div',
|
||||
raw: true,
|
||||
}),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader',
|
||||
options: vueLoaderOptions,
|
||||
},
|
||||
{
|
||||
test: /\.(js|jsx)$/,
|
||||
loader: 'babel-loader',
|
||||
exclude: /node_modules/,
|
||||
options: babelConfig,
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpg|gif|svg)$/,
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
name: '[name].[ext]?[hash]',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
resolve:
|
||||
process.env.NODE_ENV === 'development'
|
||||
? {
|
||||
modules: ['node_modules', path.join(__dirname, '../node_modules')],
|
||||
extensions: ['.js', '.jsx', '.vue', '.md'],
|
||||
alias: {
|
||||
vue$: 'vue/dist/vue.esm.js',
|
||||
'ant-design-vue$': path.join(__dirname, '../../components/index.js'),
|
||||
'ant-design-vue/es': path.join(__dirname, '../../components'),
|
||||
'ant-design-vue/lib': path.join(__dirname, '../../components'),
|
||||
},
|
||||
}
|
||||
: {
|
||||
modules: ['node_modules'],
|
||||
extensions: ['.js', '.jsx', '.vue', '.md'],
|
||||
alias: {
|
||||
vue$: 'vue/dist/vue.esm.js',
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
|
||||
new VueLoaderPlugin(),
|
||||
new WebpackBar(),
|
||||
new HardSourceWebpackPlugin(),
|
||||
],
|
||||
};
|
|
@ -0,0 +1,59 @@
|
|||
const path = require('path');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const merge = require('webpack-merge');
|
||||
const baseWebpackConfig = require('./webpack.base.conf');
|
||||
const lessLoaderConfig = require('./lessLoaderConfig');
|
||||
const { createMockMiddleware } = require('umi-mock-middleware');
|
||||
|
||||
module.exports = merge(baseWebpackConfig, {
|
||||
mode: 'development',
|
||||
output: {
|
||||
path: path.resolve(__dirname, '../dist'),
|
||||
publicPath: '/',
|
||||
filename: 'build.js',
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: ['vue-style-loader', 'css-loader'],
|
||||
},
|
||||
lessLoaderConfig('development'),
|
||||
],
|
||||
},
|
||||
devServer: {
|
||||
port: process.env.PORT || 3000,
|
||||
host: '0.0.0.0',
|
||||
historyApiFallback: {
|
||||
rewrites: [{ from: /./, to: '/index.html' }],
|
||||
},
|
||||
disableHostCheck: true,
|
||||
hot: true,
|
||||
open: true,
|
||||
headers: { 'Access-Control-Allow-Origin': '*' },
|
||||
// 解析body,对接真实服务端环境需要注释掉
|
||||
before(app) {
|
||||
// var bodyParser = require("body-parser");
|
||||
// app.use(bodyParser.json());
|
||||
if (process.env.MOCK !== 'none') {
|
||||
app.use(createMockMiddleware());
|
||||
}
|
||||
},
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://localhost:3000',
|
||||
},
|
||||
},
|
||||
},
|
||||
performance: {
|
||||
hints: false,
|
||||
},
|
||||
devtool: '#source-map',
|
||||
plugins: [
|
||||
new HtmlWebpackPlugin({
|
||||
template: 'public/index.html',
|
||||
filename: 'index.html',
|
||||
inject: true,
|
||||
}),
|
||||
],
|
||||
});
|
|
@ -0,0 +1,64 @@
|
|||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const TerserJSPlugin = require('terser-webpack-plugin');
|
||||
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
|
||||
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const merge = require('webpack-merge');
|
||||
const baseWebpackConfig = require('./webpack.base.conf');
|
||||
let lessLoaderConfig = require('./lessLoaderConfig')('production');
|
||||
|
||||
module.exports = merge(baseWebpackConfig, {
|
||||
output: {
|
||||
path: path.resolve(__dirname, '../_site'),
|
||||
publicPath: 'https://alicdn.antdv.com/v1/',
|
||||
filename: '[name].[contenthash:8].js',
|
||||
chunkFilename: '[contenthash:8].async.js',
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
lessLoaderConfig,
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'],
|
||||
},
|
||||
],
|
||||
},
|
||||
optimization: {
|
||||
splitChunks: {
|
||||
cacheGroups: {
|
||||
vendors: {
|
||||
name: `chunk-vendors`,
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
priority: -10,
|
||||
chunks: 'initial',
|
||||
},
|
||||
common: {
|
||||
name: `chunk-common`,
|
||||
minChunks: 2,
|
||||
priority: -20,
|
||||
chunks: 'initial',
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: '"production"',
|
||||
},
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
template: './public/index.html',
|
||||
inject: true,
|
||||
production: true,
|
||||
}),
|
||||
new MiniCssExtractPlugin({
|
||||
filename: '[name].[contenthash:8].css',
|
||||
chunkFilename: '[id].[contenthash:8].css',
|
||||
}),
|
||||
],
|
||||
});
|
|
@ -0,0 +1,124 @@
|
|||
<script>
|
||||
const carbonUrls = {
|
||||
'www.antdv.com': '//cdn.carbonads.com/carbon.js?serve=CK7DL2JW&placement=antdvcom',
|
||||
// 'tangjinzhou.gitee.io':
|
||||
// '//cdn.carbonads.com/carbon.js?serve=CK7DL2JN&placement=tangjinzhougiteeio',
|
||||
// 'ant-design-vue.gitee.io':
|
||||
// '//cdn.carbonads.com/carbon.js?serve=CK7DL2JN&placement=antdesignvuegiteeio',
|
||||
'vue.ant.design': '//cdn.carbonads.com/carbon.js?serve=CK7DL2JW&placement=vueantdesign',
|
||||
};
|
||||
const carbonUrl =
|
||||
carbonUrls[location.host] ||
|
||||
'//cdn.carbonads.com/carbon.js?serve=CK7DL2JW&placement=vueantdesign';
|
||||
export default {
|
||||
props: {
|
||||
isMobile: Boolean,
|
||||
},
|
||||
watch: {
|
||||
$route(e, t) {
|
||||
let adId = '#carbonads';
|
||||
// if(isGitee) {
|
||||
// adId = '#cf';
|
||||
// }
|
||||
if (e.path !== t.path && this.$el.querySelector(adId)) {
|
||||
this.$el.innerHTML = '';
|
||||
this.load();
|
||||
}
|
||||
this.adInterval && clearInterval(this.adInterval);
|
||||
this.adInterval = setInterval(() => {
|
||||
if (!this.$el.querySelector(adId)) {
|
||||
this.$el.innerHTML = '';
|
||||
this.load();
|
||||
}
|
||||
}, 20000);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.load();
|
||||
},
|
||||
methods: {
|
||||
load() {
|
||||
// if(isGitee) {
|
||||
// axios.get('https://api.codefund.app/properties/162/funder.html?template=horizontal')
|
||||
// .then(function (response) {
|
||||
// document.getElementById("codefund-ads").innerHTML = response.data;
|
||||
// });
|
||||
// } else
|
||||
if (carbonUrl) {
|
||||
const e = document.createElement('script');
|
||||
e.id = '_carbonads_js';
|
||||
e.src = carbonUrl;
|
||||
this.$el.appendChild(e);
|
||||
}
|
||||
},
|
||||
},
|
||||
render() {
|
||||
return <div id="carbon-ads" class={this.isMobile ? 'carbon-mobile' : ''} />;
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="less">
|
||||
#carbon-ads {
|
||||
width: 280px;
|
||||
float: right;
|
||||
margin-top: 75px;
|
||||
position: relative;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
z-index: 9;
|
||||
background-color: #fff;
|
||||
border-radius: 3px;
|
||||
font-size: 13px;
|
||||
background: #f5f5f5;
|
||||
font-family: 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif;
|
||||
}
|
||||
#carbonads {
|
||||
overflow: hidden;
|
||||
}
|
||||
#carbon-ads a {
|
||||
display: inline-block;
|
||||
color: #7f8c8d;
|
||||
font-weight: normal;
|
||||
}
|
||||
#carbon-ads span {
|
||||
color: #7f8c8d;
|
||||
}
|
||||
#carbon-ads img {
|
||||
float: left;
|
||||
padding-right: 10px;
|
||||
}
|
||||
#carbon-ads .carbon-img,
|
||||
#carbon-ads .carbon-text {
|
||||
display: block;
|
||||
font-weight: normal;
|
||||
color: #34495e;
|
||||
}
|
||||
#carbon-ads .carbon-text {
|
||||
padding-top: 6px;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 4;
|
||||
overflow: hidden;
|
||||
}
|
||||
#carbon-ads .carbon-poweredby {
|
||||
color: #aaa;
|
||||
font-weight: normal;
|
||||
line-height: 1.2;
|
||||
margin-top: 6px;
|
||||
}
|
||||
#carbon-ads.carbon-mobile {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 0;
|
||||
margin-bottom: 15px;
|
||||
margin-top: 5px;
|
||||
.carbon-img {
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,36 @@
|
|||
<script>
|
||||
export default {
|
||||
mounted() {
|
||||
this.load();
|
||||
},
|
||||
methods: {
|
||||
load() {
|
||||
if (this.scriptDom) {
|
||||
this.$el.removeChild(this.scriptDom);
|
||||
}
|
||||
this.$refs.ins.innerHTML = '';
|
||||
const e = document.createElement('script');
|
||||
e.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
|
||||
e.async = true;
|
||||
this.$el.appendChild(e);
|
||||
this.scriptDom = e;
|
||||
(window.adsbygoogle = window.adsbygoogle || []).push({});
|
||||
},
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<div class="google-ads" id="API">
|
||||
<ins
|
||||
ref="ins"
|
||||
class="adsbygoogle"
|
||||
style="display:block"
|
||||
data-ad-client="ca-pub-4801326429087140"
|
||||
data-ad-slot="7647023136"
|
||||
data-ad-format="auto"
|
||||
data-full-width-responsive="true"
|
||||
></ins>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,35 @@
|
|||
<script>
|
||||
export default {
|
||||
mounted() {
|
||||
this.load();
|
||||
},
|
||||
methods: {
|
||||
load() {
|
||||
if (this.scriptDom) {
|
||||
this.$el.removeChild(this.scriptDom);
|
||||
}
|
||||
this.$refs.ins.innerHTML = '';
|
||||
const e = document.createElement('script');
|
||||
e.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
|
||||
e.async = true;
|
||||
this.$el.appendChild(e);
|
||||
this.scriptDom = e;
|
||||
(window.adsbygoogle = window.adsbygoogle || []).push({});
|
||||
},
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<div class="google-ads" id="api">
|
||||
<ins
|
||||
ref="ins"
|
||||
style="display:block"
|
||||
data-ad-client="ca-pub-4801326429087140"
|
||||
data-ad-slot="3952358732"
|
||||
data-ad-format="auto"
|
||||
data-full-width-responsive="true"
|
||||
></ins>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,35 @@
|
|||
<script>
|
||||
export default {
|
||||
mounted() {
|
||||
this.load();
|
||||
},
|
||||
methods: {
|
||||
load() {
|
||||
if (this.scriptDom) {
|
||||
this.$el.removeChild(this.scriptDom);
|
||||
}
|
||||
this.$refs.ins.innerHTML = '';
|
||||
const e = document.createElement('script');
|
||||
e.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
|
||||
e.async = true;
|
||||
this.$el.appendChild(e);
|
||||
this.scriptDom = e;
|
||||
(window.adsbygoogle = window.adsbygoogle || []).push({});
|
||||
},
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<div class="google-ads">
|
||||
<ins
|
||||
ref="ins"
|
||||
style="display:block"
|
||||
data-ad-client="ca-pub-4801326429087140"
|
||||
data-ad-slot="9507921838"
|
||||
data-ad-format="auto"
|
||||
data-full-width-responsive="true"
|
||||
></ins>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,34 @@
|
|||
<script>
|
||||
export default {
|
||||
mounted() {
|
||||
this.load();
|
||||
},
|
||||
methods: {
|
||||
load() {
|
||||
if (this.scriptDom) {
|
||||
this.$el.removeChild(this.scriptDom);
|
||||
}
|
||||
this.$refs.ins.innerHTML = '';
|
||||
const e = document.createElement('script');
|
||||
e.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
|
||||
e.async = true;
|
||||
this.$el.appendChild(e);
|
||||
this.scriptDom = e;
|
||||
(window.adsbygoogle = window.adsbygoogle || []).push({});
|
||||
},
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<div style="width: 300px;float: right;margin-top: 75px;position: relative;right: 0;bottom: 0;padding: 0;z-index: 9;">
|
||||
<ins
|
||||
ref="ins"
|
||||
class="adsbygoogle"
|
||||
style="display:inline-block;width:300px;height:100px"
|
||||
data-ad-client="ca-pub-4801326429087140"
|
||||
data-ad-slot="2774992529"
|
||||
></ins>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,35 @@
|
|||
<script>
|
||||
export default {
|
||||
mounted() {
|
||||
this.load();
|
||||
},
|
||||
methods: {
|
||||
load() {
|
||||
if (this.scriptDom) {
|
||||
this.$el.removeChild(this.scriptDom);
|
||||
}
|
||||
this.$refs.ins.innerHTML = '';
|
||||
const e = document.createElement('script');
|
||||
e.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
|
||||
e.async = true;
|
||||
this.$el.appendChild(e);
|
||||
this.scriptDom = e;
|
||||
(window.adsbygoogle = window.adsbygoogle || []).push({});
|
||||
},
|
||||
},
|
||||
render() {
|
||||
return (
|
||||
<div class="google-ads">
|
||||
<ins
|
||||
ref="ins"
|
||||
style="display:block"
|
||||
class="adsbygoogle"
|
||||
data-ad-client="ca-pub-4801326429087140"
|
||||
data-ad-slot="2425414214"
|
||||
data-ad-format="auto"
|
||||
></ins>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,28 @@
|
|||
<template>
|
||||
<div class="markdown api-container">
|
||||
<google-ads v-if="showAd" />
|
||||
<slot v-if="isZhCN" name="cn" />
|
||||
<slot v-else />
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { isZhCN } from '../utils/util';
|
||||
import GoogleAds from './GoogleAds';
|
||||
|
||||
const showAd = location.host.indexOf('antdv.com') > -1;
|
||||
export default {
|
||||
name: 'Api',
|
||||
components: {
|
||||
GoogleAds,
|
||||
},
|
||||
inject: {
|
||||
demoContext: { default: {} },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showAd,
|
||||
isZhCN: isZhCN(this.demoContext.name),
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,230 @@
|
|||
<template>
|
||||
<section :id="id" :class="['code-box', codeExpand ? 'expand' : '']">
|
||||
<section class="code-box-demo">
|
||||
<template v-if="iframeDemo[iframeDemoKey]">
|
||||
<div class="browser-mockup with-url">
|
||||
<iframe :src="iframeDemo[iframeDemoKey]" height="360" />
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<slot name="component" />
|
||||
</template>
|
||||
</section>
|
||||
<section class="code-box-meta markdown">
|
||||
<slot v-if="isZhCN" name="description" />
|
||||
<slot v-else name="us-description" />
|
||||
<div class="code-box-actions">
|
||||
<a-tooltip
|
||||
:title="copied ? 'Copied!' : 'Copy code'"
|
||||
:visible="copyTooltipVisible"
|
||||
@visibleChange="onCopyTooltipVisibleChange"
|
||||
>
|
||||
<a-icon
|
||||
v-clipboard:copy="sourceCode"
|
||||
v-clipboard:success="handleCodeCopied"
|
||||
:type="copied && copyTooltipVisible ? 'check' : 'copy'"
|
||||
class="code-box-code-copy"
|
||||
/>
|
||||
</a-tooltip>
|
||||
<a-tooltip :title="codeExpand ? 'Hide Code' : 'Show Code'">
|
||||
<span class="code-expand-icon">
|
||||
<img
|
||||
width="16"
|
||||
alt="expand code"
|
||||
src="https://gw.alipayobjects.com/zos/rmsportal/wSAkBuJFbdxsosKKpqyq.svg"
|
||||
:class="codeExpand ? 'code-expand-icon-hide' : 'code-expand-icon-show'"
|
||||
@click="handleCodeExpand"
|
||||
/>
|
||||
<img
|
||||
width="16"
|
||||
alt="expand code"
|
||||
src="https://gw.alipayobjects.com/zos/rmsportal/OpROPHYqWmrMDBFMZtKF.svg"
|
||||
:class="codeExpand ? 'code-expand-icon-show' : 'code-expand-icon-hide'"
|
||||
@click="handleCodeExpand"
|
||||
/>
|
||||
</span>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</section>
|
||||
<transition appear :css="false" @enter="enter" @leave="leave">
|
||||
<section
|
||||
v-show="codeExpand"
|
||||
class="highlight-wrapper"
|
||||
style="position: relative;"
|
||||
v-html="getCode()"
|
||||
/>
|
||||
</transition>
|
||||
</section>
|
||||
</template>
|
||||
<script>
|
||||
import animate from 'ant-design-vue/es/_util/openAnimation';
|
||||
import BaseMixin from 'ant-design-vue/es/_util/BaseMixin';
|
||||
import { isZhCN } from '../utils/util';
|
||||
import { dev } from '../build/config';
|
||||
export default {
|
||||
name: 'DemoBox',
|
||||
mixins: [BaseMixin],
|
||||
inject: {
|
||||
iframeDemo: { default: {} },
|
||||
demoContext: { default: {} },
|
||||
},
|
||||
props: {
|
||||
jsfiddle: Object,
|
||||
isIframe: Boolean,
|
||||
},
|
||||
data() {
|
||||
window.test = this;
|
||||
const { name = '' } = this.demoContext;
|
||||
const { us, cn, sourceCode } = this.jsfiddle;
|
||||
const usTitle = (us.split('#### ')[1] || '').split('\n')[0] || '';
|
||||
const cnTitle = (cn.split('#### ')[1] || '').split('\n')[0] || '';
|
||||
if (process.env.NODE_ENV !== 'production' && usTitle === '') {
|
||||
throw new Error(`not have usTitle`);
|
||||
}
|
||||
const iframeDemoKey = usTitle
|
||||
.split(' ')
|
||||
.join('-')
|
||||
.toLowerCase();
|
||||
const id = [
|
||||
'components',
|
||||
name.replace(/-cn\/?$/, '') || dev.componentName,
|
||||
'demo',
|
||||
...usTitle.split(' '),
|
||||
]
|
||||
.join('-')
|
||||
.toLowerCase();
|
||||
|
||||
if (this.demoContext.store) {
|
||||
const { currentSubMenu } = this.demoContext.store.getState();
|
||||
this.demoContext.store.setState({
|
||||
currentSubMenu: [...currentSubMenu, { cnTitle, usTitle, id }],
|
||||
});
|
||||
}
|
||||
return {
|
||||
codeExpand: false,
|
||||
isZhCN: isZhCN(name),
|
||||
copied: false,
|
||||
copyTooltipVisible: false,
|
||||
sourceCode: decodeURIComponent(escape(window.atob(sourceCode))),
|
||||
id,
|
||||
iframeDemoKey,
|
||||
isDemo: true,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
getCode() {
|
||||
const { $slots } = this;
|
||||
return decodeURIComponent(
|
||||
escape(window.atob(($slots.code && $slots.code[0] && $slots.code[0].text) || '')),
|
||||
);
|
||||
},
|
||||
handleCodeExpand() {
|
||||
this.codeExpand = !this.codeExpand;
|
||||
},
|
||||
enter: animate.enter,
|
||||
leave: animate.leave,
|
||||
handleCodeCopied() {
|
||||
this.setState({ copied: true });
|
||||
},
|
||||
|
||||
onCopyTooltipVisibleChange(visible) {
|
||||
if (visible) {
|
||||
this.setState({
|
||||
copyTooltipVisible: visible,
|
||||
copied: false,
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.setState({
|
||||
copyTooltipVisible: visible,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.box-demo {
|
||||
padding: 0;
|
||||
border: 1px solid #e9e9e9;
|
||||
border-radius: 4px;
|
||||
box-shadow: none;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.box-demo-show {
|
||||
padding: 20px 25px 30px;
|
||||
border-bottom: 1px solid #e9e9e9;
|
||||
}
|
||||
.box-demo-description {
|
||||
position: relative;
|
||||
padding: 17px 16px 15px 20px;
|
||||
border-radius: 0 0 6px 6px;
|
||||
-webkit-transition: background-color 0.4s ease;
|
||||
transition: background-color 0.4s ease;
|
||||
width: 100%;
|
||||
font-size: 12px;
|
||||
&.bordered {
|
||||
border-bottom: 1px dashed #e9e9e9;
|
||||
}
|
||||
h3,
|
||||
h4 {
|
||||
position: absolute;
|
||||
top: -14px;
|
||||
padding: 1px 8px;
|
||||
margin-left: -8px;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
color: #777;
|
||||
border-radius: 4px;
|
||||
border-top-left-radius: 0;
|
||||
background: #fff;
|
||||
-webkit-transition: background-color 0.4s ease;
|
||||
transition: background-color 0.4s ease;
|
||||
.header-anchor {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
li {
|
||||
line-height: 21px;
|
||||
}
|
||||
}
|
||||
.box-demo-code {
|
||||
-webkit-transition: height 0.2s ease-in-out;
|
||||
transition: height 0.2s ease-in-out;
|
||||
overflow: auto;
|
||||
border-top: 1px dashed #e9e9e9;
|
||||
pre {
|
||||
margin: 0;
|
||||
}
|
||||
code {
|
||||
margin: 0;
|
||||
background: #f7f7f7;
|
||||
padding: 0.2em 0.4em;
|
||||
border-radius: 3px;
|
||||
font-size: 0.9em;
|
||||
border: 1px solid #eee;
|
||||
}
|
||||
}
|
||||
.btn-toggle {
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
bottom: 17px;
|
||||
cursor: pointer;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
font-size: 18px;
|
||||
line-height: 18px;
|
||||
color: #999;
|
||||
i {
|
||||
-webkit-transition: all 0.3s;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
&.open {
|
||||
i {
|
||||
-webkit-transform: rotate(-180deg);
|
||||
-ms-transform: rotate(-180deg);
|
||||
transform: rotate(-180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,82 @@
|
|||
<template>
|
||||
<div>
|
||||
<demo-box :jsfiddle="jsfiddle">
|
||||
<template slot="component">
|
||||
<slot />
|
||||
</template>
|
||||
<template slot="description">
|
||||
<div class="demo-description" v-html="cnHtml" />
|
||||
</template>
|
||||
<template slot="us-description">
|
||||
<div class="demo-description" v-html="usHtml" />
|
||||
</template>
|
||||
<template slot="code">
|
||||
{{ codeStr }}
|
||||
</template>
|
||||
</demo-box>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import marked from 'marked';
|
||||
import Prism from 'prismjs';
|
||||
import 'prismjs/components/prism-jsx.min.js';
|
||||
import 'prismjs/components/prism-bash.min.js';
|
||||
const replaceDelimiters = function(str) {
|
||||
return str.replace(/({{|}})/g, '<span>$1</span>');
|
||||
};
|
||||
const renderHighlight = function(str, lang) {
|
||||
if (!(lang && Prism.languages[lang])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
try {
|
||||
return replaceDelimiters(Prism.highlight(str, Prism.languages[lang], lang));
|
||||
} catch (err) {}
|
||||
};
|
||||
const renderer = new marked.Renderer();
|
||||
renderer.heading = function(text, level) {
|
||||
return (
|
||||
'<h' + level + ' id="' + text.replace(/[^\w]+/g, '-') + '">' + text + '</h' + level + '>\n'
|
||||
);
|
||||
};
|
||||
marked.setOptions({
|
||||
renderer,
|
||||
gfm: true,
|
||||
tables: true,
|
||||
breaks: true,
|
||||
pedantic: true,
|
||||
sanitize: true,
|
||||
smartLists: true,
|
||||
smartypants: true,
|
||||
html: true,
|
||||
highlight: renderHighlight,
|
||||
});
|
||||
const cnReg = /<cn>([\S\s\t]*?)<\/cn>/;
|
||||
const usReg = /<us>([\S\s\t]*?)<\/us>/;
|
||||
export default {
|
||||
name: 'DemoContainer',
|
||||
props: ['code'],
|
||||
data() {
|
||||
const cn = this.code.match(cnReg) || [];
|
||||
const us = this.code.match(usReg) || [];
|
||||
const cnHtml = marked(cn[1].trim());
|
||||
const usHtml = marked(us[1].trim());
|
||||
const sourceCode = this.code
|
||||
.replace(cn[0], '')
|
||||
.replace(us[0], '')
|
||||
.trim();
|
||||
const codeHtml = marked('```html\n' + sourceCode + '```');
|
||||
return {
|
||||
codeStr: window.btoa(unescape(encodeURIComponent(codeHtml))),
|
||||
cnHtml,
|
||||
usHtml,
|
||||
jsfiddle: {
|
||||
sourceCode: window.btoa(unescape(encodeURIComponent(sourceCode))),
|
||||
cn: cn[1].trim(),
|
||||
us: us[1].trim(),
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,49 @@
|
|||
import { Col, Row } from '../../components/grid';
|
||||
import '../../components/grid/style';
|
||||
function isEmptyElement(c) {
|
||||
return !(c.tag || (c.text && c.text.trim() !== ''));
|
||||
}
|
||||
|
||||
function filterEmpty(children = []) {
|
||||
return children.filter(c => !isEmptyElement(c));
|
||||
}
|
||||
export default {
|
||||
props: {
|
||||
cols: {
|
||||
type: [Number, String],
|
||||
default: 2,
|
||||
},
|
||||
},
|
||||
inject: {
|
||||
demoContext: { default: {} },
|
||||
},
|
||||
render() {
|
||||
const { cols, $slots } = this;
|
||||
const isSingleCol = cols === 1;
|
||||
const leftChildren = [];
|
||||
const rightChildren = [];
|
||||
const children = filterEmpty($slots.default);
|
||||
children.forEach((demo, index) => {
|
||||
if (index % 2 === 0 || isSingleCol) {
|
||||
leftChildren.push(demo);
|
||||
} else {
|
||||
rightChildren.push(demo);
|
||||
}
|
||||
});
|
||||
return (
|
||||
<Row gutter={16}>
|
||||
<Col
|
||||
span={isSingleCol ? 24 : 12}
|
||||
class={isSingleCol ? 'code-boxes-col-1-1' : 'code-boxes-col-2-1'}
|
||||
>
|
||||
{leftChildren}
|
||||
</Col>
|
||||
{isSingleCol ? null : (
|
||||
<Col class="code-boxes-col-2-1" span={12}>
|
||||
{rightChildren}
|
||||
</Col>
|
||||
)}
|
||||
</Row>
|
||||
);
|
||||
},
|
||||
};
|
|
@ -0,0 +1,136 @@
|
|||
<script>
|
||||
export default {
|
||||
props: {
|
||||
isCN: Boolean,
|
||||
},
|
||||
render() {
|
||||
const isCN = this.isCN;
|
||||
return (
|
||||
<footer id="footer">
|
||||
<div class="footer-wrap">
|
||||
<a-row>
|
||||
<a-col md={6} sm={24} xs={24}>
|
||||
<div class="footer-center">
|
||||
<h2>Ant Design</h2>
|
||||
<div>
|
||||
<a href="https://github.com/vueComponent/ant-design-vue" target="_blank ">
|
||||
<span>GitHub</span>
|
||||
</a>
|
||||
<span></span>
|
||||
<span>
|
||||
<i class="anticon anticon-github"></i>
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://ant.design/docs/react/introduce-cn" target="_blank">
|
||||
Ant Design
|
||||
</a>
|
||||
<span> - </span>
|
||||
<span>React</span>
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://github.com/NG-ZORRO/ng-zorro-antd" target="_blank">
|
||||
Ant Design
|
||||
</a>
|
||||
<span> - </span>
|
||||
<span>Angular</span>
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://github.com/websemantics/awesome-ant-design" target="_blank ">
|
||||
<span>Awesome Ant Design</span>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="http://library.ant.design/" rel="noopener noreferrer" target="_blank">
|
||||
AntD Library
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col md={6} sm={24} xs={24}>
|
||||
<div class="footer-center">
|
||||
<h2>{isCN ? '社区' : 'Community'}</h2>
|
||||
{isCN ? (
|
||||
<div>
|
||||
<a href="https://zhuanlan.zhihu.com/ant-design-vue" target="_blank">
|
||||
<span>知乎专栏</span>
|
||||
</a>
|
||||
</div>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
<div>
|
||||
<a href="https://github.com/vueComponent/ant-design-vue/releases" target="_blank">
|
||||
<span>{isCN ? '更新记录' : 'Change Log'}</span>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
href={`https://vuecomponent.github.io/issue-helper/${isCN ? '?lang=zh' : ''}`}
|
||||
>
|
||||
<span>{isCN ? '报告 Bug' : 'Bug Report'}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col md={6} sm={24} xs={24}>
|
||||
<div class="footer-center">
|
||||
<h2>{isCN ? '友情链接' : 'Links'}</h2>
|
||||
<div>
|
||||
<a href="https://cn.vuejs.org/" target="_blank">
|
||||
Vue
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://cli.vuejs.org/" target="_blank">
|
||||
Vue CLI
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="http://www.jeecg.com/" rel="noopener noreferrer" target="_blank">
|
||||
Jeecg Boot
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col md={6} sm={24} xs={24}>
|
||||
<div class="footer-center">
|
||||
<h2>
|
||||
<img
|
||||
alt=""
|
||||
class="title-icon"
|
||||
src="https://gw.alipayobjects.com/zos/rmsportal/nBVXkrFdWHxbZlmMbsaH.svg"
|
||||
/>
|
||||
<span>{isCN ? '更多产品' : 'More Products'}</span>
|
||||
</h2>
|
||||
<div>
|
||||
<a href="https://antv.alipay.com/" rel="noopener noreferrer" target="_blank">
|
||||
AntV
|
||||
</a>
|
||||
<span> - </span>
|
||||
<span>{isCN ? '数据可视化' : 'Data Visualization'}</span>
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://eggjs.org/" rel="noopener noreferrer" target="_blank">
|
||||
Egg
|
||||
</a>
|
||||
<span> - </span>
|
||||
<span>{isCN ? '企业级 Node 开发框架' : 'Enterprise Node Framework'}</span>
|
||||
</div>
|
||||
</div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
<div style="padding: 10px 144px;">
|
||||
备案号:
|
||||
<a href="http://www.beian.miit.gov.cn/" target="_blank">
|
||||
浙ICP备19034671号
|
||||
</a>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,41 @@
|
|||
<template>
|
||||
<div v-show="visible" id="geektime">
|
||||
<a
|
||||
href="https://time.geekbang.org/course/intro/100024601?code=KHKYcoBU6vZa8nMglg7AWfDxxi3BWrz9INAzAY3umPk%3D"
|
||||
target="_blank"
|
||||
>
|
||||
<img width="150" alt="Vue 实战教程" src="https://qn.antdv.com/geektime-vue.jpeg" />
|
||||
</a>
|
||||
<div class="close" @click="visible = false">
|
||||
<a-icon type="close" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ['isMobile'],
|
||||
data() {
|
||||
return {
|
||||
visible: true,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
#geektime {
|
||||
position: fixed;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
.close {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
top: -8px;
|
||||
right: -8px;
|
||||
font-size: 16px;
|
||||
padding: 15px;
|
||||
color: #6e3041;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,60 @@
|
|||
<template>
|
||||
<div
|
||||
v-if="isEffective(effectiveTime)"
|
||||
id="geektime-ads"
|
||||
:class="isMobile ? 'geektime-ads-mobile' : ''"
|
||||
>
|
||||
<a
|
||||
href="https://time.geekbang.org/column/intro/154?utm_term=zeusGZFFE&utm_source=app&utm_medium=tangjinzhou"
|
||||
target="_blank"
|
||||
>
|
||||
<img height="100" alt="重学前端" src="https://qn.antdv.com/chongxueqianduan.jpg" />
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import moment from 'moment';
|
||||
export default {
|
||||
props: ['isMobile'],
|
||||
data() {
|
||||
return {
|
||||
visible: true,
|
||||
effectiveTime: {
|
||||
start: '2019-08-05 17:00:00',
|
||||
end: '2019-09-05 17:00:00',
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
isEffective({ start, end }) {
|
||||
return moment().isBetween(start, end);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
#geektime-ads {
|
||||
width: 266px;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0px;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
z-index: 9;
|
||||
background-color: #fff;
|
||||
border-radius: 3px;
|
||||
font-size: 13px;
|
||||
background: #f5f5f5;
|
||||
font-family: 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif;
|
||||
}
|
||||
#geektime-ads.geektime-ads-mobile {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 0;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,322 @@
|
|||
<script>
|
||||
import { isZhCN } from '../utils/util';
|
||||
import docsearch from 'docsearch.js';
|
||||
import packageInfo from '../../package.json';
|
||||
import logo from '../public/logo.svg';
|
||||
import antDesignVue from '../public/ant-design-vue.svg';
|
||||
|
||||
export default {
|
||||
inject: {
|
||||
demoContext: { default: {} },
|
||||
},
|
||||
props: {
|
||||
name: String,
|
||||
searchData: Array,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visibleAdblockBanner: !!this.demoContext.blocked,
|
||||
value: null,
|
||||
showTopBanner: !localStorage.getItem('notification-key-2.0'),
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
'demoContex.blocked': function blocked(val) {
|
||||
this.visibleAdblockBanner = !!val;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.initDocSearch(this.$i18n.locale);
|
||||
},
|
||||
methods: {
|
||||
handleClose(key) {
|
||||
localStorage.removeItem(`notification-key-${key}`);
|
||||
localStorage.setItem(`notification-key-${key}`, true);
|
||||
this.showTopBanner = false;
|
||||
},
|
||||
initDocSearch(locale) {
|
||||
docsearch({
|
||||
apiKey: '92003c1d1d07beef165b08446f4224a3',
|
||||
indexName: 'antdv',
|
||||
inputSelector: '#search-box input',
|
||||
algoliaOptions: { facetFilters: [isZhCN(locale) ? 'cn' : 'en'] },
|
||||
transformData(hits) {
|
||||
hits.forEach(hit => {
|
||||
hit.url = hit.url.replace('www.antdv.com', window.location.host);
|
||||
hit.url = hit.url.replace('https:', window.location.protocol);
|
||||
});
|
||||
return hits;
|
||||
},
|
||||
debug: false, // Set debug to true if you want to inspect the dropdown
|
||||
});
|
||||
},
|
||||
handleClick() {
|
||||
const name = this.name;
|
||||
const path = this.$route.path;
|
||||
const newName = isZhCN(name) ? name.replace(/-cn\/?$/, '') : `${name}-cn`;
|
||||
this.$router.push({
|
||||
path: path.replace(name, newName),
|
||||
});
|
||||
this.$i18n.locale = isZhCN(name) ? 'en-US' : 'zh-CN';
|
||||
},
|
||||
onSelect(val) {
|
||||
this.$router.push(val);
|
||||
this.value = val;
|
||||
},
|
||||
closeTopBanner() {},
|
||||
},
|
||||
render() {
|
||||
const name = this.name;
|
||||
const visibleAdblockBanner = false; // this.visibleAdblockBanner;
|
||||
const isCN = isZhCN(name);
|
||||
const path = this.$route.path;
|
||||
const selectedKeys = path === '/jobs/list-cn' ? ['jobs'] : ['components'];
|
||||
return (
|
||||
<header id="header">
|
||||
{visibleAdblockBanner && (
|
||||
<div class="adblock-banner">
|
||||
{isZhCN
|
||||
? '我们检测到你可能使用了 AdBlock 或 Adblock Plus,它会影响到正常功能的使用(如复制、展开代码等)。'
|
||||
: 'We have detected that you may use AdBlock or Adblock Plus, which will affect the use of normal functions (such as copying, expanding code, etc.)'}
|
||||
<br />
|
||||
{isZhCN
|
||||
? '你可以将 Ant Design Vue 加入白名单,以便我们更好地提供服务。'
|
||||
: 'You can add Ant Design Vue to the whitelist so that we can provide better services.'}
|
||||
|
||||
<CloseOutlined class="close-icon" onClick={() => (this.visibleAdblockBanner = false)} />
|
||||
</div>
|
||||
)}
|
||||
{isCN && this.showTopBanner && (
|
||||
<div class="global-notification">
|
||||
<span>
|
||||
<a href="https://2x.antdv.com/" target="_blank">
|
||||
2.0 正式版
|
||||
</a>
|
||||
已发布,更快、更小、更易用
|
||||
</span>
|
||||
<br />
|
||||
<span style="padding: 5px 0; display: inline-block;">
|
||||
支持 Vue 3.0,全新 Composition API 文档,TS、JS 双示例
|
||||
</span>
|
||||
<br />
|
||||
<span>
|
||||
<a href="https://store.antdv.com/pro/" target="_blank">
|
||||
Vue3 Admin Pro
|
||||
</a>
|
||||
同步更新,支持多种布局、多标签页、暗黑主题等
|
||||
</span>
|
||||
<a-icon
|
||||
type="close"
|
||||
style="position: absolute;top: 13px;right: 15px;"
|
||||
onClick={() => this.handleClose('2.0')}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{!isCN && this.showTopBanner && (
|
||||
<div class="global-notification">
|
||||
<span>
|
||||
<a href="https://2x.antdv.com/" target="_blank">
|
||||
2.0 release
|
||||
</a>
|
||||
Faster, Smaller, Easier
|
||||
</span>
|
||||
<br />
|
||||
<span style="padding: 5px 0; display: inline-block;">
|
||||
Support Vue 3、New Composition API document、 TS, JS dual examples
|
||||
</span>
|
||||
<br />
|
||||
<span>
|
||||
<a href="https://store.antdv.com/pro/?lang=en" target="_blank">
|
||||
Vue3 Admin Pro
|
||||
</a>
|
||||
is updated synchronously, supports multiple layouts, dark themes, etc.
|
||||
</span>
|
||||
<a-icon
|
||||
type="close"
|
||||
style="position: absolute;top: 8px;right: 15px;"
|
||||
onClick={() => this.handleClose('2.0')}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<a-row>
|
||||
<a-col class="header-left" xxl={4} xl={5} lg={5} md={6} sm={24} xs={24}>
|
||||
<router-link to={{ path: '/' }} id="logo">
|
||||
<img alt="logo" height="32" src={logo} />
|
||||
<img alt="logo" height="16" src={antDesignVue} />
|
||||
</router-link>
|
||||
<a-button
|
||||
ghost
|
||||
size="small"
|
||||
onClick={this.handleClick}
|
||||
class="header-lang-button"
|
||||
key="lang-button"
|
||||
>
|
||||
{isCN ? 'English' : '中文'}
|
||||
</a-button>
|
||||
</a-col>
|
||||
<a-col xxl={20} xl={19} lg={19} md={18} sm={0} xs={0}>
|
||||
<div id="search-box">
|
||||
<a-icon type="search" />
|
||||
<a-input
|
||||
placeholder={isCN ? '搜索组件...' : 'input search text'}
|
||||
style="width: 200px"
|
||||
/>
|
||||
</div>
|
||||
<span id="github-btn" class="github-btn">
|
||||
<a class="gh-btn" href="//github.com/vueComponent/ant-design-vue/" target="_blank">
|
||||
<span class="gh-ico" aria-hidden="true"></span>
|
||||
<span class="gh-text">Star</span>
|
||||
</a>
|
||||
</span>
|
||||
<a-button
|
||||
ghost
|
||||
size="small"
|
||||
onClick={this.handleClick}
|
||||
class="header-lang-button"
|
||||
key="lang-button"
|
||||
>
|
||||
{isCN ? 'English' : '中文'}
|
||||
</a-button>
|
||||
<a-select size="small" defaultValue={packageInfo.version} class="version">
|
||||
<a-select-option value={packageInfo.version}>{packageInfo.version}</a-select-option>
|
||||
<a-select-option value="2.x" onClick={() => (location.href = 'https://2x.antdv.com')}>
|
||||
2.x
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
<a-menu selectedKeys={selectedKeys} mode="horizontal" class="menu-site" id="nav">
|
||||
<a-menu-item key="components">
|
||||
<router-link to="/docs/vue/introduce">{isCN ? '组件' : 'Components'}</router-link>
|
||||
</a-menu-item>
|
||||
{isCN ? (
|
||||
<a-menu-item key="store">
|
||||
<a
|
||||
href="https://store.antdv.com/pro/"
|
||||
target="_blank"
|
||||
style="position: relative;"
|
||||
>
|
||||
商店 <a-badge color="red" style="position: absolute;top: -10px;right: -10px;" />
|
||||
</a>
|
||||
</a-menu-item>
|
||||
) : (
|
||||
<a-menu-item key="store">
|
||||
<a
|
||||
href="https://store.antdv.com/pro/?lang=en"
|
||||
target="_blank"
|
||||
style="position: relative;"
|
||||
>
|
||||
Store{' '}
|
||||
<a-badge color="red" style="position: absolute;top: -10px;right: -10px;" />
|
||||
</a>
|
||||
</a-menu-item>
|
||||
)}
|
||||
{isCN ? (
|
||||
<a-menu-item key="geektime">
|
||||
<a
|
||||
href="https://time.geekbang.org/course/intro/100024601?code=KHKYcoBU6vZa8nMglg7AWfDxxi3BWrz9INAzAY3umPk%3D"
|
||||
target="_blank"
|
||||
style="position: relative;"
|
||||
>
|
||||
Vue 实战教程
|
||||
<a-badge color="red" style="position: absolute;top: -10px;right: -10px;" />
|
||||
</a>
|
||||
</a-menu-item>
|
||||
) : null}
|
||||
<a-menu-item key="sponsor">
|
||||
<router-link to={{ path: isCN ? '/docs/vue/sponsor-cn/' : '/docs/vue/sponsor/' }}>
|
||||
{isCN ? '支持我们' : 'Support us'}
|
||||
</router-link>
|
||||
</a-menu-item>
|
||||
<a-sub-menu key="Ecosystem" title={isCN ? '更多' : 'More'}>
|
||||
<a-menu-item key="pro">
|
||||
<a target="_blank" href="https://pro.antdv.com">
|
||||
Pro (Admin)
|
||||
</a>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="vip">
|
||||
<a target="_blank" href="https://store.antdv.com/pro/">
|
||||
Pro For VIP
|
||||
</a>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="design">
|
||||
<router-link
|
||||
to={{ path: isCN ? '/docs/vue/download-cn/' : '/docs/vue/download/' }}
|
||||
>
|
||||
{isCN ? '设计资源' : 'Design Resources'}
|
||||
</router-link>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="vscode">
|
||||
<a
|
||||
target="_blank"
|
||||
href="https://marketplace.visualstudio.com/items?itemName=ant-design-vue.vscode-ant-design-vue-helper"
|
||||
>
|
||||
VS Code Extension
|
||||
</a>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="awesome">
|
||||
<a target="_blank" href="https://github.com/vueComponent/ant-design-vue-awesome">
|
||||
Awesome
|
||||
</a>
|
||||
</a-menu-item>
|
||||
|
||||
<a-menu-item key="wechat">
|
||||
<a-popover placement="right">
|
||||
<template slot="content">
|
||||
<img
|
||||
width="160"
|
||||
height="160"
|
||||
alt="wechat"
|
||||
src="https://qn.antdv.com/wechat.jpeg"
|
||||
/>
|
||||
</template>
|
||||
<a>{isCN ? '微信' : 'WeChat'}</a>
|
||||
</a-popover>
|
||||
</a-menu-item>
|
||||
<a-menu-item key="qq">
|
||||
<a-popover placement="right">
|
||||
<template slot="content">
|
||||
<img width="160" height="160" alt="qq" src="https://qn.antdv.com/qq.png" />
|
||||
</template>
|
||||
<a>{isCN ? 'QQ(217490093)' : 'QQ(217490093)'}</a>
|
||||
</a-popover>
|
||||
</a-menu-item>
|
||||
</a-sub-menu>
|
||||
</a-menu>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</header>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scope>
|
||||
.adblock-banner {
|
||||
position: relative;
|
||||
z-index: 100;
|
||||
min-width: 1000px;
|
||||
padding: 16px;
|
||||
line-height: 28px;
|
||||
color: #8590a6;
|
||||
text-align: center;
|
||||
background-color: #ebebeb;
|
||||
}
|
||||
.close-icon {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
}
|
||||
.global-notification {
|
||||
text-align: center;
|
||||
background: #001529;
|
||||
padding: 20px 0;
|
||||
font-size: 16px;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
color: #fff;
|
||||
z-index: 99;
|
||||
}
|
||||
.global-notification a {
|
||||
color: #177ddc;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,30 @@
|
|||
<script>
|
||||
// import * as AllDemo from '../demo'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
name: String,
|
||||
hash: String,
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
demoContext: this,
|
||||
};
|
||||
},
|
||||
render() {
|
||||
// const name = this.name
|
||||
// const titleMap = {}
|
||||
// for (const [title] of Object.entries(AllDemo)) {
|
||||
// const key = `${title.replace(/(\B[A-Z])/g, '-$1').toLowerCase()}`
|
||||
// titleMap[key] = title
|
||||
// }
|
||||
// const Demo = AllDemo[titleMap[name.replace(/-cn\/?$/, '')]]
|
||||
// const hash = this.$route.hash.replace('#', '')
|
||||
return (
|
||||
<div id="iframe-page">
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,374 @@
|
|||
<script>
|
||||
import { enquireScreen } from 'enquire-js';
|
||||
import AllDemo from '../site/demo';
|
||||
import Header from './header';
|
||||
import Footer from './footer';
|
||||
// import Geektime from './geektime';
|
||||
import GeektimeAds from './geektime_ads';
|
||||
import RightBottomAd from './right_bottom_ad';
|
||||
import Sponsors from './sponsors';
|
||||
import zhCN from 'ant-design-vue/es/locale-provider/zh_CN';
|
||||
import enUS from 'ant-design-vue/es/locale-provider/default';
|
||||
import sortBy from 'lodash/sortBy';
|
||||
import { isZhCN } from '../utils/util';
|
||||
import { Provider, create } from '../../components/_util/store';
|
||||
import NProgress from 'nprogress';
|
||||
import MobileMenu from '../../components/vc-drawer/src';
|
||||
import TopAd from './top_ad';
|
||||
import GoogleAds from './GoogleAds';
|
||||
|
||||
const docsList = [
|
||||
{ key: 'introduce', enTitle: 'Ant Design of Vue', title: 'Ant Design of Vue' },
|
||||
{ key: 'getting-started', enTitle: 'Getting Started', title: '快速上手' },
|
||||
{ key: 'use-with-vue-cli', enTitle: 'Use in vue-cli', title: '在 vue-cli 中使用' },
|
||||
{ key: 'customize-theme', enTitle: 'Customize Theme', title: '定制主题' },
|
||||
{ key: 'changelog', enTitle: 'Change Log', title: '更新日志' },
|
||||
{ key: 'i18n', enTitle: 'Internationalization', title: '国际化' },
|
||||
{ key: 'faq', enTitle: 'FAQ', title: '常见问题' },
|
||||
{ key: 'sponsor', enTitle: 'Sponsor', title: '支持我们' },
|
||||
{ key: 'download', enTitle: 'Download Design Resources', title: '下载设计资源' },
|
||||
];
|
||||
|
||||
const isGitee = window.location.host.indexOf('gitee.io') > -1;
|
||||
const showAd = false; // location.host.indexOf('antdv.com') > -1;
|
||||
|
||||
export default {
|
||||
provide() {
|
||||
return {
|
||||
demoContext: this,
|
||||
};
|
||||
},
|
||||
props: {
|
||||
name: String,
|
||||
showDemo: Boolean,
|
||||
showApi: Boolean,
|
||||
},
|
||||
data() {
|
||||
this.store = create({
|
||||
currentSubMenu: [],
|
||||
});
|
||||
this.subscribe();
|
||||
let blocked = false;
|
||||
setTimeout(() => {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'adsbox';
|
||||
document.body.appendChild(div);
|
||||
blocked = 'none' === getComputedStyle(div).display;
|
||||
}, 300);
|
||||
return {
|
||||
showSideBars: true,
|
||||
currentSubMenu: [],
|
||||
sidebarHeight: document.documentElement.offsetHeight,
|
||||
isMobile: false,
|
||||
blocked,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
'$route.path'() {
|
||||
this.store.setState({ currentSubMenu: [] });
|
||||
this.addSubMenu();
|
||||
},
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.unsubscribe) {
|
||||
this.unsubscribe();
|
||||
}
|
||||
clearTimeout(this.timer);
|
||||
if (this.resizeEvent) {
|
||||
this.resizeEvent.remove();
|
||||
}
|
||||
if (this.debouncedResize && this.debouncedResize.cancel) {
|
||||
this.debouncedResize.cancel();
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (isGitee) {
|
||||
this.$info({
|
||||
title: '提示',
|
||||
content: '访问国内镜像站点的用户请访问 antdv.com 站点',
|
||||
okText: '立即跳转',
|
||||
onOk() {
|
||||
location.href = 'https://www.antdv.com';
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.addSubMenu();
|
||||
const nprogressHiddenStyle = document.getElementById('nprogress-style');
|
||||
if (nprogressHiddenStyle) {
|
||||
this.timer = setTimeout(() => {
|
||||
nprogressHiddenStyle.parentNode.removeChild(nprogressHiddenStyle);
|
||||
}, 0);
|
||||
}
|
||||
enquireScreen(b => {
|
||||
this.isMobile = !!b;
|
||||
});
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
addSubMenu() {
|
||||
if (this.$route.path.indexOf('/docs/vue/') !== -1) {
|
||||
this.$nextTick(() => {
|
||||
const menus = [];
|
||||
const doms = [...this.$refs.doc.querySelectorAll(['h2', 'h3'])];
|
||||
doms.forEach(dom => {
|
||||
const id = dom.id;
|
||||
if (id) {
|
||||
const title = dom.textContent.split('#')[0].trim();
|
||||
menus.push({ cnTitle: title, usTitle: title, id });
|
||||
}
|
||||
});
|
||||
this.currentSubMenu = menus;
|
||||
});
|
||||
}
|
||||
},
|
||||
subscribe() {
|
||||
const { store } = this;
|
||||
this.unsubscribe = store.subscribe(() => {
|
||||
this.currentSubMenu = this.store.getState().currentSubMenu;
|
||||
});
|
||||
},
|
||||
getSubMenu(isCN) {
|
||||
const currentSubMenu = this.currentSubMenu;
|
||||
const lis = [];
|
||||
currentSubMenu.forEach(({ cnTitle, usTitle, id }, index) => {
|
||||
const title = isCN ? cnTitle : usTitle;
|
||||
lis.push(<a-anchor-link key={id + index} href={`#${id}`} title={title} />);
|
||||
});
|
||||
const showApi = this.$route.path.indexOf('/components/') !== -1;
|
||||
return (
|
||||
<a-anchor offsetTop={100} class="demo-anchor">
|
||||
{lis}
|
||||
{showApi ? <a-anchor-link key="API" title="API" href="#API" /> : ''}
|
||||
</a-anchor>
|
||||
);
|
||||
},
|
||||
getDocsMenu(isCN, pagesKey) {
|
||||
const docsMenu = [];
|
||||
docsList.forEach(({ key, enTitle, title }) => {
|
||||
const k = isCN ? `${key}-cn` : key;
|
||||
pagesKey.push({ name: k, url: `/docs/vue/${k}/`, title: isCN ? title : enTitle });
|
||||
docsMenu.push(
|
||||
<a-menu-item key={k}>
|
||||
<router-link to={`/docs/vue/${k}/`}>{isCN ? title : enTitle}</router-link>
|
||||
</a-menu-item>,
|
||||
);
|
||||
});
|
||||
return docsMenu;
|
||||
},
|
||||
resetDocumentTitle(component, name, isCN) {
|
||||
let titleStr = 'Ant Design Vue';
|
||||
if (component) {
|
||||
const { subtitle, title } = component;
|
||||
const componentName = isCN ? subtitle + ' ' + title : title;
|
||||
titleStr = componentName + ' - ' + titleStr;
|
||||
} else {
|
||||
const currentKey = docsList.filter(item => {
|
||||
return item.key === name;
|
||||
});
|
||||
if (currentKey.length) {
|
||||
titleStr = (isCN ? currentKey[0]['title'] : currentKey[0]['enTitle']) + ' - ' + titleStr;
|
||||
}
|
||||
}
|
||||
document.title = titleStr;
|
||||
},
|
||||
mountedCallback() {
|
||||
NProgress.done();
|
||||
document.documentElement.scrollTop = 0;
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
const name = this.name;
|
||||
const isCN = isZhCN(name);
|
||||
const titleMap = {};
|
||||
const menuConfig = {
|
||||
General: [],
|
||||
Layout: [],
|
||||
Navigation: [],
|
||||
'Data Entry': [],
|
||||
'Data Display': [],
|
||||
Feedback: [],
|
||||
Other: [],
|
||||
};
|
||||
const pagesKey = [];
|
||||
let prevPage = null;
|
||||
let nextPage = null;
|
||||
const searchData = [];
|
||||
for (const [title, d] of Object.entries(AllDemo)) {
|
||||
const type = d.type || 'Other';
|
||||
const key = `${title.replace(/(\B[A-Z])/g, '-$1').toLowerCase()}`;
|
||||
titleMap[key] = title;
|
||||
AllDemo[title].key = key;
|
||||
menuConfig[type] = menuConfig[type] || [];
|
||||
menuConfig[type].push(d);
|
||||
}
|
||||
const docsMenu = this.getDocsMenu(isCN, pagesKey);
|
||||
const reName = name.replace(/-cn\/?$/, '');
|
||||
const MenuGroup = [];
|
||||
for (const [type, menus] of Object.entries(menuConfig)) {
|
||||
const MenuItems = [];
|
||||
sortBy(menus, ['title']).forEach(({ title, subtitle, key }) => {
|
||||
const linkValue = isCN
|
||||
? [<span>{title}</span>, <span class="chinese">{subtitle}</span>]
|
||||
: [<span>{title}</span>];
|
||||
if (isCN) {
|
||||
key = `${key}-cn`;
|
||||
}
|
||||
pagesKey.push({
|
||||
name: key,
|
||||
url: `/components/${key}/`,
|
||||
title: isCN ? `${title} ${subtitle}` : title,
|
||||
});
|
||||
searchData.push({
|
||||
title,
|
||||
subtitle,
|
||||
url: `/components/${key}/`,
|
||||
});
|
||||
MenuItems.push(
|
||||
<a-menu-item key={key}>
|
||||
<router-link to={`/components/${key}/`}>{linkValue}</router-link>
|
||||
</a-menu-item>,
|
||||
);
|
||||
});
|
||||
MenuGroup.push(<a-menu-item-group title={type}>{MenuItems}</a-menu-item-group>);
|
||||
}
|
||||
pagesKey.forEach((item, index) => {
|
||||
if (item.name === name) {
|
||||
prevPage = pagesKey[index - 1];
|
||||
nextPage = pagesKey[index + 1];
|
||||
}
|
||||
});
|
||||
let locale = zhCN;
|
||||
if (!isCN) {
|
||||
locale = enUS;
|
||||
}
|
||||
const config = AllDemo[titleMap[reName]];
|
||||
this.resetDocumentTitle(config, reName, isCN);
|
||||
const { isMobile, $route } = this;
|
||||
return (
|
||||
<div class="page-wrapper">
|
||||
<Header searchData={searchData} name={name} />
|
||||
<a-config-provider locale={locale}>
|
||||
<div class="main-wrapper">
|
||||
<a-row>
|
||||
{isMobile ? (
|
||||
<MobileMenu ref="sidebar" wrapperClassName="drawer-wrapper">
|
||||
<a-menu
|
||||
class="aside-container menu-site"
|
||||
selectedKeys={[name]}
|
||||
defaultOpenKeys={['Components']}
|
||||
inlineIndent={40}
|
||||
mode="inline"
|
||||
>
|
||||
{docsMenu}
|
||||
<a-sub-menu title={`Components(${searchData.length})`} key="Components">
|
||||
{MenuGroup}
|
||||
</a-sub-menu>
|
||||
</a-menu>
|
||||
</MobileMenu>
|
||||
) : (
|
||||
<a-col
|
||||
ref="sidebar"
|
||||
class="site-sidebar main-menu"
|
||||
xxl={4}
|
||||
xl={5}
|
||||
lg={5}
|
||||
md={6}
|
||||
sm={8}
|
||||
xs={12}
|
||||
>
|
||||
<a-affix>
|
||||
<section class="main-menu-inner">
|
||||
<Sponsors isCN={isCN} />
|
||||
<a-menu
|
||||
class="aside-container menu-site"
|
||||
selectedKeys={[name]}
|
||||
defaultOpenKeys={['Components']}
|
||||
inlineIndent={40}
|
||||
mode="inline"
|
||||
>
|
||||
{docsMenu}
|
||||
<a-sub-menu title={`Components(${searchData.length})`} key="Components">
|
||||
{MenuGroup}
|
||||
</a-sub-menu>
|
||||
</a-menu>
|
||||
</section>
|
||||
</a-affix>
|
||||
</a-col>
|
||||
)}
|
||||
<a-col xxl={20} xl={19} lg={19} md={18} sm={24} xs={24}>
|
||||
<section class="main-container main-container-component">
|
||||
<TopAd isCN={isCN} />
|
||||
{showAd ? <GeektimeAds isMobile={isMobile} /> : null}
|
||||
{!isMobile ? (
|
||||
<div class={['toc-affix', isCN ? 'toc-affix-cn' : '']} style="width: 150px;">
|
||||
{this.getSubMenu(isCN)}
|
||||
</div>
|
||||
) : null}
|
||||
{this.showDemo ? (
|
||||
<Provider store={this.store} key={isCN ? 'cn' : 'en'}>
|
||||
<router-view
|
||||
class={`demo-cols-${config.cols || 2}`}
|
||||
{...{
|
||||
directives: [
|
||||
{
|
||||
name: 'mountedCallback',
|
||||
value: this.mountedCallback,
|
||||
},
|
||||
],
|
||||
}}
|
||||
></router-view>
|
||||
</Provider>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{this.showApi ? (
|
||||
<div class="markdown api-container" ref="doc">
|
||||
<router-view
|
||||
{...{
|
||||
directives: [
|
||||
{
|
||||
name: 'mountedCallback',
|
||||
value: this.mountedCallback,
|
||||
},
|
||||
],
|
||||
}}
|
||||
></router-view>
|
||||
{showAd ? <GoogleAds key={`GoogleAds_${$route.path}`} /> : null}
|
||||
</div>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</section>
|
||||
<section class="prev-next-nav">
|
||||
{prevPage ? (
|
||||
<router-link class="prev-page" to={`${prevPage.url}`}>
|
||||
<a-icon type="left" />
|
||||
{prevPage.title}
|
||||
</router-link>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
{nextPage ? (
|
||||
<router-link class="next-page" to={`${nextPage.url}`}>
|
||||
{nextPage.title}
|
||||
<a-icon type="right" />
|
||||
</router-link>
|
||||
) : (
|
||||
''
|
||||
)}
|
||||
</section>
|
||||
<Footer ref="footer" isCN={isCN} />
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
</a-config-provider>
|
||||
{name.indexOf('back-top') === -1 ? <a-back-top /> : null}
|
||||
<RightBottomAd isCN={isCN} isMobile={isMobile} />
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,51 @@
|
|||
<template>
|
||||
<div class="markdown" v-html="marked(text)" />
|
||||
</template>
|
||||
<script>
|
||||
import marked from 'marked';
|
||||
import { isZhCN } from '../utils/util';
|
||||
const renderer = new marked.Renderer();
|
||||
renderer.heading = function(text, level) {
|
||||
return (
|
||||
'<h' + level + ' id="' + text.replace(/[^\w]+/g, '-') + '">' + text + '</h' + level + '>\n'
|
||||
);
|
||||
};
|
||||
marked.setOptions({
|
||||
renderer,
|
||||
gfm: true,
|
||||
tables: true,
|
||||
breaks: true,
|
||||
pedantic: true,
|
||||
sanitize: true,
|
||||
smartLists: true,
|
||||
smartypants: true,
|
||||
});
|
||||
export default {
|
||||
name: 'Md',
|
||||
props: {
|
||||
cn: String,
|
||||
us: String,
|
||||
},
|
||||
inject: {
|
||||
demoContext: { default: {} },
|
||||
},
|
||||
data() {
|
||||
let text = '';
|
||||
const { cn, us } = this;
|
||||
if (this.$slots.default && this.$slots.default[0] && this.$slots.default[0].text) {
|
||||
text = this.$slots.default[0].text;
|
||||
} else {
|
||||
text = isZhCN(this.demoContext.name) ? cn : us;
|
||||
}
|
||||
text = text || '';
|
||||
text = text
|
||||
.split('\n')
|
||||
.map(t => t.trim())
|
||||
.join('\n');
|
||||
return {
|
||||
marked,
|
||||
text,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,57 @@
|
|||
<template>
|
||||
<div id="right-bottom">
|
||||
<img v-if="isCN" width="150" alt="官方公众号" src="https://qn.antdv.com/wechat.jpeg">
|
||||
<div v-if="isMobile" class="close" @click="visible = false">
|
||||
<a-icon type="close" />
|
||||
</div>
|
||||
<!-- <span v-if="isCN">广告</span> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import moment from 'moment';
|
||||
const isEffective = (start, end) => {
|
||||
return moment().isBetween(start, end);
|
||||
};
|
||||
export default {
|
||||
components: {},
|
||||
props: ['isCN', 'isMobile'],
|
||||
data() {
|
||||
return {
|
||||
visible: true,
|
||||
ads: [
|
||||
{
|
||||
alt: 'geektime',
|
||||
img: 'https://qn.antdv.com/geektime-web-small.jpg',
|
||||
href: 'http://gk.link/a/10l8O',
|
||||
visible: isEffective('2020-09-03 10:00:00', '2020-10-04 10:00:00'),
|
||||
},
|
||||
{
|
||||
alt: 'powerproject',
|
||||
img: 'https://qn.antdv.com/powerproject.jpeg?v=20200327',
|
||||
href: 'http://www.powerproject.com.cn',
|
||||
visible: isEffective('2020-03-27 17:00:00', '2020-09-28 17:00:00'),
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
#right-bottom {
|
||||
position: fixed;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
width: 150px;
|
||||
.close {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
top: -8px;
|
||||
right: -8px;
|
||||
font-size: 16px;
|
||||
padding: 15px;
|
||||
color: #6e3041;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,66 @@
|
|||
<template>
|
||||
<div class="snd-ad">
|
||||
<div class="sponsorsWrap">
|
||||
<span v-if="!isCN" class="sponsorsTitle">
|
||||
{{ isCN ? '赞助商' : 'Sponsors' }}
|
||||
</span>
|
||||
<ul>
|
||||
<!-- <li class="sponsorsItem">
|
||||
<a href="https://tipe.io/?ref=ant-design-vue" target="_blank">
|
||||
<img height="51" src="https://cdn.tipe.io/tipe/tipe-cat-no-text.svg" alt="tipe" />
|
||||
</a>
|
||||
</li> -->
|
||||
<li v-if="isCN && isEffective(effectiveTime.kkb)" class="sponsorsItem">
|
||||
<a href="https://datayi.cn/w/Y9J3M2vR" target="_blank">
|
||||
<img height="66" src="https://qn.antdv.com/kaikeba_ssr.jpeg" alt="kaikeba">
|
||||
</a>
|
||||
<span style="position: absolute; top: 0px;right: 10px">广告</span>
|
||||
</li>
|
||||
<!-- <li class="sponsorsItem">
|
||||
<a-button type="primary" ghost style="font-size: 12px" @click="handleClick">
|
||||
{{ isCN ? '成为赞助商' : 'Become a Sponsor' }}
|
||||
</a-button>
|
||||
</li> -->
|
||||
</ul>
|
||||
</div>
|
||||
<a-modal v-model="visible" title="成为赞助商" @ok="visible = false">
|
||||
如果您有品牌推广、活动推广、招聘推广、社区合作等需求,欢迎联系我们,成为赞助商。<br>
|
||||
您的广告将出现在 And Design Vue 文档所有子页面及 GitHub Readme 等页面。<br>
|
||||
咨询邮箱:<a href="mailto:antdv@foxmail.com">antdv@foxmail.com</a><br>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import moment from 'moment';
|
||||
export default {
|
||||
props: ['isCN'],
|
||||
data() {
|
||||
return {
|
||||
top: 50,
|
||||
effectiveTime: {
|
||||
bmatch: {
|
||||
start: '2019-03-11',
|
||||
end: '2019-06-11',
|
||||
},
|
||||
kkb: {
|
||||
start: '2020-11-16 22:00:00',
|
||||
end: '2021-05-17 22:00:00',
|
||||
},
|
||||
},
|
||||
visible: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
isEffective({ start, end }) {
|
||||
return moment().isBetween(start, end);
|
||||
},
|
||||
handleClick() {
|
||||
if (this.isCN) {
|
||||
this.visible = true;
|
||||
} else {
|
||||
window.open('https://opencollective.com/ant-design-vue#sponsor');
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,56 @@
|
|||
<template>
|
||||
<div>
|
||||
<template v-if="ads.length">
|
||||
<a-carousel autoplay>
|
||||
<template v-for="ad in ads">
|
||||
<a :key="ad.href" :href="ad.href" target="_blank">
|
||||
<img style="width: 100%; max-width: 1200px;" :alt="ad.alt || ''" :src="ad.img" />
|
||||
</a>
|
||||
</template>
|
||||
</a-carousel>
|
||||
</template>
|
||||
<template v-else-if="showGoogleAd">
|
||||
<GoogleAdsTop :key="`GoogleAdsTop_${$route.path}`" />
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import moment from 'moment';
|
||||
import GoogleAdsTop from './GoogleAdsTop';
|
||||
const isEffective = (start, end) => {
|
||||
return moment().isBetween(start, end);
|
||||
};
|
||||
export default {
|
||||
components: {
|
||||
GoogleAdsTop,
|
||||
},
|
||||
props: ['isCN', 'isMobile'],
|
||||
data() {
|
||||
return {
|
||||
showGoogleAd: location.host.indexOf('antdv.com') > -1,
|
||||
cnAds: [
|
||||
{
|
||||
img: `https://yidengfe.com/launches/01/yd.png?v=${Date.now()}`,
|
||||
href: 'https://yidengfe.com/launches/01/yd.html',
|
||||
visible: isEffective('2020-09-11 17:00:00', '2021-03-11 17:00:00'),
|
||||
},
|
||||
].filter(ad => ad.visible),
|
||||
enAds: [
|
||||
{
|
||||
img: 'https://qn.antdv.com/TheBigRichGroup.png',
|
||||
href: 'https://thebigrichgroup.com/',
|
||||
visible: isEffective('2020-09-18 17:00:00', '2021-10-11 17:00:00'),
|
||||
},
|
||||
].filter(ad => ad.visible),
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
ads() {
|
||||
return this.isCN ? this.cnAds : this.enAds;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
|
@ -0,0 +1,38 @@
|
|||
<cn>
|
||||
#### 基本
|
||||
最简单的用法。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### basic
|
||||
The simplest usage.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<a-affix :offset-top="top">
|
||||
<a-button type="primary" @click="top += 10">
|
||||
Affix top
|
||||
</a-button>
|
||||
</a-affix>
|
||||
<br />
|
||||
<a-affix :offset-bottom="bottom">
|
||||
<a-button type="primary" @click="bottom += 10">
|
||||
Affix bottom
|
||||
</a-button>
|
||||
</a-affix>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
top: 10,
|
||||
bottom: 10,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
```
|
|
@ -0,0 +1,44 @@
|
|||
<script>
|
||||
import Basic from './basic';
|
||||
import Onchange from './on-change';
|
||||
import Target from './target';
|
||||
import CN from '../index.zh-CN.md';
|
||||
import US from '../index.en-US.md';
|
||||
const md = {
|
||||
cn: `# Affix 固钉
|
||||
将页面元素钉在可视范围。
|
||||
## 何时使用
|
||||
当内容区域比较长,需要滚动页面时,这部分内容对应的操作或者导航需要在滚动范围内始终展现。常用于侧边菜单和按钮组合。
|
||||
页面可视范围过小时,慎用此功能以免遮挡页面内容。
|
||||
## 代码演示`,
|
||||
us: `# Affix
|
||||
Make an element stick to viewport.
|
||||
## When To Use
|
||||
When user browses a long web page, some content need to stick to the viewport. This is common for menus and actions.
|
||||
Please note that Affix should not cover other content on the page, especially when the size of the viewport is small.
|
||||
## Examples `,
|
||||
};
|
||||
export default {
|
||||
category: 'Components',
|
||||
subtitle: '固钉',
|
||||
zhType: '导航',
|
||||
type: 'Navigation',
|
||||
title: 'Affix',
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<md cn={md.cn} us={md.us} />
|
||||
<demo-sort>
|
||||
<Basic />
|
||||
<Onchange />
|
||||
<Target />
|
||||
</demo-sort>
|
||||
<api>
|
||||
<CN slot="cn" />
|
||||
<US />
|
||||
</api>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,26 @@
|
|||
<cn>
|
||||
#### 固定状态改变的回调
|
||||
可以获得是否固定的状态。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Callback
|
||||
Callback with affixed state.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<a-affix :offset-top="120" @change="change">
|
||||
<a-button>120px to affix top</a-button>
|
||||
</a-affix>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
change(affixed) {
|
||||
console.log(affixed);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
```
|
|
@ -0,0 +1,34 @@
|
|||
<cn>
|
||||
#### 滚动容器
|
||||
用 `target` 设置 `Affix` 需要监听其滚动事件的元素,默认为 `window`。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Container to scroll.
|
||||
Set a `target` for 'Affix', which is listen to scroll event of target element (default is `window`).
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div id="components-affix-demo-target" ref="container" class="scrollable-container">
|
||||
<div class="background">
|
||||
<a-affix :target="() => this.$refs.container">
|
||||
<a-button type="primary">
|
||||
Fixed at the top of container
|
||||
</a-button>
|
||||
</a-affix>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style>
|
||||
#components-affix-demo-target.scrollable-container {
|
||||
height: 100px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
#components-affix-demo-target .background {
|
||||
padding-top: 60px;
|
||||
height: 300px;
|
||||
background-image: url('https://zos.alipayobjects.com/rmsportal/RmjwQiJorKyobvI.jpg');
|
||||
}
|
||||
</style>
|
||||
```
|
|
@ -0,0 +1,29 @@
|
|||
## API
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| offsetBottom | Offset from the bottom of the viewport (in pixels) | number | - | |
|
||||
| offsetTop | Offset from the top of the viewport (in pixels) | number | 0 | |
|
||||
| target | Specifies the scrollable area DOM node | () => HTMLElement | () => window | |
|
||||
|
||||
### events
|
||||
|
||||
| Events Name | Description | Arguments | Version |
|
||||
| ----------- | ---------------------------------------- | ----------------- | ------- |
|
||||
| change | Callback for when Affix state is changed | Function(affixed) |
|
||||
|
||||
**Note:** Children of `Affix` must not have the property `position: absolute`, but you can set `position: absolute` on `Affix` itself:
|
||||
|
||||
```html
|
||||
<a-affix :style="{ position: 'absolute', top: y, left: x}">
|
||||
...
|
||||
</a-affix>
|
||||
```
|
||||
|
||||
## FAQ
|
||||
|
||||
### Affix bind container with `target`, sometime move out of container.
|
||||
|
||||
We don't listen window scroll for performance consideration.
|
||||
|
||||
Related issues:[#3938](https://github.com/ant-design/ant-design/issues/3938) [#5642](https://github.com/ant-design/ant-design/issues/5642) [#16120](https://github.com/ant-design/ant-design/issues/16120)
|
|
@ -0,0 +1,29 @@
|
|||
## API
|
||||
|
||||
| 成员 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| offsetBottom | 距离窗口底部达到指定偏移量后触发 | number | | |
|
||||
| offsetTop | 距离窗口顶部达到指定偏移量后触发 | number | | |
|
||||
| target | 设置 `Affix` 需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 | () => HTMLElement | () => window | |
|
||||
|
||||
### 事件
|
||||
|
||||
| 事件名称 | 说明 | 回调参数 | 版本 |
|
||||
| -------- | ---------------------------- | ----------------- | ---- |
|
||||
| change | 固定状态改变时触发的回调函数 | Function(affixed) | 无 | |
|
||||
|
||||
**注意:**`Affix` 内的元素不要使用绝对定位,如需要绝对定位的效果,可以直接设置 `Affix` 为绝对定位:
|
||||
|
||||
```html
|
||||
<a-affix :style="{ position: 'absolute', top: y, left: x}">
|
||||
...
|
||||
</a-affix>
|
||||
```
|
||||
|
||||
## FAQ
|
||||
|
||||
### Affix 使用 `target` 绑定容器时,元素会跑到容器外。
|
||||
|
||||
从性能角度考虑,我们只监听容器滚动事件。
|
||||
|
||||
相关 issue:[#3938](https://github.com/ant-design/ant-design/issues/3938) [#5642](https://github.com/ant-design/ant-design/issues/5642) [#16120](https://github.com/ant-design/ant-design/issues/16120)
|
|
@ -0,0 +1,27 @@
|
|||
<cn>
|
||||
#### 顶部公告
|
||||
页面顶部通告形式,默认有图标且`type` 为 'warning'。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Banner
|
||||
Display Alert as a banner at top of page.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<a-alert message="Warning text" banner />
|
||||
<br />
|
||||
<a-alert
|
||||
message="Very long warning text warning text text text text text text text"
|
||||
banner
|
||||
closable
|
||||
/>
|
||||
<br />
|
||||
<a-alert :show-icon="false" message="Warning text without icon" banner />
|
||||
<br />
|
||||
<a-alert type="error" message="Error text" banner />
|
||||
</div>
|
||||
</template>
|
||||
```
|
|
@ -0,0 +1,15 @@
|
|||
<cn>
|
||||
#### 基本
|
||||
最简单的用法,适用于简短的警告提示。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### basic
|
||||
The simplest usage for short messages.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<a-alert message="Success Text" type="success" />
|
||||
</template>
|
||||
```
|
|
@ -0,0 +1,38 @@
|
|||
<cn>
|
||||
#### 可关闭的警告提示
|
||||
显示关闭按钮,点击可关闭警告提示。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Closable
|
||||
To show close button.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<a-alert
|
||||
message="Warning Text Warning Text Warning TextW arning Text Warning Text Warning TextWarning Text"
|
||||
type="warning"
|
||||
closable
|
||||
@close="onClose"
|
||||
/>
|
||||
<a-alert
|
||||
message="Error Text"
|
||||
description="Error Description Error Description Error Description Error Description Error Description Error Description"
|
||||
type="error"
|
||||
closable
|
||||
@close="onClose"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
onClose(e) {
|
||||
console.log(e, 'I was closed.');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
```
|
|
@ -0,0 +1,15 @@
|
|||
<cn>
|
||||
#### 自定义关闭
|
||||
可以自定义关闭,自定义的文字会替换原先的关闭 `Icon`。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Customized Close Text
|
||||
Replace the default icon with customized text.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<a-alert message="Info Text" type="info" close-text="Close Now" />
|
||||
</template>
|
||||
```
|
|
@ -0,0 +1,63 @@
|
|||
<cn>
|
||||
#### 自定义图标
|
||||
可口的图标让信息类型更加醒目。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Custom Icon
|
||||
Decent icon make information more clear and more friendly.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<a-alert message="showIcon = false" type="success">
|
||||
<a-icon slot="icon" type="smile" />
|
||||
</a-alert>
|
||||
<a-alert message="Success Tips" type="success" show-icon>
|
||||
<a-icon slot="icon" type="smile" />
|
||||
</a-alert>
|
||||
<a-alert message="Informational Notes" type="info" show-icon>
|
||||
<a-icon slot="icon" type="smile" />
|
||||
</a-alert>
|
||||
<a-alert message="Warning" type="warning" show-icon>
|
||||
<a-icon slot="icon" type="smile" />
|
||||
</a-alert>
|
||||
<a-alert message="Error" type="error" show-icon>
|
||||
<a-icon slot="icon" type="smile" />
|
||||
</a-alert>
|
||||
<a-alert
|
||||
message="Success Tips"
|
||||
description="Detailed description and advices about successful copywriting."
|
||||
type="success"
|
||||
show-icon
|
||||
>
|
||||
<a-icon slot="icon" type="smile" />
|
||||
</a-alert>
|
||||
<a-alert
|
||||
message="Informational Notes"
|
||||
description="Additional description and informations about copywriting."
|
||||
type="info"
|
||||
show-icon
|
||||
>
|
||||
<a-icon slot="icon" type="smile" />
|
||||
</a-alert>
|
||||
<a-alert
|
||||
message="Warning"
|
||||
description="This is a warning notice about copywriting."
|
||||
type="warning"
|
||||
show-icon
|
||||
>
|
||||
<a-icon slot="icon" type="smile" />
|
||||
</a-alert>
|
||||
<a-alert
|
||||
message="Error"
|
||||
description="This is an error message about copywriting."
|
||||
type="error"
|
||||
show-icon
|
||||
>
|
||||
<a-icon slot="icon" type="smile" />
|
||||
</a-alert>
|
||||
</div>
|
||||
</template>
|
||||
```
|
|
@ -0,0 +1,36 @@
|
|||
<cn>
|
||||
#### 含有辅助性文字介绍
|
||||
含有辅助性文字介绍的警告提示。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Description
|
||||
Additional description for alert message.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<a-alert message="Success Text" type="success">
|
||||
<p slot="description">
|
||||
Success Description <span style="color: red">Success</span> Description Success Description
|
||||
</p>
|
||||
</a-alert>
|
||||
<a-alert
|
||||
message="Info Text"
|
||||
description="Info Description Info Description Info Description Info Description"
|
||||
type="info"
|
||||
/>
|
||||
<a-alert
|
||||
message="Warning Text"
|
||||
description="Warning Description Warning Description Warning Description Warning Description"
|
||||
type="warning"
|
||||
/>
|
||||
<a-alert
|
||||
message="Error Text"
|
||||
description="Error Description Error Description Error Description Error Description"
|
||||
type="error"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
```
|
|
@ -0,0 +1,44 @@
|
|||
<cn>
|
||||
#### 图标
|
||||
可口的图标让信息类型更加醒目。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Icon
|
||||
Decent icon make information more clear and more friendly.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<a-alert message="Success Tips" type="success" show-icon />
|
||||
<a-alert message="Informational Notes" type="info" show-icon />
|
||||
<a-alert message="Warning" type="warning" show-icon />
|
||||
<a-alert message="Error" type="error" show-icon />
|
||||
<a-alert
|
||||
message="Success Tips"
|
||||
description="Detailed description and advices about successful copywriting."
|
||||
type="success"
|
||||
show-icon
|
||||
/>
|
||||
<a-alert
|
||||
message="Informational Notes"
|
||||
description="Additional description and informations about copywriting."
|
||||
type="info"
|
||||
show-icon
|
||||
/>
|
||||
<a-alert
|
||||
message="Warning"
|
||||
description="This is a warning notice about copywriting."
|
||||
type="warning"
|
||||
show-icon
|
||||
/>
|
||||
<a-alert
|
||||
message="Error"
|
||||
description="This is an error message about copywriting."
|
||||
type="error"
|
||||
show-icon
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
```
|
|
@ -0,0 +1,61 @@
|
|||
<script>
|
||||
import Banner from './banner';
|
||||
import Basic from './basic';
|
||||
import Closable from './closable';
|
||||
import CloseText from './close-text';
|
||||
import Description from './description';
|
||||
import Icon from './icon';
|
||||
import Style from './style';
|
||||
import SmoothClosed from './smooth-closed';
|
||||
|
||||
import CN from '../index.zh-CN.md';
|
||||
import US from '../index.en-US.md';
|
||||
const md = {
|
||||
cn: `# Alert 警告提示
|
||||
警告提示,展现需要关注的信息。
|
||||
## 何时使用
|
||||
- 当某个页面需要向用户显示警告的信息时。
|
||||
- 非浮层的静态展现形式,始终展现,不会自动消失,用户可以点击关闭。
|
||||
## 代码演示`,
|
||||
us: `# Alert
|
||||
Alert component for feedback.
|
||||
## When To Use
|
||||
- When you need to show alert messages to users.
|
||||
- When you need a persistent static container which is closable by user actions.
|
||||
## Examples
|
||||
`,
|
||||
};
|
||||
export default {
|
||||
category: 'Components',
|
||||
subtitle: '警告提示',
|
||||
type: 'Feedback',
|
||||
zhType: '反馈',
|
||||
title: 'Alert',
|
||||
render() {
|
||||
return (
|
||||
<div id="components-alert-demo">
|
||||
<md cn={md.cn} us={md.us} />
|
||||
<demo-sort>
|
||||
<Banner />
|
||||
<Basic />
|
||||
<Closable />
|
||||
<CloseText />
|
||||
<Description />
|
||||
<Icon />
|
||||
<Style />
|
||||
<SmoothClosed />
|
||||
</demo-sort>
|
||||
<api>
|
||||
<CN slot="cn" />
|
||||
<US />
|
||||
</api>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
#components-alert-demo .ant-alert {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,37 @@
|
|||
<cn>
|
||||
#### 平滑地卸载
|
||||
平滑、自然的卸载提示。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Smoothly Unmount
|
||||
Smoothly and unaffectedly unmount Alert.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<a-alert
|
||||
v-if="visible"
|
||||
message="Alert Message Text"
|
||||
type="success"
|
||||
closable
|
||||
:after-close="handleClose"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
visible: true,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleClose() {
|
||||
this.visible = false;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
```
|
|
@ -0,0 +1,20 @@
|
|||
<cn>
|
||||
#### 四种样式
|
||||
共有四种样式 `success`、`info`、`warning`、`error`。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### More types
|
||||
There are 4 types of Alert: `success`, `info`, `warning`, `error`.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<a-alert message="Success Text" type="success" />
|
||||
<a-alert message="Info Text" type="info" />
|
||||
<a-alert message="Warning Text" type="warning" />
|
||||
<a-alert message="Error Text" type="error" />
|
||||
</div>
|
||||
</template>
|
||||
```
|
|
@ -0,0 +1,19 @@
|
|||
## API
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| afterClose | Called when close animation is finished | () => void | - | - |
|
||||
| banner | Whether to show as banner | boolean | false | - |
|
||||
| closable | Whether Alert can be closed | boolean | - | - |
|
||||
| closeText | Close text to show | string\|slot | - | - |
|
||||
| description | Additional content of Alert | string\|slot | - | - |
|
||||
| icon | Custom icon, effective when `showIcon` is `true` | vnode \| slot | - | - |
|
||||
| message | Content of Alert | string\|slot | - | - |
|
||||
| showIcon | Whether to show icon | boolean | false, in `banner` mode default is true | - |
|
||||
| type | Type of Alert styles, options: `success`, `info`, `warning`, `error` | string | `info`, in `banner` mode default is `warning` | - |
|
||||
|
||||
### events
|
||||
|
||||
| Events Name | Description | Arguments | Version |
|
||||
| ----------- | ----------------------------- | ----------------------- | ------- |
|
||||
| close | Callback when Alert is closed | (e: MouseEvent) => void | - |
|
|
@ -0,0 +1,19 @@
|
|||
## API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| afterClose | 关闭动画结束后触发的回调函数 | () => void | - | - |
|
||||
| banner | 是否用作顶部公告 | boolean | false | - |
|
||||
| closable | 默认不显示关闭按钮 | boolean | 无 | - |
|
||||
| closeText | 自定义关闭按钮 | string\|slot | 无 | - |
|
||||
| description | 警告提示的辅助性文字介绍 | string\|slot | 无 | - |
|
||||
| icon | 自定义图标,`showIcon` 为 `true` 时有效 | vnode \| slot | - | - |
|
||||
| message | 警告提示内容 | string\|slot | 无 | - |
|
||||
| showIcon | 是否显示辅助图标 | boolean | false,`banner` 模式下默认值为 true | - |
|
||||
| type | 指定警告提示的样式,有四种选择 `success`、`info`、`warning`、`error` | string | `info`,`banner` 模式下默认值为 `warning` | - |
|
||||
|
||||
### 事件
|
||||
|
||||
| 事件名称 | 说明 | 回调参数 | 版本 |
|
||||
| -------- | -------------------- | ----------------------- | ---- |
|
||||
| close | 关闭时触发的回调函数 | (e: MouseEvent) => void | - |
|
|
@ -0,0 +1,27 @@
|
|||
<cn>
|
||||
#### 基本
|
||||
最简单的用法。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### basic
|
||||
The simplest usage.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<a-anchor>
|
||||
<a-anchor-link href="#components-anchor-demo-basic" title="Basic demo" />
|
||||
<a-anchor-link href="#components-anchor-demo-static" title="Static demo" />
|
||||
<a-anchor-link
|
||||
href="#components-anchor-demo-basic"
|
||||
title="Basic demo with Target"
|
||||
target="_blank"
|
||||
/>
|
||||
<a-anchor-link href="#API" title="API">
|
||||
<a-anchor-link href="#Anchor-Props" title="Anchor Props" />
|
||||
<a-anchor-link href="#Link-Props" title="Link Props" />
|
||||
</a-anchor-link>
|
||||
</a-anchor>
|
||||
</template>
|
||||
```
|
|
@ -0,0 +1,31 @@
|
|||
<cn>
|
||||
#### 自定义锚点高亮
|
||||
自定义锚点高亮。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Customize the anchor highlight
|
||||
Customize the anchor highlight.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<a-anchor :affix="false" :get-current-anchor="getCurrentAnchor">
|
||||
<a-anchor-link href="#components-anchor-demo-basic" title="Basic demo" />
|
||||
<a-anchor-link href="#components-anchor-demo-static" title="Static demo" />
|
||||
<a-anchor-link href="#API" title="API">
|
||||
<a-anchor-link href="#Anchor-Props" title="Anchor Props" />
|
||||
<a-anchor-link href="#Link-Props" title="Link Props" />
|
||||
</a-anchor-link>
|
||||
</a-anchor>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
getCurrentAnchor() {
|
||||
return '#components-anchor-demo-static';
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
```
|
|
@ -0,0 +1,61 @@
|
|||
<script>
|
||||
import Basic from './basic';
|
||||
import Static from './static';
|
||||
import OnClick from './onClick';
|
||||
import CustomizeHighlight from './customizeHighlight';
|
||||
import OnChange from './onChange';
|
||||
import TargetOffset from './targetOffset';
|
||||
|
||||
import CN from '../index.zh-CN.md';
|
||||
import US from '../index.en-US.md';
|
||||
const md = {
|
||||
cn: `# Anchor 锚点
|
||||
用于跳转到页面指定位置。
|
||||
|
||||
## 何时使用
|
||||
|
||||
需要展现当前页面上可供跳转的锚点链接,以及快速在锚点之间跳转。
|
||||
## 代码演示`,
|
||||
us: `# Anchor
|
||||
|
||||
Hyperlinks to scroll on one page.
|
||||
|
||||
## When To Use
|
||||
|
||||
For displaying anchor hyperlinks on page and jumping between them.
|
||||
## Examples
|
||||
`,
|
||||
};
|
||||
export default {
|
||||
category: 'Components',
|
||||
subtitle: '锚点',
|
||||
cols: 2,
|
||||
type: 'Other',
|
||||
zhType: '其他',
|
||||
title: 'Anchor',
|
||||
render() {
|
||||
return (
|
||||
<div id="components-anchor-demo">
|
||||
<md cn={md.cn} us={md.us} />
|
||||
<demo-sort>
|
||||
<Basic />
|
||||
<Static />
|
||||
<OnClick />
|
||||
<CustomizeHighlight />
|
||||
<OnChange />
|
||||
<TargetOffset />
|
||||
</demo-sort>
|
||||
<api>
|
||||
<CN slot="cn" />
|
||||
<US />
|
||||
</api>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
#components-anchor-demo .ant-affix {
|
||||
z-index: 11;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,31 @@
|
|||
<cn>
|
||||
#### 监听锚点链接改变
|
||||
监听锚点链接改变
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Listening for anchor link change
|
||||
Listening for anchor link change.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<a-anchor :affix="false" @change="onChange">
|
||||
<a-anchor-link href="#components-anchor-demo-basic" title="Basic demo" />
|
||||
<a-anchor-link href="#components-anchor-demo-static" title="Static demo" />
|
||||
<a-anchor-link href="#API" title="API">
|
||||
<a-anchor-link href="#Anchor-Props" title="Anchor Props" />
|
||||
<a-anchor-link href="#Link-Props" title="Link Props" />
|
||||
</a-anchor-link>
|
||||
</a-anchor>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
onChange(link) {
|
||||
console.log('Anchor:OnChange', link);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
```
|
|
@ -0,0 +1,32 @@
|
|||
<cn>
|
||||
#### 自定义 click 事件
|
||||
点击锚点不记录历史。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Customize the click event
|
||||
Clicking on an anchor does not record history.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<a-anchor :affix="false" @click="handleClick">
|
||||
<a-anchor-link href="#components-anchor-demo-basic" title="Basic demo" />
|
||||
<a-anchor-link href="#components-anchor-demo-static" title="Static demo" />
|
||||
<a-anchor-link href="#API" title="API">
|
||||
<a-anchor-link href="#Anchor-Props" title="Anchor Props" />
|
||||
<a-anchor-link href="#Link-Props" title="Link Props" />
|
||||
</a-anchor-link>
|
||||
</a-anchor>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
handleClick(e, link) {
|
||||
e.preventDefault();
|
||||
console.log(link);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
```
|
|
@ -0,0 +1,22 @@
|
|||
<cn>
|
||||
#### 静态位置
|
||||
不浮动,状态不随页面滚动变化。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Static
|
||||
Do not change state when page is scrolling.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<a-anchor :affix="false">
|
||||
<a-anchor-link href="#components-anchor-demo-basic" title="Basic demo" />
|
||||
<a-anchor-link href="#components-anchor-demo-static" title="Static demo" />
|
||||
<a-anchor-link href="#API" title="API">
|
||||
<a-anchor-link href="#Anchor-Props" title="Anchor Props" />
|
||||
<a-anchor-link href="#Link-Props" title="Link Props" />
|
||||
</a-anchor-link>
|
||||
</a-anchor>
|
||||
</template>
|
||||
```
|
|
@ -0,0 +1,34 @@
|
|||
<cn>
|
||||
#### 设置锚点滚动偏移量
|
||||
锚点目标滚动到屏幕正中间。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Set Anchor scroll offset
|
||||
Anchor target scroll to screen center.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<a-anchor :target-offset="targetOffset">
|
||||
<a-anchor-link href="#components-anchor-demo-basic" title="Basic demo" />
|
||||
<a-anchor-link href="#components-anchor-demo-static" title="Static demo" />
|
||||
<a-anchor-link href="#API" title="API">
|
||||
<a-anchor-link href="#Anchor-Props" title="Anchor Props" />
|
||||
<a-anchor-link href="#Link-Props" title="Link Props" />
|
||||
</a-anchor-link>
|
||||
</a-anchor>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
targetOffset: undefined,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.targetOffset = window.innerHeight / 2;
|
||||
},
|
||||
};
|
||||
</script>
|
||||
```
|
|
@ -0,0 +1,31 @@
|
|||
## API
|
||||
|
||||
### Anchor Props
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| affix | Fixed mode of Anchor | boolean | true | |
|
||||
| bounds | Bounding distance of anchor area | number | 5(px) | |
|
||||
| getContainer | Scrolling container | () => HTMLElement | () => window | |
|
||||
| offsetBottom | Pixels to offset from bottom when calculating position of scroll | number | - | |
|
||||
| offsetTop | Pixels to offset from top when calculating position of scroll | number | 0 | |
|
||||
| showInkInFixed | Whether show ink-balls in Fixed mode | boolean | false | |
|
||||
| wrapperClass | The class name of the container | string | - | |
|
||||
| wrapperStyle | The style of the container | object | - | |
|
||||
| getCurrentAnchor | Customize the anchor highlight | () => string | - | 1.5.0 |
|
||||
| targetOffset | Anchor scroll offset, default as `offsetTop`, [example](#components-anchor-demo-targetOffset) | number | `offsetTop` | 1.5.0 |
|
||||
|
||||
### Events
|
||||
|
||||
| Events Name | Description | Arguments | Version |
|
||||
| --- | --- | --- | --- |
|
||||
| click | set the handler to handle `click` event | Function(e: Event, link: Object) | |
|
||||
| change | Listening for anchor link change | (currentActiveLink: string) => void | | 1.5.0 |
|
||||
|
||||
### Link Props
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
| -------- | ----------------------------------------- | ------------ | ------- | ------- |
|
||||
| href | target of hyperlink | string | | |
|
||||
| title | content of hyperlink | string\|slot | | |
|
||||
| target | Specifies where to display the linked URL | string | | 1.5.0 |
|
|
@ -0,0 +1,31 @@
|
|||
## API
|
||||
|
||||
### Anchor Props
|
||||
|
||||
| 成员 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| affix | 固定模式 | boolean | true | |
|
||||
| bounds | 锚点区域边界 | number | 5(px) | |
|
||||
| getContainer | 指定滚动的容器 | () => HTMLElement | () => window | |
|
||||
| offsetBottom | 距离窗口底部达到指定偏移量后触发 | number | | |
|
||||
| offsetTop | 距离窗口顶部达到指定偏移量后触发 | number | | |
|
||||
| showInkInFixed | 固定模式是否显示小圆点 | boolean | false | |
|
||||
| wrapperClass | 容器的类名 | string | - | |
|
||||
| wrapperStyle | 容器样式 | object | - | |
|
||||
| getCurrentAnchor | 自定义高亮的锚点 | () => string | - | 1.5.0 |
|
||||
| targetOffset | 锚点滚动偏移量,默认与 offsetTop 相同,[例子](#components-anchor-demo-targetOffset) | number | `offsetTop` | 1.5.0 |
|
||||
|
||||
### 事件
|
||||
|
||||
| 事件名称 | 说明 | 回调参数 | 版本 |
|
||||
| -------- | ---------------------- | ----------------------------------- | ---- |
|
||||
| click | `click` 事件的 handler | Function(e: Event, link: Object) | |
|
||||
| change | 监听锚点链接改变 | (currentActiveLink: string) => void | | 1.5.0 |
|
||||
|
||||
### Link Props
|
||||
|
||||
| 成员 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| ------ | -------------------------------- | ------------ | ------ | ----- |
|
||||
| href | 锚点链接 | string | | |
|
||||
| title | 文字内容 | string\|slot | | |
|
||||
| target | 该属性指定在何处显示链接的资源。 | string | | 1.5.0 |
|
|
@ -0,0 +1,49 @@
|
|||
<cn>
|
||||
#### 基本使用
|
||||
基本使用。通过 dataSource 设置自动完成的数据源
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Basic Usage
|
||||
Basic Usage, set datasource of autocomplete with `dataSource` property.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<a-auto-complete
|
||||
v-model="value"
|
||||
:data-source="dataSource"
|
||||
style="width: 200px"
|
||||
placeholder="input here"
|
||||
@select="onSelect"
|
||||
@search="onSearch"
|
||||
@change="onChange"
|
||||
/>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
value: '',
|
||||
dataSource: [],
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
value(val) {
|
||||
console.log('value', val);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onSearch(searchText) {
|
||||
this.dataSource = !searchText ? [] : [searchText, searchText.repeat(2), searchText.repeat(3)];
|
||||
},
|
||||
onSelect(value) {
|
||||
console.log('onSelect', value);
|
||||
},
|
||||
onChange(value) {
|
||||
console.log('onChange', value);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
```
|
|
@ -0,0 +1,149 @@
|
|||
<cn>
|
||||
#### 查询模式 - 确定类目
|
||||
查询模式 - 确定类目
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Lookup-Patterns - Certain Category
|
||||
Lookup-Patterns - Certain Category
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div class="certain-category-search-wrapper" style="width: 250px">
|
||||
<a-auto-complete
|
||||
class="certain-category-search"
|
||||
dropdown-class-name="certain-category-search-dropdown"
|
||||
:dropdown-match-select-width="false"
|
||||
:dropdown-style="{ width: '300px' }"
|
||||
size="large"
|
||||
style="width: 100%"
|
||||
placeholder="input here"
|
||||
option-label-prop="value"
|
||||
>
|
||||
<template slot="dataSource">
|
||||
<a-select-opt-group v-for="group in dataSource" :key="group.title">
|
||||
<span slot="label">
|
||||
{{ group.title }}
|
||||
<a
|
||||
style="float: right"
|
||||
href="https://www.google.com/search?q=antd"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>more
|
||||
</a>
|
||||
</span>
|
||||
<a-select-option v-for="opt in group.children" :key="opt.title" :value="opt.title">
|
||||
{{ opt.title }}
|
||||
<span class="certain-search-item-count">{{ opt.count }} people</span>
|
||||
</a-select-option>
|
||||
</a-select-opt-group>
|
||||
<a-select-option key="all" disabled class="show-all">
|
||||
<a
|
||||
href="https://www.google.com/search?q=ant-design-vue"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
View all results
|
||||
</a>
|
||||
</a-select-option>
|
||||
</template>
|
||||
<a-input>
|
||||
<a-icon slot="suffix" type="search" class="certain-category-icon" />
|
||||
</a-input>
|
||||
</a-auto-complete>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
const dataSource = [
|
||||
{
|
||||
title: 'Libraries',
|
||||
children: [
|
||||
{
|
||||
title: 'AntDesign',
|
||||
count: 10000,
|
||||
},
|
||||
{
|
||||
title: 'AntDesign UI',
|
||||
count: 10600,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Solutions',
|
||||
children: [
|
||||
{
|
||||
title: 'AntDesign UI',
|
||||
count: 60100,
|
||||
},
|
||||
{
|
||||
title: 'AntDesign',
|
||||
count: 30010,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Articles',
|
||||
children: [
|
||||
{
|
||||
title: 'AntDesign design language',
|
||||
count: 100000,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dataSource,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.certain-category-search-dropdown .ant-select-dropdown-menu-item-group-title {
|
||||
color: #666;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.certain-category-search-dropdown .ant-select-dropdown-menu-item-group {
|
||||
border-bottom: 1px solid #f6f6f6;
|
||||
}
|
||||
|
||||
.certain-category-search-dropdown .ant-select-dropdown-menu-item {
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
.certain-category-search-dropdown .ant-select-dropdown-menu-item.show-all {
|
||||
text-align: center;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.certain-category-search-dropdown .ant-select-dropdown-menu {
|
||||
max-height: 300px;
|
||||
}
|
||||
</style>
|
||||
<style scoped>
|
||||
.certain-category-search-wrapper
|
||||
>>> .certain-category-search.ant-select-auto-complete
|
||||
.ant-input-affix-wrapper
|
||||
.ant-input-suffix {
|
||||
right: 12px;
|
||||
}
|
||||
.certain-category-search-wrapper >>> .certain-search-item-count {
|
||||
position: absolute;
|
||||
color: #999;
|
||||
right: 16px;
|
||||
}
|
||||
.certain-category-search-wrapper
|
||||
>>> .certain-category-search.ant-select-focused
|
||||
.certain-category-icon {
|
||||
color: #108ee9;
|
||||
}
|
||||
.certain-category-search-wrapper >>> .certain-category-icon {
|
||||
color: #6e6e6e;
|
||||
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
```
|
|
@ -0,0 +1,47 @@
|
|||
<cn>
|
||||
#### 自定义输入组件
|
||||
自定义输入组件。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Customize Input Component
|
||||
Customize Input Component
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<a-auto-complete
|
||||
:data-source="dataSource"
|
||||
style="width: 200px"
|
||||
@search="handleSearch"
|
||||
@select="onSelect"
|
||||
>
|
||||
<a-textarea
|
||||
placeholder="input here"
|
||||
class="custom"
|
||||
style="height: 50px"
|
||||
@keypress="handleKeyPress"
|
||||
/>
|
||||
</a-auto-complete>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dataSource: [],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onSelect(value) {
|
||||
console.log('onSelect', value);
|
||||
},
|
||||
handleSearch(value) {
|
||||
this.dataSource = !value ? [] : [value, value + value, value + value + value];
|
||||
},
|
||||
handleKeyPress(ev) {
|
||||
console.log('handleKeyPress', ev);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
```
|
|
@ -0,0 +1,51 @@
|
|||
<script>
|
||||
import Basic from './basic';
|
||||
import CertainCategory from './certain-category';
|
||||
import Custom from './custom';
|
||||
import NonCaseSensitive from './non-case-sensitive';
|
||||
import Options from './options';
|
||||
import UncertainCategory from './uncertain-category';
|
||||
|
||||
import CN from '../index.zh-CN.md';
|
||||
import US from '../index.en-US.md';
|
||||
const md = {
|
||||
cn: `# AutoComplete 自动完成
|
||||
输入框自动完成功能。
|
||||
## 何时使用
|
||||
需要自动完成时。
|
||||
## 代码演示`,
|
||||
us: `# AutoComplete
|
||||
Autocomplete function of input field.
|
||||
## When To Use
|
||||
When there is a need for autocomplete functionality.
|
||||
## Examples
|
||||
`,
|
||||
};
|
||||
export default {
|
||||
category: 'Components',
|
||||
subtitle: '自动完成',
|
||||
type: 'Data Entry',
|
||||
zhType: '数据录入',
|
||||
cols: 2,
|
||||
title: 'AutoComplete',
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<md cn={md.cn} us={md.us} />
|
||||
<demo-sort>
|
||||
<Basic />
|
||||
<CertainCategory />
|
||||
<Custom />
|
||||
<NonCaseSensitive />
|
||||
<Options />
|
||||
<UncertainCategory />
|
||||
</demo-sort>
|
||||
<api>
|
||||
<CN slot="cn" />
|
||||
<US />
|
||||
</api>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,36 @@
|
|||
<cn>
|
||||
#### 不区分大小写
|
||||
不区分大小写的 AutoComplete
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Non-case-sensitive AutoComplete
|
||||
A non-case-sensitive AutoComplete
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<a-auto-complete
|
||||
:data-source="dataSource"
|
||||
style="width: 200px"
|
||||
placeholder="input here"
|
||||
:filter-option="filterOption"
|
||||
/>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dataSource: ['Burns Bay Road', 'Downing Street', 'Wall Street'],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
filterOption(input, option) {
|
||||
return (
|
||||
option.componentOptions.children[0].text.toUpperCase().indexOf(input.toUpperCase()) >= 0
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
```
|
|
@ -0,0 +1,41 @@
|
|||
<cn>
|
||||
#### 自定义选项
|
||||
也可以直接传递slot="dataSource"的Option
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Customized
|
||||
You could pass `slot="dataSource` as children of `AutoComplete`, instead of using `dataSource`。
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<a-auto-complete style="width: 200px" placeholder="input here" @search="handleSearch">
|
||||
<template slot="dataSource">
|
||||
<a-select-option v-for="email in result" :key="email">
|
||||
{{ email }}
|
||||
</a-select-option>
|
||||
</template>
|
||||
</a-auto-complete>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
result: [],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleSearch(value) {
|
||||
let result;
|
||||
if (!value || value.indexOf('@') >= 0) {
|
||||
result = [];
|
||||
} else {
|
||||
result = ['gmail.com', '163.com', 'qq.com'].map(domain => `${value}@${domain}`);
|
||||
}
|
||||
this.result = result;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
```
|
|
@ -0,0 +1,120 @@
|
|||
<cn>
|
||||
#### 查询模式 - 不确定类目
|
||||
查询模式 - 不确定类目
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Lookup-Patterns - Uncertain Category
|
||||
Lookup-Patterns - Uncertain Category
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div class="global-search-wrapper" style="width: 300px">
|
||||
<a-auto-complete
|
||||
class="global-search"
|
||||
size="large"
|
||||
style="width: 100%"
|
||||
placeholder="input here"
|
||||
option-label-prop="title"
|
||||
@select="onSelect"
|
||||
@search="handleSearch"
|
||||
>
|
||||
<template slot="dataSource">
|
||||
<a-select-option v-for="item in dataSource" :key="item.category" :title="item.category">
|
||||
Found {{ item.query }} on
|
||||
<a
|
||||
:href="`https://s.taobao.com/search?q=${item.query}`"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{{ item.category }}
|
||||
</a>
|
||||
<span className="global-search-item-count">{{ item.count }} results</span>
|
||||
</a-select-option>
|
||||
</template>
|
||||
<a-input>
|
||||
<a-button
|
||||
slot="suffix"
|
||||
style="margin-right: -12px"
|
||||
class="search-btn"
|
||||
size="large"
|
||||
type="primary"
|
||||
>
|
||||
<a-icon type="search" />
|
||||
</a-button>
|
||||
</a-input>
|
||||
</a-auto-complete>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dataSource: [],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onSelect(value) {
|
||||
console.log('onSelect', value);
|
||||
},
|
||||
|
||||
handleSearch(value) {
|
||||
this.dataSource = value ? this.searchResult(value) : [];
|
||||
},
|
||||
|
||||
getRandomInt(max, min = 0) {
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
},
|
||||
|
||||
searchResult(query) {
|
||||
return new Array(this.getRandomInt(5))
|
||||
.join('.')
|
||||
.split('.')
|
||||
.map((item, idx) => ({
|
||||
query,
|
||||
category: `${query}${idx}`,
|
||||
count: this.getRandomInt(200, 100),
|
||||
}));
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.global-search-wrapper {
|
||||
padding-right: 50px;
|
||||
}
|
||||
|
||||
.global-search {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.global-search.ant-select-auto-complete .ant-select-selection--single {
|
||||
margin-right: -46px;
|
||||
}
|
||||
|
||||
.global-search.ant-select-auto-complete .ant-input-affix-wrapper .ant-input:not(:last-child) {
|
||||
padding-right: 62px;
|
||||
}
|
||||
|
||||
.global-search.ant-select-auto-complete .ant-input-affix-wrapper .ant-input-suffix button {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
.global-search-item {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.global-search-item-desc {
|
||||
flex: auto;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.global-search-item-count {
|
||||
flex: none;
|
||||
}
|
||||
</style>
|
||||
```
|
|
@ -0,0 +1,41 @@
|
|||
## API
|
||||
|
||||
```html
|
||||
<a-auto-complete :dataSource="dataSource" />
|
||||
```
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| allowClear | Show clear button, effective in multiple mode only. | boolean | false | |
|
||||
| autoFocus | get focus when component mounted | boolean | false | |
|
||||
| backfill | backfill selected item the input when using keyboard | boolean | false | |
|
||||
| slot="default" (for customize input element) | customize input element | HTMLInputElement / HTMLTextAreaElement | `<Input />` | |
|
||||
| dataSource | Data source for autocomplete | slot \| [DataSourceItemType](https://github.com/vueComponent/ant-design-vue/blob/724d53b907e577cf5880c1e6742d4c3f924f8f49/components/auto-complete/index.vue#L9)\[] | | |
|
||||
| dropdownMenuStyle | additional style applied to dropdown menu | object | | 1.5.0 |
|
||||
| defaultActiveFirstOption | Whether active first option by default | boolean | true | |
|
||||
| defaultValue | Initial selected option. | string\|string\[]\| - | |
|
||||
| disabled | Whether disabled select | boolean | false | |
|
||||
| filterOption | If true, filter options by input, if function, filter options against it. The function will receive two arguments, `inputValue` and `option`, if the function returns `true`, the option will be included in the filtered set; Otherwise, it will be excluded. | boolean or function(inputValue, option) | true | |
|
||||
| optionLabelProp | Which prop value of option will render as content of select. | string | `children` | |
|
||||
| placeholder | placeholder of input | string | - | |
|
||||
| value(v-model) | selected option | string\|string\[]\|{ key: string, label: string\|vNodes }\|Array<{ key: string, label: string\|vNodes }> | - | |
|
||||
| defaultOpen | Initial open state of dropdown | boolean | - | |
|
||||
| open | Controlled open state of dropdown | boolean | - | |
|
||||
|
||||
### events
|
||||
|
||||
| Events Name | Description | Arguments | Version |
|
||||
| --- | --- | --- | --- |
|
||||
| change | Called when select an option or input value change, or value of input is changed | function(value) | |
|
||||
| blur | Called when leaving the component. | function() | |
|
||||
| focus | Called when entering the component | function() | |
|
||||
| search | Called when searching items. | function(value) | - | |
|
||||
| select | Called when a option is selected. param is option's value and option instance. | function(value, option) | |
|
||||
| dropdownVisibleChange | Call when dropdown open | function(open) | |
|
||||
|
||||
## Methods
|
||||
|
||||
| Name | Description | Version |
|
||||
| ------- | ------------ | ------- |
|
||||
| blur() | remove focus | |
|
||||
| focus() | get focus | |
|
|
@ -0,0 +1,41 @@
|
|||
## API
|
||||
|
||||
```html
|
||||
<a-auto-complete :dataSource="dataSource" />
|
||||
```
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| allowClear | 支持清除, 单选模式有效 | boolean | false | |
|
||||
| autoFocus | 自动获取焦点 | boolean | false | |
|
||||
| backfill | 使用键盘选择选项的时候把选中项回填到输入框中 | boolean | false | |
|
||||
| slot="default" (自定义输入框) | 自定义输入框 | HTMLInputElement / HTMLTextAreaElement | `<Input />` | |
|
||||
| dataSource | 自动完成的数据源 | slot \| [DataSourceItemType](https://github.com/vueComponent/ant-design-vue/blob/724d53b907e577cf5880c1e6742d4c3f924f8f49/components/auto-complete/index.vue#L9)\[] | | |
|
||||
| dropdownMenuStyle | dropdown 菜单自定义样式 | object | | 1.5.0 |
|
||||
| defaultActiveFirstOption | 是否默认高亮第一个选项。 | boolean | true | |
|
||||
| defaultValue | 指定默认选中的条目 | string\|string\[]\| 无 | |
|
||||
| disabled | 是否禁用 | boolean | false | |
|
||||
| filterOption | 是否根据输入项进行筛选。当其为一个函数时,会接收 `inputValue` `option` 两个参数,当 `option` 符合筛选条件时,应返回 `true`,反之则返回 `false`。 | boolean or function(inputValue, option) | true | |
|
||||
| optionLabelProp | 回填到选择框的 Option 的属性值,默认是 Option 的子元素。比如在子元素需要高亮效果时,此值可以设为 `value`。 | string | `children` | |
|
||||
| placeholder | 输入框提示 | string \| slot | - | |
|
||||
| value(v-model) | 指定当前选中的条目 | string\|string\[]\|{ key: string, label: string\|vNodes }\|Array<{ key: string, label: string\|vNodes }> | 无 | |
|
||||
| defaultOpen | 是否默认展开下拉菜单 | boolean | - | |
|
||||
| open | 是否展开下拉菜单 | boolean | - | |
|
||||
|
||||
### 事件
|
||||
|
||||
| 事件名称 | 说明 | 回调参数 | 版本 |
|
||||
| --- | --- | --- | --- |
|
||||
| change | 选中 option,或 input 的 value 变化时,调用此函数 | function(value) |
|
||||
| blur | 失去焦点时的回调 | function() |
|
||||
| focus | 获得焦点时的回调 | function() |
|
||||
| search | 搜索补全项的时候调用 | function(value) |
|
||||
| select | 被选中时调用,参数为选中项的 value 值 | function(value, option) |
|
||||
| dropdownVisibleChange | 展开下拉菜单的回调 | function(open) |
|
||||
|
||||
## 方法
|
||||
|
||||
| 名称 | 描述 | 版本 |
|
||||
| ------- | -------- | ---- |
|
||||
| blur() | 移除焦点 |
|
||||
| focus() | 获取焦点 |
|
|
@ -0,0 +1,22 @@
|
|||
<cn>
|
||||
#### 带徽标的头像
|
||||
通常用于消息提示。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### With Badge
|
||||
Usually used for reminders and notifications.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<span style="margin-right:24px">
|
||||
<a-badge :count="1"><a-avatar shape="square" icon="user"/></a-badge>
|
||||
</span>
|
||||
<span>
|
||||
<a-badge dot><a-avatar shape="square" icon="user"/></a-badge>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
```
|
|
@ -0,0 +1,29 @@
|
|||
<cn>
|
||||
#### 基本
|
||||
头像有三种尺寸,两种形状可选。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### basic
|
||||
Three sizes and two shapes are available.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<div>
|
||||
<a-avatar :size="64" icon="user" />
|
||||
<a-avatar size="large" icon="user" />
|
||||
<a-avatar icon="user" />
|
||||
<a-avatar size="small" icon="user" />
|
||||
</div>
|
||||
<br />
|
||||
<div>
|
||||
<a-avatar shape="square" :size="64" icon="user" />
|
||||
<a-avatar shape="square" size="large" icon="user" />
|
||||
<a-avatar shape="square" icon="user" />
|
||||
<a-avatar shape="square" size="small" icon="user" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
```
|
|
@ -0,0 +1,49 @@
|
|||
<cn>
|
||||
#### 自动调整字符大小
|
||||
对于字符型的头像,当字符串较长时,字体大小可以根据头像宽度自动调整。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Autoset Font Size
|
||||
For letter type Avatar, when the letters are too long to display, the font size can be automatically adjusted according to the width of the Avatar.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<a-avatar
|
||||
shape="square"
|
||||
size="large"
|
||||
:style="{ backgroundColor: color, verticalAlign: 'middle' }"
|
||||
>
|
||||
{{ avatarValue }}
|
||||
</a-avatar>
|
||||
<a-button
|
||||
size="small"
|
||||
:style="{ marginLeft: 16, verticalAlign: 'middle' }"
|
||||
@click="changeValue"
|
||||
>
|
||||
改变
|
||||
</a-button>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
const UserList = ['U', 'Lucy', 'Tom', 'Edward'];
|
||||
const colorList = ['#f56a00', '#7265e6', '#ffbf00', '#00a2ae'];
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
avatarValue: UserList[0],
|
||||
color: colorList[0],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
changeValue() {
|
||||
const index = UserList.indexOf(this.avatarValue);
|
||||
this.avatarValue = index < UserList.length - 1 ? UserList[index + 1] : UserList[0];
|
||||
this.color = index < colorList.length - 1 ? colorList[index + 1] : colorList[0];
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
```
|
|
@ -0,0 +1,47 @@
|
|||
<script>
|
||||
import Basic from './basic';
|
||||
import Badge from './badge';
|
||||
import Type from './type';
|
||||
import Dynamic from './dynamic';
|
||||
import CN from '../index.zh-CN.md';
|
||||
import US from '../index.en-US.md';
|
||||
|
||||
const md = {
|
||||
cn: `# Avatar头像
|
||||
用来代表用户或事物,支持图片、图标或字符展示。
|
||||
## 设计师专属
|
||||
安装 [Kitchen Sketch 插件 <EFBFBD>](https://kitchen.alipay.com),一键填充高逼格头像和文本.
|
||||
|
||||
## 代码演示`,
|
||||
us: `# Avatar
|
||||
Avatars can be used to represent people or objects. It supports images, 'Icon's, or letters.
|
||||
## Examples
|
||||
`,
|
||||
};
|
||||
export default {
|
||||
category: 'Components',
|
||||
subtitle: '头像',
|
||||
type: 'Data Display',
|
||||
zhType: '数据展示',
|
||||
title: 'Avatar',
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<md cn={md.cn} us={md.us} />
|
||||
<demo-sort>
|
||||
<Basic />
|
||||
<Badge />
|
||||
<Type />
|
||||
<Dynamic />
|
||||
</demo-sort>
|
||||
<api>
|
||||
<template slot="cn">
|
||||
<CN />
|
||||
</template>
|
||||
<US />
|
||||
</api>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,27 @@
|
|||
<cn>
|
||||
#### 类型
|
||||
支持三种类型:图片、Icon 以及字符,其中 Icon 和字符型可以自定义图标颜色及背景色。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Type
|
||||
Image, Icon and letter are supported, and the latter two kinds avatar can have custom colors and background colors.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<a-avatar icon="user" />
|
||||
<a-avatar>
|
||||
<a-icon slot="icon" type="user" />
|
||||
</a-avatar>
|
||||
<a-avatar>U</a-avatar>
|
||||
<a-avatar>USER</a-avatar>
|
||||
<a-avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
|
||||
<a-avatar style="color: #f56a00; backgroundColor: #fde3cf">
|
||||
U
|
||||
</a-avatar>
|
||||
<a-avatar style="backgroundColor:#87d068" icon="user" />
|
||||
</div>
|
||||
</template>
|
||||
```
|
|
@ -0,0 +1,11 @@
|
|||
## API
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
| --- | --- | --- | --- |
|
||||
| icon | the `Icon` type for an icon avatar, see `Icon` Component | string | - |
|
||||
| shape | the shape of avatar | `circle` \| `square` | `circle` |
|
||||
| size | the size of the avatar | number \| string: `large` `small` `default` | `default` |
|
||||
| src | the address of the image for an image avatar | string | - |
|
||||
| srcSet | a list of sources to use for different screen resolutions | string | - |
|
||||
| alt | This attribute defines the alternative text describing the image | string | - |
|
||||
| loadError | handler when img load error, return false to prevent default fallback behavior | () => boolean | - |
|
|
@ -0,0 +1,11 @@
|
|||
## API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| icon | 设置头像的图标类型,可设为 Icon 的 `type` 或 VNode | string \| VNode \| slot | - |
|
||||
| shape | 指定头像的形状 | Enum{ 'circle', 'square' } | `circle` |
|
||||
| size | 设置头像的大小 | number \| Enum{ 'large', 'small', 'default' } | `default` |
|
||||
| src | 图片类头像的资源地址 | string | - |
|
||||
| srcSet | 设置图片类头像响应式资源地址 | string | - |
|
||||
| alt | 图像无法显示时的替代文本 | string | - |
|
||||
| loadError | 图片加载失败的事件,返回 false 会关闭组件默认的 fallback 行为 | () => boolean | - |
|
|
@ -0,0 +1,20 @@
|
|||
<cn>
|
||||
#### 基本
|
||||
最简单的用法。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### basic
|
||||
The most basic usage.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<a-back-top />
|
||||
Scroll down to see the bottom-right
|
||||
<strong style="color: rgba(64, 64, 64, 0.6)"> gray </strong>
|
||||
button.
|
||||
</div>
|
||||
</template>
|
||||
```
|
|
@ -0,0 +1,39 @@
|
|||
<cn>
|
||||
#### 自定义样式
|
||||
可以自定义回到顶部按钮的样式,限制宽高:`40px * 40px`。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Custom style
|
||||
You can customize the style of the button, just note the size limit: no more than `40px * 40px`.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div id="components-back-top-demo-custom">
|
||||
<a-back-top>
|
||||
<div class="ant-back-top-inner">
|
||||
UP
|
||||
</div>
|
||||
</a-back-top>
|
||||
Scroll down to see the bottom-right
|
||||
<strong style="color: #1088e9"> blue </strong>
|
||||
button.
|
||||
</div>
|
||||
</template>
|
||||
<style scoped>
|
||||
#components-back-top-demo-custom .ant-back-top {
|
||||
bottom: 100px;
|
||||
}
|
||||
#components-back-top-demo-custom .ant-back-top-inner {
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
line-height: 40px;
|
||||
border-radius: 4px;
|
||||
background-color: #1088e9;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
}
|
||||
</style>
|
||||
```
|
|
@ -0,0 +1,43 @@
|
|||
<script>
|
||||
import Basic from './basic';
|
||||
import Custom from './custom';
|
||||
import CN from '../index.zh-CN.md';
|
||||
import US from '../index.en-US.md';
|
||||
const md = {
|
||||
cn: `# BackTop 回到顶部
|
||||
返回页面顶部的操作按钮。
|
||||
## 何时使用
|
||||
- 当页面内容区域比较长时;
|
||||
- 当用户需要频繁返回顶部查看相关内容时。
|
||||
## 代码演示`,
|
||||
us: `# BackTop
|
||||
\`BackTop\` makes it easy to go back to the top of the page.
|
||||
## When To Use
|
||||
- When the page content is very long.
|
||||
- When you need to go back to the top very frequently in order to view the contents.
|
||||
## Examples
|
||||
`,
|
||||
};
|
||||
export default {
|
||||
category: 'Components',
|
||||
type: 'Other',
|
||||
zhType: '其他',
|
||||
subtitle: '回到顶部',
|
||||
title: 'BackTop',
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<md cn={md.cn} us={md.us} />
|
||||
<demo-sort>
|
||||
<Basic />
|
||||
<Custom />
|
||||
</demo-sort>
|
||||
<api>
|
||||
<CN slot="cn" />
|
||||
<US />
|
||||
</api>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,16 @@
|
|||
## API
|
||||
|
||||
> The distance to the bottom is set to `50px` by default, which is overridable.
|
||||
>
|
||||
> If you decide to use custom styles, please note the size limit: no more than `40px * 40px`.
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| target | specifies the scrollable area dom node | () => HTMLElement | () => window | |
|
||||
| visibilityHeight | the `BackTop` button will not show until the scroll height reaches this value | number | 400 | |
|
||||
|
||||
### events
|
||||
|
||||
| Events Name | Description | Arguments | Version |
|
||||
| --- | --- | --- | --- |
|
||||
| click | a callback function, which can be executed when you click the button | Function | |
|
|
@ -0,0 +1,16 @@
|
|||
## API
|
||||
|
||||
> 有默认样式,距离底部 `50px`,可覆盖。
|
||||
>
|
||||
> 自定义样式宽高不大于 40px \* 40px。
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| target | 设置需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 | Function | () => window | |
|
||||
| visibilityHeight | 滚动高度达到此参数值才出现 `BackTop` | number | 400 | |
|
||||
|
||||
### 事件
|
||||
|
||||
| 事件名称 | 说明 | 回调参数 | 版本 |
|
||||
| -------- | ------------------ | -------- | ---- |
|
||||
| click | 点击按钮的回调函数 | Function | |
|
|
@ -0,0 +1,26 @@
|
|||
<cn>
|
||||
#### 基本
|
||||
简单的徽章展示,当 `count` 为 `0` 时,默认不显示,但是可以使用 `showZero` 修改为显示。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### basic
|
||||
Simplest Usage. Badge will be hidden when `count` is `0`, but we can use `showZero` to show it.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<a-badge count="5">
|
||||
<a href="#" class="head-example" />
|
||||
</a-badge>
|
||||
<a-badge count="0" show-zero>
|
||||
<a href="#" class="head-example" />
|
||||
</a-badge>
|
||||
<a-badge>
|
||||
<a-icon slot="count" type="clock-circle" style="color: #f5222d" />
|
||||
<a href="#" class="head-example" />
|
||||
</a-badge>
|
||||
</div>
|
||||
</template>
|
||||
```
|
|
@ -0,0 +1,57 @@
|
|||
<cn>
|
||||
#### 动态
|
||||
展示动态变化的效果。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Dynamic
|
||||
The count will be animated as it changes.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<div>
|
||||
<a-badge :count="count">
|
||||
<a href="#" class="head-example" />
|
||||
</a-badge>
|
||||
<a-button-group>
|
||||
<a-button @click="decline">
|
||||
<a-icon type="minus" />
|
||||
</a-button>
|
||||
<a-button @click="increase">
|
||||
<a-icon type="plus" />
|
||||
</a-button>
|
||||
</a-button-group>
|
||||
</div>
|
||||
<div style="margin-top: 10px">
|
||||
<a-badge :dot="show">
|
||||
<a href="#" class="head-example" />
|
||||
</a-badge>
|
||||
<a-switch v-model="show" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
count: 5,
|
||||
show: true,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
decline() {
|
||||
let count = this.count - 1;
|
||||
if (count < 0) {
|
||||
count = 0;
|
||||
}
|
||||
this.count = count;
|
||||
},
|
||||
increase() {
|
||||
this.count++;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
```
|
|
@ -0,0 +1,60 @@
|
|||
<cn>
|
||||
#### 多彩徽标
|
||||
1.5.0 后新增。我们添加了多种预设色彩的徽标样式,用作不同场景使用。如果预设值不能满足你的需求,可以设置为具体的色值。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Colorful Badge
|
||||
New feature after 3.16.0. We preset a series of colorful Badge styles for use in different situations. You can also set it to a hex color string for custom color.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<h4 style="margin-bottom: 16px">
|
||||
Presets:
|
||||
</h4>
|
||||
<div>
|
||||
<div v-for="color in colors" :key="color">
|
||||
<a-badge :color="color" :text="color" />
|
||||
</div>
|
||||
</div>
|
||||
<h4 style="margin: 16px 0">
|
||||
Custom:
|
||||
</h4>
|
||||
<div>
|
||||
<a-badge color="#f50" text="#f50" />
|
||||
<br />
|
||||
<a-badge color="#2db7f5" text="#2db7f5" />
|
||||
<br />
|
||||
<a-badge color="#87d068" text="#87d068" />
|
||||
<br />
|
||||
<a-badge color="#108ee9" text="#108ee9" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
const colors = [
|
||||
'pink',
|
||||
'red',
|
||||
'yellow',
|
||||
'orange',
|
||||
'cyan',
|
||||
'green',
|
||||
'blue',
|
||||
'purple',
|
||||
'geekblue',
|
||||
'magenta',
|
||||
'volcano',
|
||||
'gold',
|
||||
'lime',
|
||||
];
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
colors,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
```
|
|
@ -0,0 +1,34 @@
|
|||
<cn>
|
||||
#### 讨嫌的小红点
|
||||
没有具体的数字。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Red badge
|
||||
This will simply display a red badge, without a specific count.
|
||||
If count equals 0, it won't display the dot.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div id="components-badge-demo-dot">
|
||||
<a-badge dot>
|
||||
<a-icon type="notification" />
|
||||
</a-badge>
|
||||
<a-badge :count="0" dot>
|
||||
<a-icon type="notification" />
|
||||
</a-badge>
|
||||
<a-badge dot>
|
||||
<a href="#">Link something</a>
|
||||
</a-badge>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped>
|
||||
#components-badge-demo-dot .anticon-notification {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
line-height: 16px;
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
```
|
|
@ -0,0 +1,74 @@
|
|||
<script>
|
||||
import Basic from './basic.md';
|
||||
import NoWapper from './no-wrapper';
|
||||
import Dot from './dot';
|
||||
import Change from './change';
|
||||
import Overflow from './overflow';
|
||||
import Status from './status';
|
||||
import Title from './title';
|
||||
import Colors from './colors';
|
||||
|
||||
import CN from './../index.zh-CN.md';
|
||||
import US from './../index.en_US.md';
|
||||
|
||||
const md = {
|
||||
cn: `# Badge徽标数
|
||||
图标右上角的圆形徽标数字。
|
||||
## 何时使用
|
||||
一般出现在通知图标或头像的右上角,用于显示需要处理的消息条数,通过醒目视觉形式吸引用户处理。
|
||||
## 代码演示
|
||||
`,
|
||||
us: `# Badge
|
||||
Small numerical value or status descriptor for UI elements.
|
||||
## When To Use
|
||||
Badge normally appears in proximity to notifications or user avatars with eye-catching appeal, typically displaying unread messages count.
|
||||
## Examples
|
||||
`,
|
||||
};
|
||||
|
||||
export default {
|
||||
category: 'Components',
|
||||
subtitle: '徽标数',
|
||||
type: 'Data Display',
|
||||
zhType: '数据展示',
|
||||
title: 'Badge',
|
||||
render() {
|
||||
return (
|
||||
<div id="components-badge-demo">
|
||||
<md cn={md.cn} us={md.us} />
|
||||
<demo-sort>
|
||||
<Basic />
|
||||
<NoWapper />
|
||||
<Overflow />
|
||||
<Dot />
|
||||
<Status />
|
||||
<Change />
|
||||
<Title />
|
||||
<Colors />
|
||||
</demo-sort>
|
||||
<api>
|
||||
<CN slot="cn" />
|
||||
<US />
|
||||
</api>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#components-badge-demo .ant-badge:not(.ant-badge-not-a-wrapper) {
|
||||
margin-right: 20px;
|
||||
}
|
||||
#components-badge-demo .head-example {
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
border-radius: 4px;
|
||||
background: #eee;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
#components-badge-demo .ant-badge-not-a-wrapper:not(.ant-badge-status) {
|
||||
margin-right: 8px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,19 @@
|
|||
<cn>
|
||||
#### 可点击
|
||||
用 a 标签进行包裹即可。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Clickable
|
||||
The badge can be wrapped with `a` tag to make it linkable.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<a href="#">
|
||||
<a-badge count="5">
|
||||
<span class="head-example" />
|
||||
</a-badge>
|
||||
</a>
|
||||
</template>
|
||||
```
|
|
@ -0,0 +1,27 @@
|
|||
<cn>
|
||||
#### 独立使用
|
||||
不包裹任何元素即是独立使用,可自定样式展现。
|
||||
在右上角的 badge 则限定为红色。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Standalone
|
||||
Used in standalone when children is empty.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<a-badge count="25" />
|
||||
<a-badge
|
||||
count="4"
|
||||
:number-style="{
|
||||
backgroundColor: '#fff',
|
||||
color: '#999',
|
||||
boxShadow: '0 0 0 1px #d9d9d9 inset',
|
||||
}"
|
||||
/>
|
||||
<a-badge count="109" :number-style="{ backgroundColor: '#52c41a' }" />
|
||||
</div>
|
||||
</template>
|
||||
```
|
|
@ -0,0 +1,28 @@
|
|||
<cn>
|
||||
#### 封顶数字
|
||||
超过 `overflowCount` 的会显示为 `${overflowCount}+`,默认的 `overflowCount` 为 `99`。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Overflow Count
|
||||
`${overflowCount}+` is displayed when count is larger than `overflowCount`. The default value of `overflowCount` is `99`.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<a-badge :count="99">
|
||||
<a href="#" class="head-example" />
|
||||
</a-badge>
|
||||
<a-badge :count="100">
|
||||
<a href="#" class="head-example" />
|
||||
</a-badge>
|
||||
<a-badge :count="99" :overflow-count="10">
|
||||
<a href="#" class="head-example" />
|
||||
</a-badge>
|
||||
<a-badge :count="1000" :overflow-count="999">
|
||||
<a href="#" class="head-example" />
|
||||
</a-badge>
|
||||
</div>
|
||||
</template>
|
||||
```
|
|
@ -0,0 +1,31 @@
|
|||
<cn>
|
||||
#### 状态点
|
||||
用于表示状态的小圆点。
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Status
|
||||
Standalone badge with status.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<a-badge status="success" />
|
||||
<a-badge status="error" />
|
||||
<a-badge status="default" />
|
||||
<a-badge status="processing" />
|
||||
<a-badge status="warning" />
|
||||
<br />
|
||||
<a-badge status="success" text="Success" />
|
||||
<br />
|
||||
<a-badge status="error" text="Error" />
|
||||
<br />
|
||||
<a-badge status="default" text="Default" />
|
||||
<br />
|
||||
<a-badge status="processing" text="Processing" />
|
||||
<br />
|
||||
<a-badge status="warning" text="warning" />
|
||||
</div>
|
||||
</template>
|
||||
```
|
|
@ -0,0 +1,31 @@
|
|||
<cn>
|
||||
#### 自定义标题
|
||||
设置鼠标放在状态点上时显示的文字
|
||||
</cn>
|
||||
|
||||
<us>
|
||||
#### Title
|
||||
The badge will display `title` when hovered over, instead of `count`.
|
||||
</us>
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div id="components-badge-demo-title">
|
||||
<a-badge :count="5" title="Custom hover text">
|
||||
<a href="#" class="head-example" />
|
||||
</a-badge>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped>
|
||||
#components-badge-demo-title .ant-badge:not(.ant-badge-status) {
|
||||
margin-right: 20px;
|
||||
}
|
||||
.head-example {
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
border-radius: 4px;
|
||||
background: #eee;
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
```
|
|
@ -0,0 +1,24 @@
|
|||
## API
|
||||
|
||||
```html
|
||||
<a-badge :count="5">
|
||||
<a href="#" class="head-example" />
|
||||
</a-badge>
|
||||
```
|
||||
|
||||
```html
|
||||
<a-badge :count="5" />
|
||||
```
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| color | Customize Badge dot color | string | - | 1.5.0 |
|
||||
| count | Number to show in badge | number\|string \| slot | | |
|
||||
| dot | Whether to display a red dot instead of `count` | boolean | `false` | |
|
||||
| offset | set offset of the badge dot, like [x, y] | [number\|string, number\|string] | - | |
|
||||
| overflowCount | Max count to show | number | 99 | |
|
||||
| showZero | Whether to show badge when `count` is zero | boolean | `false` | |
|
||||
| status | Set Badge as a status dot | `success` \| `processing` \| `default` \| `error` \| `warning` | `''` | |
|
||||
| text | If `status` is set, `text` sets the display text of the status `dot` | string | `''` | |
|
||||
| numberStyle | sets the display style of the status `dot` | object | '' | |
|
||||
| title | Text to show when hovering over the badge | string | `count` | |
|
|
@ -0,0 +1,24 @@
|
|||
## API
|
||||
|
||||
```html
|
||||
<a-badge :count="5">
|
||||
<a href="#" class="head-example" />
|
||||
</a-badge>
|
||||
```
|
||||
|
||||
```html
|
||||
<a-badge :count="5" />
|
||||
```
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| color | 自定义小圆点的颜色 | string | - | 1.5.0 |
|
||||
| count | 展示的数字,大于 overflowCount 时显示为 `${overflowCount}+`,为 0 时隐藏 | number \| string \| slot | | |
|
||||
| dot | 不展示数字,只有一个小红点 | boolean | false | |
|
||||
| offset | 设置状态点的位置偏移,格式为 [x, y] | [number\|string, number\|string] | - | |
|
||||
| overflowCount | 展示封顶的数字值 | number | 99 | |
|
||||
| showZero | 当数值为 0 时,是否展示 Badge | boolean | false | |
|
||||
| status | 设置 Badge 为状态点 | Enum{ 'success', 'processing, 'default', 'error', 'warning' } | '' | |
|
||||
| text | 在设置了 `status` 的前提下有效,设置状态点的文本 | string | '' | |
|
||||
| numberStyle | 设置状态点的样式 | object | '' | |
|
||||
| title | 设置鼠标放在状态点上时显示的文字 | string | `count` | |
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue