I am trying to learn vue . I grabbed a demo project and have much of it working but I am not sure I under stand what this does.
const search = ref("");
const movies= ref([]);
in the template and other places it then accesses the value using search.value. Why use Ref("") ?
ref() allows us to create a "reference" to any value and pass it around without losing reactivity.
The beauty behind that is the fact that you can create reactive properties outside your Vue component. Inside a plain js (or ts) file, just import "ref" from the "vue" package, and then create a reactive property, e.g.
const msg = ref("hello")
For the examples you provided, you're simply initializing the variables with an empty string for search and empty array for movies.
In Vue 3, ref() makes a variable reactive.
https://vuejs.org/api/reactivity-core.html#ref
Related
I'm making an application that uses TypeScript, and as a templating language I'm using Svelte.
That allows me to create DOM elements with classes that can change in realtime according to a variable, thanks to ternary operator. For instance:
<div class="{theme == "dark" ? "bg-black" : "bg-white"}"> Hello </div>
The thing is, my application has to dynamically generate some DOM elements. That makes me create some divs using the following piece of script:
const parentDiv = document.getElementById("parentDiv");
const childDiv = document.createElement("div")
childDiv.classList.add(theme == "dark" ? "bg-black" : "bg-white")
parentDiv.appendChild(childDiv)
In this case, the conditional operator is just calculated when .add() is called, which happens once. There is no "realtime calculation" of the value like in the first method above. How do I handle this ?
If you are not creating the elements via plain Svelte markup you are probably doing something wrong. There are various directives that help, e.g. {#if} and {#each}.
In some cases it makes sense to imperatively add things, but even then, you should add components not plain DOM elements. You can instantiate any component using the client API, e.g.
new MyComponent({ target: document.body })
Anything inside the component then can use the Svelte mechanism that automatically update. If you need to have reactivity from the outside, you can pass a store as a property or import a global store from within/load it from a context.
(Would recommend making the theme a store. Either global or passed through props/contexts.)
Note on contexts with the client API: They have to be passed explicitly; to inherit existing contexts you can use getAllContexts:
// somewhere at top-level
const context = getAllContexts();
// ...
new MyComponent({ ..., context })
const app = createApp({
data() {
return {
some_id: 0
}
}
})
I have an autocomplete on a field.
When a label is selected, I want to pass the id to a Vue app.
onSelectItem: ({label, value}) => {
app.some_id = value;
}
This worked in an old v2 version of Vue.js.
Now, I can't even call the methods of the Vue app from other JavaScript functions.
What is the best solution?
There are certain circumstances where you may need to access and mutate, change the instance's data.
This was easier in Vue JS 2, but Vue JS 3 has become more encapsulated. However it does not mean mutating state from outside is impossible. You can read about it here
Supposing that you are using Vue with build steps, which covers most cases, you will have something like this:
const app = createApp({
data() {
return {}
},
})
.mount('#app');
Now if you head to browser console and type app, it will be null because it is limited to the scope of compiled .js files.
But if you attach app to a global object, document for example:
document.app = createApp({
data() {
return {}
},
})
.mount('#app');
Now if you type app in the console, it will no longer be null, but the Vue instance. From there, you can access the instance's data as well as mutate it via app.$data property.
Now what if the instance has components and you want to mutate their $data? In previous versions, it was possible to access children via $children property. But now in order to access children, you have to give each of them a ref, then access via their ref name. For example:
app.$refs.alertComponent.$data.message = "New message!"
I'm curious about passing props into setup and what are best practices to update variables/templates based on property changes.
I'm curious about reactive and computed.
For example:
setup(props) {
// Setup global config settings
const config = computed(() => {
return {
// See if the component is disabled
isDisabled: props.disabled, // (1)
// Test for rounded
isRounded: props.rounded // (2)
}
})
return { config }
}
Should config.isDisabled and config.isRounded be wrapped in their own computed function as they are both different and independent? However, it is easy to just stick them into one big function. What is best practice in this regard?
Does the entire config function evaluate once a single property changes within the function or can it recognize the change and update what is required?
Per docs, reactive is deeply reactive and used for objects, however, I've noticed it doesn't update to property changes. Therefore, I've been treating it more like data in Vue 2. Am I missing something or is this correct treatment?
You do not have to wrap props with computed at all, as they should be already reactive and immutable.
You also do not have to return config from your setup function as all props passed to your component should be automatically exposed to your template.
The computed function is evaluated only once and then Vue3 uses Proxy to observe changes to values and update only what's required. If you need to run a function every time a property changes you can use watchEffect.
Vue3 reactive is actually deep and works fine on objects. It should track all changes, unless you are trying to change the original object (the target of reactive function).
I've used higher order component to share a function between my components.With this implementation,the function comes as a prop in my component.The app supports multi languages so in each component a key is passed and the hash value is obtained to display. Hash values are passed to all the components using the context. Now getSkinHash access the context and returns the hash value.
const {getSkinHash} = this.props; //shared function,accesses the context
const value = getSkinHash(SOME_VALUE);
No problem with this implementation but getting the function out of prop every time leads to writing lot's of boilerplate code in all the components.
Is there a better/alternate ways to achieve this?
Thanks
React works with properties, so you can't just say you don't want to work with properties. That is when sharing data between components.
As far as you can do to shorten
const {getSkinHash} = this.props;
const value = getSkinHash(SOME_VALUE);
is to:
this.props.getSkinHash(SOME_VALUE).
If that is a generic function, not component dependent, you can choose to import it into your component just like you import other stuff.
import { myFunction } from './functions'
Then you would simple call it with myFunction.
If you need your function to synchronize data between your components, use a Redux action and connect your components to the global state. Your other components will get to know value hash changes too.
This question already has answers here:
How to use global variables in React Native?
(7 answers)
Closed 2 years ago.
I haven't been able to find anything like
$rootScope
for React Native and I want to share a couple variables between different Views.
For example, you can export class with static properties and then import there when need.
In main.js for example:
export class AppColors {
static colors = {main_color: "#FFEB3B", secondary_color: "#FFC107"}
}
In other file, where need to get this colors
import { AppColors } from './main.js';
class AnotherPage {
constructor() {
super();
console.log(AppColors.colors); // youla! You will see your main and secondary colors :)
}
}
Storing variables in the global scope is a bit of an anti-pattern in React. React is intended to be used with a one-way data flow, meaning data flows down from components to their children. This is achieved through the passing of props.
In order to share a value between multiple views, you would either need to store the data on a shared parent component and pass it down as a prop OR store it in a separate entity that is responsible for data management. In ReactJS this is achieved through patterns like Flux, but I'm not sure about the options for react-native.
Step 1. create ConstantFile.js File and put this code.
export class ConstantClass {
static webserviceName = 'http://172.104.180.157/epadwstest/';
static Email = 'emailid';
static Passoword = 'password';
}
Step 2. Access as like below. But before that, you need to import your js file to particular class file something like that
import { ConstantClass } from './MyJS/ConstantFile.js';
ConstantClass.webserviceName
ConstantClass.Email
ConstantClass.Passoword
You can store those values in parent components state. Then pass methods changing those values via props or context / or like #Jakemmarsh suggested - use Flux/Redux approach.
OR, you can use AsyncStorage. Its useful for storing app data like tokens and such.