1611494700
@ vue / cli 4.5.10
Custom: default+ts+unit test+no class-style+eslint+prettier+jest
Install Prettier-Code formatter vscode plugin
Create .prettierrc
{
"semi": false,
"singleQuote": true,
"arrowParens": "always",
"trailingComma": "all"
}
Configuration setting: Format On Save, it is recommended to save as workspace configuration
Please check the latest https://github.com/vuejs/rfcs/pull/227
<script setup>
// imported components are also directly usable in template
import Foo from './Foo.vue'
import { ref } from 'vue'
// write Composition API code just like in a normal setup()
// but no need to manually return everything
const count = ref(0)
const inc = () => {
count.value++
}
</script>
<template>
<Foo :count="count" @click="inc" />
</template>
Compiled Output
<script setup>
import Foo from './Foo.vue'
import { ref } from 'vue'
export default {
setup() {
const count = ref(1)
const inc = () => {
count.value++
}
return {
Foo , // see note below
count ,
inc ,
}
} ,
}
</script>
<template>
<Foo :count="count" @click="inc" />
</template>
Note: the SFC compiler also extracts binding metadata from <script setup>
and use it during template compilation. This is why the template can use Foo
as a component here even though it’s returned from setup()
instead of registered via components
option.
Declaring Props and Emits
<script setup>
import { defineProps, defineEmit } from 'vue'
// expects props options
const props = defineProps({
foo: String,
})
// expects emits options
const emit = defineEmits(['update', 'delete'])
</script>
####### defineConponent function
Mainly returns the type definition of the component, the specific implementation is very simple
// vue-next/package/runtime-core/src/apiDefineComponent.ts
// various definitions
...
// implementation, close to no-op
export function defineComponent(options: unknown) {
return isFunction(options) ? { setup: options, name: options.name } : options
}
Define props
...
<script lang="ts">
import { defineComponent, PropType } from "vue";
export default defineComponent ( {
name : "HelloWorld" ,
props : {
// shorthand
msg : String ,
// complete
name : {
type : String as PropType < string > ,
required : true ,
} ,
} ,
} ) ;
</ script >
The pit that require does not work when extracting common props definitions
...
<script lang="ts">
import { defineComponent, PropType } from "vue";
const PropsType = {
msg : String ,
name : {
type : String as PropType < string > ,
// required
required : true ,
} ,
// solution: add as const, manually tell ts that this object is read-only
} as const
export default defineComponent ( {
name : "HelloWorld" ,
props : PropsType ,
mounted ( ) {
// The name prompt here may also be undefined
// Reason: {required: true} here is not tried correctly because ts does not know This object is read-only, and only read-only can allow {required: true} to be tested correctly by ts
// View the comment mentioned in the source defineComponent definition:
// the Readonly constraint allows TS to treat the type of { required: true} as constant instead of boolean.
// PropsOptions extends Readonly<ComponentPropsOptions>,
this . name
}
} ) ;
</ script >
Equivalent to createElement in React
// main.ts
import { createApp, defineComponent, h } from "vue";
// import App from "./App.vue";
import HelloWorld from './components
/
HelloWorld.vue ' // ts verification does not pass the transposition of require's writing // import img from'./assets
/logo.png
' // eslint error: require is not allowed, cancel the current line Eslint check const img = require ( './assets/logo.png' ) // eslint-disable-line
// Use the h function to simulate app files (sfc: single file component) to generate vue components. App files are almost compiled like this
const App = defineComponent ( {
render ( ) {
// h is equivalent to createElement in React for creating nodes
/ / Native nodes use strings
// Parameters: node type, attributes, child nodes
return h ( 'div' , { id : 'app' } , [
h ( 'img' , {
alt : "Vue logo" ,
// image It can’t be displayed, because the image address vue-loader in the template will be addressed. Here you need to import the image yourself
// src: "./assets/logo.png",
src : img ,
}),
h(HelloWorld, {
msg: "Welcome to Your Vue.js + TypeScript App",
name: "naxies",
})
])
}
})
createApp(App).mount("#app");
In fact, it is the package of createVNode. It is also possible to replace the following code h with createVNode
// vue-next/package/runtime-core/src/apiDefineComponent.ts
// various definitions
...
// Actual implementation
export function h(type: any, propsOrChildren?: any, children?: any): VNode {
const l = arguments.length
if (l === 2) {
if (isObject(propsOrChildren) && !isArray(propsOrChildren)) {
// single vnode without props
if (isVNode(propsOrChildren)) {
return createVNode(type, null, [propsOrChildren])
}
// props without children
return createVNode(type, propsOrChildren)
} else {
// omit props
return createVNode(type, null, propsOrChildren)
}
} else {
if (l > 3) {
children = Array.prototype.slice.call(arguments, 2)
} else if (l === 3 && isVNode(children)) {
children = [children]
}
return createVNode(type, propsOrChildren, children)
}
}
In addition to the three parameters like h, the createVNode parameters also have some optimized parameters, and vue-loader will make some optimizations through these
// App.vue
< template >
< img alt =" Vue logo " src =" ./assets/logo.png " />
< HelloWorld msg =" Welcome to Your Vue.js + TypeScript App " name =" naxies " / >
< h2 > {{state.age}}~ </ h2 >
<!-- It is not necessary. The value is because sfc will judge whether it is a ref currently -->
< h2 > ref {{ageRef}}~ </ h2 >
< h2 >computedAgeRef {{computedAgeRef}} ~ </ h2>
</template>
<script lang="ts">
import { defineComponent, reactive, ref, computed, watchEffect } from 'vue'
import HelloWorld from './components/HelloWorld.vue'
export default defineComponent ( {
name : 'App' ,
components : {
HelloWorld ,
} ,
mounted ( ) {
// The ref in this is a proxy or you don't need to write .value, it will automatically determine the
console . log ( this . ageRef )
} ,
// and the same data only once at initialization
Setup ( the props , { slots , attrs , EMIT } ) {
// returns: sfc returns the object
const State = reactive({
age: 18
})
setInterval(() => {
state.age += 1
}, 1000)
// Return {value: xxx} structure object, value is
const ageRef = ref ( 18 )
setInterval ( ( ) => {
ageRef . Value += 1
} , 1000 )
// computed
const computedAgeRef = computed(() => {
return ageRef.value + 2
})
// watchEffect: will be executed when all reactive function references and changes to ref
watchEffect ( ( ) => {
// assignment will be executed each time ageRef
Console . Log ( ageRef . Value ) ;
} )
// Can't use {...state} to return, what is returned is not a responsive
return {
state ,
ageRef ,
computedAgeRef
}
}
})
</script>
Setup returns the usage of render function
// main.ts
import { createApp, defineComponent, h, reactive, ref } from "vue";
// import App from "./App.vue";
import HelloWorld from './components/HelloWorld.vue'
const img = require('./assets/logo.png') // eslint-disable-line
// setup returns the writing of the render function =======================
const App = defineComponent ( {
setup ( ) {
// You can also write other codes here
// Both reactive and ref are used to define reactive data. It is more recommended to define complex data types. ref is more recommended to define basic types. It can be simply understood that ref is a secondary packaging of reactive and access to data defined by ref One more time. value
const state = reactive ( {
age : 18
} )
const ageRef = ref(18)
setInterval(() => {
ageRef.value += 1
}, 1000)
// Return to the render function
return ( ) => {
// Put this sentence outside the render function and the page display will not dynamically change according to the timer
// Because setup is only executed once, ageRefNum is always the initialized value
// reactive or The change of ref will re-execute this render function to form a dom tree, so the final value reading needs to be executed in render
const ageRefNum = ageRef . value
return h ( 'div' , { id : 'app' } , [
h ( 'img' , {
alt : "Vue logo" ,
src : img ,
} ) ,
h ( HelloWorld, {
msg : "Welcome to Your Vue.js + TypeScript App" ,
name : "naxies" ,
} ) ,
// You can get the value of the closure
h ( 'h2' , state . age ) ,
h ( 'h2' , 'ageRef ' + ageRefNum )
] )
}
}
} )
createApp(App).mount("#app");
// watching a getter
const state = reactive({ count: 0 })
watch(
() => state.count,
(count, prevCount) => {
/* ... */
}
)
// directly watching a ref
const count = ref(0)
watch(count, (count, prevCount) => {
/* ... */
})
// A watcher can also watch multiple sources at the same time using an array
const firstName = ref('');
const lastName = ref('');
watch([firstName, lastName], (newValues, prevValues) => {
console.log(newValues, prevValues);
})
firstName.value = "John"; // logs: ["John",""] ["", ""]
lastName.value = "Smith"; // logs: ["John", "Smith"] ["John", ""]
https://github.com/vuejs/jsx-next
Install the plugin with:
npm install @vue/babel-plugin-jsx -D
Then add the plugin to .babelrc:
{
"plugins": ["@vue/babel-plugin-jsx"]
}
Advantages: ts can be verified at compile time (ts cannot recognize the type exported in the vue file, it is a unified type), flexible to use (return and reuse html fragments through functions, etc.), and can use instructions
Used to define json data, verify data, multi-terminal universal
Official draft: json-schema.org
js library of json-schema, https://ajv.js.org/
// or ESM/TypeScript import
// import Ajv from "ajv"
// Node.js require:
const Ajv = require("ajv").default
const addFormats = require("ajv-formats")
const localize = require('ajv-i18n');
// Simple
let schema = {
type : 'string' ,
minLength : 10 ,
}
// More complicated
schema = {
type : 'object' ,
properties : {
name : {
type : 'string' ,
maxLength : 10 ,
} ,
age : {
type : 'number' ,
} ,
pets : {
type :'array' ,
// The first way of defining
// items: {
// type:'string',
// },
// The second kind of
items : [
{ type : 'string' , } ,
{ type : 'number ' , }
]
} ,
email : {
type : 'string' ,
format : 'email' ,
} ,
testFormatProperty : {
type : 'string' ,
format : 'testFormat' ,
} ,
testKeywordProperty : {
type : 'string' ,
testKeyword : 'testKeyword' ,
// provided by ajv-errors
// Any rule error will only display this error message
// errorMessage:'You are wrong again! ',
// Distinguish keyword setting error message
errorMessage : {
type : 'What you passed is not a string, don't you even recognize a string! ' ,
testKeyword : 'Guess where you are wrong again! '
} ,
}
} ,
required : [ 'name' , 'age' ] ,
}
let data = 'naixes'
data = {
name: 'naixes',
age: 18,
pets: ['egg core', 2],
testFormatProperty: 'testFormat',
testKeywordProperty: 'hello!',
}
// To use ajv-errors, you need to pass in {allErrors: true}
const ajv = new Ajv ( { allErrors : true } ) // options can be passed, eg {allErrors: true}
// version 7 and above formats need to install a plug-in separately
addFormats ( ajv )
// 引入 ajv-errors 库
require ( 'ajv-errors' ) ( ajv )
// 定义 定义 format
ajv . addFormat ( 'testFormat' , ( data ) => {
return data === 'testFormat'
} )
// Custom keyword
ajv . addKeyword ( {
keyword : 'testKeyword' ,
// Method 1: Call when validate
// validate: xx = (schema, data) => {
// console.log('schema', schema,'data', data);
// // Custom error message, You can also use the library to customize error information
// xx.errors = [
// {
// keyword:'testKeyword',
// dataPath:'/testKeywordProperty',
// schemaPath:'#/properties/testKeywordProperty/testKeyword',
/ / params: {},
// message:'You are wrong! '
//}
//]
// return data.length === 3
// },
// Method 2: Call when compile
// compile: (sch, parentSchema) => {
// console.log('sch', sch,'parentSchema', parentSchema);
// // To return a function
// return () => true
// },
// // The schema of the value received by this keyword
// metaSchema: (),
// Method 3: Equivalent to combining multiple schema
macros : ( sch , parentSchema ) => {
// console.log('sch', sch,'parentSchema', parentSchema);
// To return a schema
return {
minLength : 10 ,
}
} ,
metaSchema : { } ,
// Will overwrite the custom error message in Method 1
errors : false ,
} )
const validate = ajv.compile(schema)
const valid = validate(data)
if (!valid) {
localize.zh(validate.errors)
console.log(validate.errors)
}
installation:npm i ajv
####### Formats
format: some commonly used validation rules, only for string and number types
installation:npm i ajv-formats
From version 7 Ajv does not include formats defined by JSON Schema specification - these and several other formats are provided by ajv-formats plugin.
To add all formats from this plugin:
import Ajv from "ajv"
import addFormats from "ajv-formats"
const ajv = new Ajv ( )
addFormats ( ajv )
Custom format
ajv.addFormat (name: string, format: Format): Ajv
type Format =
| true // to ignore this format (and pass validation)
| string // will be converted to RegExp
| RegExp
| (data: string) => boolean
| Object // format definition (see below and in types)
Add format to validate strings or numbers.
If object is passed it should have properties validate
, compare
and async
:
interface FormatDefinition { // actual type definition is more precise - see types.ts
validate: string | RegExp | (data: number | string) => boolean | Promise<boolean>
compare: (data1: string, data2: string): number // an optional function that accepts two strings
// and compares them according to the format meaning.
// This function is used with keywords `formatMaximum`/`formatMinimum`
// (defined in [ajv-keywords](https://github.com/ajv-validator/ajv-keywords) package).
// It should return `1` if the first value is bigger than the second value,
// `-1` if it is smaller and `0` if it is equal.
async?: true // if `validate` is an asynchronous function
type?: "string" | "number" // "string" is default. If data type is different, the validation will pass.
}
Formats can be also added via formats
option.
####### keywords
Four ways to customize keywords
ajv.addKeyword({
keyword: "constant",
validate: (schema, data) =>
typeof schema == "object" && schema !== null ? deepEqual(schema, data) : schema === data,
errors: false,
})
const schema = {
constant: 2,
}
const validate = ajv.compile(schema)
console.log(validate(2)) // true
console.log(validate(3)) // false
const schema = {
constant: {foo: "bar"},
}
const validate = ajv.compile(schema)
console.log(validate({foo: "bar"})) // true
console.log(validate({foo: "baz"})) // false
ajv.addKeyword({
keyword: "range",
type: "number",
compile([min, max], parentSchema) {
return parentSchema.exclusiveRange === true
? (data) => data > min && data < max
: (data) => data >= min && data <= max
},
errors: false,
metaSchema: {
// schema to validate keyword value
type: "array",
items: [{type: "number"}, {type: "number"}],
minItems: 2,
additionalItems: false,
},
})
const schema = {
range: [2, 4],
exclusiveRange: true,
}
const validate = ajv.compile(schema)
console.log(validate(2.01)) // true
console.log(validate(3.99)) // true
console.log(validate(2) ) // false
console . log ( validate ( 4 ) ) // false
ajv.addKeyword({
keyword: "range",
type: "number",
macro: ([minimum, maximum]) => ({minimum, maximum}), // schema with keywords minimum and maximum
// metaSchema: the same as in the example above
})
####### Error message
Display Chinese error message:
Install ajv-i18n
var Ajv = require('ajv'); // version >= 2.0.0
var localize = require('ajv-i18n');
// option `i18n` is required for this package to work
var ajv = Ajv({ allErrors: true });
var validate = ajv.compile(schema);
var valid = validate(data);
if (!valid) {
// ru for Russian
localize.ru(validate.errors);
// string with all errors and data paths
console.log(ajv.errorsText(validate.errors, { separator: '\n' }));
}
Custom error message
...
// Custom keyword
ajv . AddKeyword ( {
keyword : 'testKeyword' ,
// Method 1: When calls validate
validate : XX = ( Schema , Data ) => {
Console . Log ( 'Schema' , Schema , 'Data' , Data ) ;
// custom error message
XX . Errors = [
{
keyword : 'testKeyword' ,
dataPath : '/testKeywordProperty' ,
schemaPath : '#/properties/testKeywordProperty/testKeyword' ,
params : { },
message : 'You are wrong! '
}
]
return data . length === 3
} ,
// overrides custom error messages
// errors: false,
} )
. . .
: : Ajv-errors
const Ajv = require("ajv").default
const ajv = new Ajv({allErrors: true})
// Ajv option allErrors is required
require("ajv-errors")(ajv /*, {singleError: true} */)
const schema = {
type: "object",
required: ["foo"],
properties: {
foo: {type: "integer"},
},
additionalProperties: false,
errorMessage: "should be an object with an integer property foo only",
}
const validate = ajv.compile(schema)
console.log(validate({foo: "a", bar: 2})) // false
console.log(validate.errors) // processed errors
<JsonSchemaForm
schema={schema}
value={value}
locale={locale}
onChange={handleChange}
contextRef={someRef}
uiSchema={uiSchema}
></JsonSchemaForm>
json schema object, used to define the data, but also the basis for us to define the form
The data result of the form, you can change the value from the outside. When the form is edited, the onChange
value will be revealed through
It should be noted that because Vue uses variable data, if we change value
the object address every time the data changes , the entire form will need to be re-rendered, which will cause performance degradation. From a practical point of view, the internal modification of the value of the field of the object we passed in will basically not have any side effects, so we will use this method to implement it. In other words, if it value
is an object, then JsonSchemaForm
the value modified from the inside will not change the value
object itself. We will still trigger onChange
, because the user may need to perform some actions after the form changes.
The callback method will be triggered when there is any change in the form value, and the new value will be returned
Language, use the language of the ajv-i18n
specified error message
You need to pass in a vue3 Ref
object, we will mount the doValidate
method on this object , you can pass
const yourRef = ref({})
onMounted(() => {
yourRef.value.doValidate()
})
<JsonSchemaForm contextRef={yourRef} />
In this way, the form is actively verified.
Make some customizations to the display of the form, the types are as follows:
export interface VueJsonSchemaConfig {
title?: string
descrription?: string
component?: string
additionProps?: {
[key: string]: any
}
withFormItem?: boolean
widget?: 'checkbox' | 'textarea' | 'select' | 'radio' | 'range' | string
items?: UISchema | UISchema[]
}
export interface UISchema extends VueJsonSchemaConfig {
properties?: {
[property: string]: UISchema
}
}
The css in js library is based on the secondary development of jss
npm i vue-jss jss jss-preset-default
Code editor
/* eslint no-use-before-define: 0 */
import { defineComponent, ref, onMounted, watch, onBeforeUnmount, shallowReadonly, shallowRef } from 'vue'
import * as Monaco from 'monaco-editor'
import type { PropType, Ref } from 'vue'
import { createUseStyles } from 'vue-jss'
// 返回一个方法
const useStyles = createUseStyles({
container: {
border: '1px solid #eee',
display: 'flex',
flexDirection: 'column',
borderRadius: 5
},
title: {
backgroundColor: '#eee',
padding: '10px 0',
paddingLeft: 20,
},
code: {
flexGrow: 1
}
})
export default defineComponent({
props: {
code: {
type: String as PropType<string>,
required: true
},
onChange: {
type: Function as PropType<(value: string, event: Monaco.editor.IModelContentChangedEvent) => void>,
required: true
},
title: {
type: String as PropType<string>,
required: true
}
},
setup(props) {
// must be shallowRef, if not, editor.getValue() won't work
const editorRef = shallowRef()
const containerRef = ref()
let _subscription: Monaco.IDisposable | undefined
let __prevent_trigger_change_event = false // eslint-disable-line
onMounted(() => {
const editor = editorRef.value = Monaco.editor.create(containerRef.value, {
value: props.code,
language: 'json',
formatOnPaste: true,
tabSize: 2,
minimap: {
enabled: false,
},
})
_subscription = editor.onDidChangeModelContent((event) => {
console.log('--------->', __prevent_trigger_change_event) // eslint-disable-line
if (!__prevent_trigger_change_event) { // eslint-disable-line
props.onChange(editor.getValue(), event);
}
});
})
onBeforeUnmount(() => {
if (_subscription)
_subscription.dispose()
})
watch(() => props.code, (v) => {
const editor = editorRef.value
const model = editor.getModel()
if (v !== model.getValue()) {
editor.pushUndoStop();
__prevent_trigger_change_event = true // eslint-disable-line
// pushEditOperations says it expects a cursorComputer, but doesn't seem to need one.
model.pushEditOperations(
[],
[
{
range: model.getFullModelRange(),
text: v,
},
]
);
editor.pushUndoStop();
__prevent_trigger_change_event = false // eslint-disable-line
}
// if (v !== editorRef.value.getValue()) {
// editorRef.value.setValue(v)
// }
})
const classesRef = useStyles()
return () => {
const classes = classesRef.value
return (
<div class={classes.container}>
<div class={classes.title}><span>{props.title}</span></div>
<div class={classes.code} ref={containerRef}></div>
</div>
)
}
}
})
Plug-in: monaco-editor-webpack-plugin
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin')
module.exports = {
chainWebpack(config) {
config.plugin('monaco').use(new MonacoWebpackPlugin())
},
}
app.tsx
import { defineComponent, reactive, ref, Ref, watchEffect } from "vue";
import {createUseStyles} from 'vue-jss'
import MonacoEditor from './components/MonacoEditor'
import demos from './demos'
import SchemaForm from '../lib'
// TODO:在lib中export
type Schema = any
type UISchema = any
function jsonToString(data: any) {
return JSON.stringify(data, null, 2)
}
// 样式
const useStyles = createUseStyles({
...
})
export default defineComponent ( {
setup ( ) {
// Record the currently selected demo
const selectedRef : Ref < number > = ref ( 0 )
const demo : {
schema : Schema | null ,
data : any ,
uiSchema : UISchema | null ,
schemaCode : string ,
dataCode : string ,
uiSchemaCode : string ,
} = reactive ( {
schema : null ,
data : { } ,
uiSchema : { } ,
schemaCode: '' ,
dataCode : '' ,
uiSchemaCode : '' ,
} )
watchEffect(() => {
const index = selectedRef.value
const d = demos[index]
demo.schema = d.schema
demo.data = d.default
demo.uiSchema = d.uiSchema
demo.schemaCode = jsonToString(d.schema)
demo.dataCode = jsonToString(d.default)
demo.uiSchemaCode = jsonToString(d.uiSchema)
})
const handleChange = (v: any) => {
demo.data = v
demo.dataCode = jsonToString(v)
}
// 工厂函数
const handleCodeChange = (
field: 'schema' | 'data' | 'uiSchema',
value: string
) => {
let json: any
try {
json = JSON.parse(value)
demo[field] = json
;(demo as any)[`${field}Code`] = value
} catch (err){
console.log(err);
}
}
const handleSchemaChange = (v: string) => handleCodeChange('schema', v)
const handleDataChange = (v: string) => handleCodeChange('data', v)
const handleUISchemaChange = (v: string) => handleCodeChange('uiSchema', v)
const classesRef = useStyles()
return () => {
const classes = classesRef.value
const selected = selectedRef.value
return ( // <StyleThemeProvider>
// <VJSFThemeProvider theme={theme as any}>
<div class={classes.container}>
<div class={classes.menu}>
<h1>Vue3 JsonSchema Form</h1>
<div>
{demos.map((demo, index) => (
<button
class={{
[classes.menuButton]: true,
[classes.menuSelected]: index === selected,
}}
onClick={() => (selectedRef.value = index)}
>
{demo.name}
</button>
))}
</div>
</div>
<div class={classes.content}>
<div class={classes.code}>
<MonacoEditor
code={demo.schemaCode}
class={classes.codePanel}
onChange={handleSchemaChange}
title="Schema"
/>
<div class={classes.uiAndValue}>
<MonacoEditor
code={demo.uiSchemaCode}
class={classes.codePanel}
onChange={handleUISchemaChange}
title="UISchema"
/>
<MonacoEditor
code={demo.dataCode}
class={classes.codePanel}
onChange={handleDataChange}
title="Value"
/>
</div>
</div>
<div class={classes.form}>
<SchemaForm
schema={demo.schema}
onChange={handleChange}
value={demo.data}
/>
{/* <SchemaForm
schema={demo.schema!}
uiSchema={demo.uiSchema!}
onChange={handleChange}
contextRef={methodRef}
value={demo.data}
/> */}
</div>
</div>
</div>
// </VJSFThemeProvider>
// </StyleThemeProvider>
)
}
}
})
SchemaItem: Distribute different types of schemas
fields/xxxField: specific implementation
<template>
<input type="text" :value="value" @input="handleChange" />
</template>
<script lang='ts' setup>
import {defineProps} from 'vue'
import {FieldPropsDefine, Schema} from '../types'
// Using FieldPropsDefine directly will report an error
const props = defineProps ({ ... FieldPropsDefine })
const handleChange = (e: any) => {
props.onChange(e.target.value)
}
</script>
Do not refer to components circularly, it is difficult to find errors, use plug-ins to remindnpm i -D circular-dependency-plugin
Use provide to solve the problem of circular references
Source code: apiInject.ts
// /packages/runtime-core/src/apiInject.ts
import { isFunction } from '@vue/shared'
import { currentInstance } from './component'
import { currentRenderingInstance } from './componentRenderUtils'
import { warn } from './warning'
export interface InjectionKey<T> extends Symbol {}
export function provide < T > ( key : InjectionKey < T > | string | number , value : T ) {
// Determine whether it is in the component rendering process, that is, you can only use
if ( ! currentInstance ) {
if ( __DEV__ ) {
warn ( `provide() can only be used inside setup().` )
}
} else {
let provides = currentInstance .provides
// by default an instance inherits its parent's provides object
// but when it needs to provide values of its own, it creates its
// own provides object using parent provides object as prototype.
// this way in `inject` we can simply look up injections from direct
// parent and let the prototype chain do the work.
// By default, the instance inherits the Provides object of its parent object
// But when it needs to provide its own value, it will use the parent provided object as prototype to create objects
// in this way, the `inject`, we can look directly from the parent object directly injected into the query so that the prototype chain works
const parentProvides =
the currentInstance of . parent && the currentInstance of . parent . the Provides
IF ( parentProvides == = provides) {
provides = currentInstance.provides = Object.create(parentProvides)
}
// TS doesn't allow symbol as index type
provides[key as string] = value
}
}
...
export function inject(
key: InjectionKey<any> | string,
defaultValue?: unknown,
treatDefaultAsFactory = false
) {
// fallback to `currentRenderingInstance` so that this can be called in
// a functional component
const instance = currentInstance || currentRenderingInstance
if (instance) {
// #2400
// to support `app.use` plugins,
// fallback to appContext's `provides` if the intance is at root
const provides =
instance.parent == null
? instance.vnode.appContext && instance.vnode.appContext.provides
: instance.parent.provides
if (provides && (key as string | symbol) in provides) {
// TS doesn't allow symbol as index type
return provides[key as string]
} else if (arguments.length > 1) {
return treatDefaultAsFactory && isFunction(defaultValue)
? defaultValue()
: defaultValue
} else if (__DEV__) {
warn(`injection "${String(key)}" not found.`)
}
} else if (__DEV__) {
warn(`inject() can only be used inside setup() or functional components.`)
}
}
Optimization: Encapsulate common logic
/**
* Three cases
*
* Single-type arrays, with no length limitation by default, are all the same type
* {
* items: {type:'string'}
*}
* Fixed length, which types are respectively
* {
* items: [
* {type:'string'},
* {type:'numer'}
*]
*}
* enum means optional
items * {
* items: {type:'string', enum: ['1', '2']}
*}
*/
Fixed-length array rendering
Single type array rendering
Contains optional array rendering
Author: Naixes
Source Code: https://github.com/Naixes/vue3-json-schema-form
#vue #vuejs #javascript
1600347600
This is part 3 of “MS SQL Server- Zero to Hero” and in this article, we will be discussing about the SCHEMAS in SQL SERVER. Before getting into this article, please consider to visit previous articles in this series from below,
In part one, we learned the basics of data, database, database management system, and types of DBMS and SQL.
#sql server #benefits of schemas #create schema in sql #database schemas #how to create schema in sql server #schemas #schemas in sql server #sql server schemas #what is schema in sql server
1625637060
In this video, we work with JSONs, which are a common data format for most web services (i.e. APIs). Thank you for watching and happy coding!
Need some new tech gadgets or a new charger? Buy from my Amazon Storefront https://www.amazon.com/shop/blondiebytes
What is an API?
https://youtu.be/T74OdSCBJfw
JSON Google Extension
https://chrome.google.com/webstore/detail/json-formatter/bcjindcccaagfpapjjmafapmmgkkhgoa?hl=en
Endpoint Example
http://maps.googleapis.com/maps/api/geocode/json?address=13+East+60th+Street+New+York,+NY
Check out my courses on LinkedIn Learning!
REFERRAL CODE: https://linkedin-learning.pxf.io/blondiebytes
https://www.linkedin.com/learning/instructors/kathryn-hodge
Support me on Patreon!
https://www.patreon.com/blondiebytes
Check out my Python Basics course on Highbrow!
https://gohighbrow.com/portfolio/python-basics/
Check out behind-the-scenes and more tech tips on my Instagram!
https://instagram.com/blondiebytes/
Free HACKATHON MODE playlist:
https://open.spotify.com/user/12124758083/playlist/6cuse5033woPHT2wf9NdDa?si=VFe9mYuGSP6SUoj8JBYuwg
MY FAVORITE THINGS:
Stitch Fix Invite Code: https://www.stitchfix.com/referral/10013108?sod=w&som=c
FabFitFun Invite Code: http://xo.fff.me/h9-GH
Uber Invite Code: kathrynh1277ue
Postmates Invite Code: 7373F
SoulCycle Invite Code: https://www.soul-cycle.com/r/WY3DlxF0/
Rent The Runway: https://rtr.app.link/e/rfHlXRUZuO
Want to BINGE?? Check out these playlists…
Quick Code Tutorials: https://www.youtube.com/watch?v=4K4QhIAfGKY&index=1&list=PLcLMSci1ZoPu9ryGJvDDuunVMjwKhDpkB
Command Line: https://www.youtube.com/watch?v=Jm8-UFf8IMg&index=1&list=PLcLMSci1ZoPvbvAIn_tuSzMgF1c7VVJ6e
30 Days of Code: https://www.youtube.com/watch?v=K5WxmFfIWbo&index=2&list=PLcLMSci1ZoPs6jV0O3LBJwChjRon3lE1F
Intermediate Web Dev Tutorials: https://www.youtube.com/watch?v=LFa9fnQGb3g&index=1&list=PLcLMSci1ZoPubx8doMzttR2ROIl4uzQbK
GitHub | https://github.com/blondiebytes
Twitter | https://twitter.com/blondiebytes
LinkedIn | https://www.linkedin.com/in/blondiebytes
#jsons #json arrays #json objects #what is json #jsons tutorial #blondiebytes
1597067523
Recently, I have seen several questions like “what’s the difference between JSON-LD and JSON Schema” or “can I use JSON Schema and Schema.org”. I come from a linked data background (which is close to the world of Schema.org) but have recently started using JSON Schema a lot and I have to admit that there is no trivial answer to these questions. There is the obvious similarity in the standard names like “Schema” and “JSON”. If you compare the Schema.org page for Person to this example on the JSON Schema page, you have to admit that they kind of look alike. Combine this with the fact that Schema.org touts JSON-LD, which — by design — very much looks like regular JSON completes the confusion. So there definitely are enough reasons to write this article.
JSON Schema is to JSON what XML Schema is to XML. It allows you to specify the structure of a JSON document. You can state that the field “email” must follow a certain regular expression or that an address has “street_name”, “number”, and “street_type” fields. Michael Droettboom’s book “Understanding JSON Schema” illustrates validation quite nicely with red & green examples.
The main use case for JSON Schema seems to be in JSON APIs where it plays two major roles:
As with all things related to code, reuse is a good idea. JSON Schema has the ability to import schemas using the $ref keyword. There are also efforts to share schemas. JSON Schema Store is one example. Its main use case is to support syntax highlighting for editors, for instance when editing a swagger file. At the time of writing, it contains over 250 schemas including — drum-roll please / you certainly guessed it — Schema.org. These describe things like Action and Place. So the idea could be to centrally define JSON Schema building blocks that can be re-used in different APIs, making it easier to consume them, maybe even to the point where intelligent software can interact with APIs automatically. But before we get carried away, let’s have a look at Schema.org.
#schema #swagger #json-ld #json-schema
1673587800
This library serves as a Dynamic JSON Powered Form rendering library for Angular. This works by providing a JSON schema to a <formio>
Angular component, where that form is dynamically rendered within the front end application. This allows forms to be dynamically built using JSON schemas.
If you are looking for Angular Material support, then this is within a separate library @ https://github.com/formio/angular-material-formio
To run a demo of the Form.io Angular renderer, please follow these steps.
npm install
ng serve
This will startup an example application where you can see all the features provided by this module.
Here is the hosted demo application https://formio.github.io/angular-demo/
You can easily render a form within your Angular application by referencing the URL of that form as follows.
<formio src='https://examples.form.io/example'></formio>
You can also pass the JSON form directly to the renderer as follows.
<formio [form]='{
"title": "My Test Form",
"components": [
{
"type": "textfield",
"input": true,
"tableView": true,
"inputType": "text",
"inputMask": "",
"label": "First Name",
"key": "firstName",
"placeholder": "Enter your first name",
"prefix": "",
"suffix": "",
"multiple": false,
"defaultValue": "",
"protected": false,
"unique": false,
"persistent": true,
"validate": {
"required": true,
"minLength": 2,
"maxLength": 10,
"pattern": "",
"custom": "",
"customPrivate": false
},
"conditional": {
"show": "",
"when": null,
"eq": ""
}
},
{
"type": "textfield",
"input": true,
"tableView": true,
"inputType": "text",
"inputMask": "",
"label": "Last Name",
"key": "lastName",
"placeholder": "Enter your last name",
"prefix": "",
"suffix": "",
"multiple": false,
"defaultValue": "",
"protected": false,
"unique": false,
"persistent": true,
"validate": {
"required": true,
"minLength": 2,
"maxLength": 10,
"pattern": "",
"custom": "",
"customPrivate": false
},
"conditional": {
"show": "",
"when": null,
"eq": ""
}
},
{
"input": true,
"label": "Submit",
"tableView": false,
"key": "submit",
"size": "md",
"leftIcon": "",
"rightIcon": "",
"block": false,
"action": "submit",
"disableOnInvalid": true,
"theme": "primary",
"type": "button"
}
]
}'></formio>
This is a very simple example. This library is capable of building very complex forms which include e-signatures, columns, panels, field conditionals, validation requirements, and the list goes on and on.
To use this library within your project, you will first need to install it as a dependency.
npm install --save @formio/angular formiojs
You can now include the module in your Angular application like so.
import { FormioModule } from '@formio/angular';
@NgModule({
imports: [ BrowserModule, CommonModule, FormioModule ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule { }
This library is a combination of multiple libraries that enable rapid Serverless application development using Form.io. These libraries are as follows.
Click on each of those links to read more about how they work and how to utilize them to their fullest potential.
If you would like to run a demonstration of all the features of this module, then you can check out the Angular Demo Application, which is the code behind the following hosted application @ https://formio.github.io/angular-demo
For help in getting started using this library, we created the angular-app-starterkit repository to help you get started with best practices with using Form.io within an Angular application. You can try this applicatoin by downloading that application and then doing the following.
npm install
npm start
To read up on the full documentation of this library, please check out the Wiki Page
Form.io is a combined form and data management API platform created for developers who are building "Serverless" form-based applications. Form.io provides an easy drag-and-drop form builder workflow allowing you to build complex forms for enterprise applications quickly and easily. These forms are then embedded directly into your application with a single line of code that dynamically renders the form (using Angular or React) in your app while at the very same time generating the RESTful API to support those forms. The Form.io platform also offers numerous 3rd-party services that are fully integrated into the form building process allowing you to extend the power and capability of your apps while saving time and effort.
You can use this renderer with Form.io by simply pointing the src
parameter to the URL of the form. For example, the following URL points to the JSON schema of a form built on Form.io.
https://pjmfogrfqptslvi.form.io/test
To render this form, you simply provide that URL to the <formio>
directive like so.
<formio src="https://pjmfogrfqptslvi.form.io/test"></formio>
Not only will this render the form, but it will also submit that form to the provided API endpoint.
Author: formio
Source Code: https://github.com/formio/angular
License: MIT license
1600307723
Laravel 8 form example. In this tutorial, i would love to show you how to create form in laravel. And how to insert data into database using form in laravel 8.
https://laratutorials.com/laravel-8-form-example-tutorial/
#insert form data into database using laravel #laravel bootstrap form #laravel post forms #laravel 8 form tutorial #laravel 8 form example #laravel 8 form submit tutorial